Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to QGarphicsVideoItem update by QTimer.



  • Greeting!

    I want to update QGraphicsVideoItem using QTimer which is declared in QWidget.
    But below github test code is not working.
    I am wondering if you could suggest some ideas to this problem.

    https://github.com/kr-MATAGI/TimerUpdate-test.git

    What I want is below steps.

    1. If i click the button, display first video and playing.
    2. second video is displayed by timer's timeout function.
      (using mainwindow signal / slot)

    Sorry for the lack of English skills.


  • Lifetime Qt Champion

    @Matagi said in How to QGarphicsVideoItem update by QTimer.:

    But below github test code is not working

    Please explain what exactly is not working

    "second video is displayed by timer's timeout function" - displayed where?



  • @jsulm I want to display second video on ui->graphicsView.
    Just change a new scene which is added new video item.


  • Lifetime Qt Champion

    @Matagi What exactly is not working?



  • @jsulm
    I apologize for the inconvenience due to the short explanation.

    1. Main Window has a QGraphicsView and a button.
      스크린샷, 2021-04-09 14-36-07.png

    2. if I click the button, below code is called.
      Then, timer is add 2 videoitems(QGraphisVideoItem) to MainWindow using 'signal' and call a DisplayNewScene() function also using 'signal'.
      Then, Display QGraphisScene which is added first Video Item on ui->graphicsView.
      After 3 second, ui->garphicsView is chagned a new QGraphicsScene which has second Video Item. but, this behavior is not working.

    mainwindow.cpp

    void MainWindow::TestBtnClicked()
    {
        m_timer = new UpdateTimer;
        m_timer->MakeVideoItem();
        m_timer->start(3000);
    }
    
    void MainWindow::AddVideoItemSlot(VideoItemInfo item)
    {
        qDebug() << __FUNCTION__ << item.first;
    
        m_videoItemList.push_back(item);
    }
    
    void MainWindow::DisplayNewSceneSlot(int key)
    {
        qDebug() << __FUNCTION__ << key;
    
        QGraphicsScene *newScene = new QGraphicsScene;
        newScene->setSceneRect(ui->graphicsView->rect());
    
        newScene->addItem(m_videoItemList[key].second);
        ui->graphicsView->setScene(newScene);
        m_videoItemList[key].second->PlayVideo();
    
    }
    

    updatetimer.cpp

    void UpdateTimer::MakeVideoItem()
    {
        QString path_1 = "localPath";
        QString path_2 = "localPath";
    
        MyVideoItem *myVideoItem_1 = new MyVideoItem;
        myVideoItem_1->SetMedia(path_1);
        myVideoItem_1->setSize(QSize(500, 500));
        myVideoItem_1->setPos(0,0);
    
        MyVideoItem *myVideoItem_2 = new MyVideoItem;
        myVideoItem_2->SetMedia(path_2);
        myVideoItem_2->setSize(QSize(300, 300));
        myVideoItem_2->setPos(100, 100);
    
        VideoItemInfo pair_1(0, myVideoItem_1);
        VideoItemInfo pair_2(1, myVideoItem_2);
    
        emit MainWindow::GetInstance()->AddVideoItemSignal(pair_1);
        emit MainWindow::GetInstance()->AddVideoItemSignal(pair_2);
    
        emit MainWindow::GetInstance()->DisplayNewSceneSingal(0);
    }
    
    void UpdateTimer::TimeoutSlot()
    {
       emit MainWindow::GetInstance()->DisplayNewSceneSingal(1);
    }
    
    • first Video ( in first QGraphicsScene)
      스크린샷, 2021-04-09 14-05-16.png

    • second Video ( in second QGraphicsScene)
      Not playing second video, saved data is not wrong.
      스크린샷, 2021-04-09 14-36-07.png


  • Lifetime Qt Champion

    @Matagi said in How to QGarphicsVideoItem update by QTimer.:

    emit MainWindow::GetInstance()->DisplayNewSceneSingal(1);

    Why does UpdateTimer emit signals from MainWindow?! This is very bad design! UpdateTimer should emit own signals which iare connected to slots in MainWindow.
    I also don't understand why a class called UpdateTimer does anything with UI? Why do you need UpdateTimer at all? You can have timers in MainWindow.



  • @jsulm

    I need video item changing behavior just in time by video duration expiration in my main project. (like to TV channel changing action, digital signage)

    'Why does UpdateTimer emit signals from MainWindow?! This is very bad design!'
    -> I don't have idea about best way. (It's my fault...., first my QT project and I am junior developer.)

    'You can have timers in MainWindow.'
    -> (I don't know exact meaning... Is it accord with your meaning?)
    So, I modify mainwindow.cpp like below. but It doesn't work....

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QGraphicsScene>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    #include "updatetimer.h"
    #include "myvideoitem.h"
    
    typedef std::pair<int, QGraphicsScene *> SceneInfo;
    typedef std::pair<int, MyVideoItem*> VideoItemInfo;
    
    class UpdateTimer;
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        static MainWindow *pInstance;
    
        static MainWindow *GetInstance();
    
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        void MakeVideoItemAndPlayFirstItem();
    
        void AddVideoItem(VideoItemInfo item);
        void DisplayNewScene(int key);
    
    signals:
        void DisplayNewSceneSignal(int key);
    
    private slots:
        void TestBtnClicked();
        void TimeoutSlot();
    
        void DisplayNewSceneSlot(int key);
    
    private:
        Ui::MainWindow *ui;
    
        QTimer m_timer;
        QVector<SceneInfo> m_sceneList;
        QVector<VideoItemInfo> m_videoItemList;
    
    };
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <QDebug>
    
    MainWindow* MainWindow::pInstance = nullptr;
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        ui->graphicsView->setStyleSheet("border: 0px");
        ui->graphicsView->setAlignment(Qt::AlignLeft | Qt::AlignTop);
        ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->graphicsView->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
        ui->graphicsView->setRenderHint(QPainter::Antialiasing);
    
        // connect
        connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(TestBtnClicked()));
    
        connect(&m_timer, SIGNAL(timeout()), this, SLOT(TimeoutSlot()));
    
        connect(this, SIGNAL(DisplayNewSceneSignal(int)),
                this, SLOT(DisplayNewSceneSlot(int)));
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    MainWindow* MainWindow::GetInstance()
    {
        if(nullptr == pInstance)
        {
            pInstance = new MainWindow;
        }
        return pInstance;
    }
    
    void MainWindow::MakeVideoItemAndPlayFirstItem()
    {
        QString path_1 = "local video path";
        QString path_2 = "local video path";
    
        MyVideoItem *myVideoItem_1 = new MyVideoItem;
        myVideoItem_1->SetMedia(path_1);
        myVideoItem_1->setSize(QSize(500, 500));
        myVideoItem_1->setPos(0,0);
    
        MyVideoItem *myVideoItem_2 = new MyVideoItem;
        myVideoItem_2->SetMedia(path_2);
        myVideoItem_2->setSize(QSize(300, 300));
        myVideoItem_2->setPos(100, 100);
    
        VideoItemInfo pair_1(0, myVideoItem_1);
        VideoItemInfo pair_2(1, myVideoItem_2);
    
        AddVideoItem(pair_1);
        AddVideoItem(pair_2);
    
        DisplayNewScene(0);
    }
    
    void MainWindow::TestBtnClicked()
    {
        MakeVideoItemAndPlayFirstItem();
        m_timer.start(3000);
    }
    
    void MainWindow::TimeoutSlot()
    {
        emit DisplayNewSceneSignal(1);
    }
    
    void MainWindow::AddVideoItem(VideoItemInfo item)
    {
        qDebug() << __FUNCTION__ << item.first;
    
        m_videoItemList.push_back(item);
    }
    
    void MainWindow::DisplayNewSceneSlot(int key)
    {
        DisplayNewScene(key);
    }
    
    void MainWindow::DisplayNewScene(int key)
    {
        qDebug() << __FUNCTION__ << key;
    
        QGraphicsScene *newScene = new QGraphicsScene;
        newScene->setSceneRect(ui->graphicsView->rect());
    
        newScene->addItem(m_videoItemList[key].second);
        ui->graphicsView->setScene(newScene);
        m_videoItemList[key].second->PlayVideo();
    
    }
    

Log in to reply