Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Threading scene

Threading scene

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 5 Posters 628 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    micha_eleric
    wrote on last edited by
    #1

    Trying to use one thread to update scene, and another thread to show, but sigfaults if scene id updated to often.

    #include "CThreadController.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        CThreadController threcon;
        MainWindow w;
        CSceneView scene;
        CViewLoop vloop;
    
        w.SetController(&threcon);
        scene.SetController(&threcon);
    
        threcon.SetMainWindow(&w);
        threcon.SetSceneView(&scene);
        threcon.SetViewLoop(&vloop);
    
        threcon.startThreads();
        threcon.ShowPointers();
        w.show();
        return a.exec();
    }
    
    #include "CMainWindow.h"
    #include "CThreadController.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , m_ui(new Ui::MainWindow)
    {
        m_ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete m_ui;
    }
    
    void MainWindow::SetController(CThreadController *controller)
    {
        m_threadcontroller = controller;
        connect(m_ui->pushButton, &QPushButton::clicked,this, &MainWindow::Run);
    }
    
    void MainWindow::ReceiveGView(QGraphicsScene *scene)
    {
        std::cout << "================ MainWindow::ReceiveGView ================ \n" << std::flush;
        std::cout << "scene = " << scene << '\n' << std::flush;
        m_ui->graphicsView->setScene(scene);
        m_ui->graphicsView->show();
        // want to delete scene here, to save memory
        //scene->clear(); //causes crash [not supprised]
    }
    
    void MainWindow::ReceiveGView2(QGraphicsScene *scene)
    {
        std::cout << "================ MainWindow::ReceiveGView2 ================ \n" << std::flush;
        m_ui->graphicsView_2->setScene(scene);
        m_ui->graphicsView_2->show();
    }
    
    void MainWindow::Run()
    {
        std::cout << "================ MainWindow::Run ================ \n" << std::flush;
        emit EmitDisPlayView();
    }
    
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QApplication>
    #include <QCoreApplication>
    #include <QDebug>
    #include <QGraphicsScene>
    #include <QtGui>
    #include <QMainWindow>
    //#include <QSerialPort>
    #include <QThread>
    #include <cstring>
    #include <fstream>
    #include <functional>
    #include <iostream>
    #include <sstream>
    #include <string>
    #include "ui_mainwindow.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class CThreadController;
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    private:
        Ui::MainWindow *m_ui;
        CThreadController *m_threadcontroller;
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        void SetController(CThreadController *controller);
        void ReceiveGView(QGraphicsScene *scene);
        void ReceiveGView2(QGraphicsScene *scene);
        void Run();
    
        // signals
    signals:
        void EmitDisPlayView();
    
    };
    #endif // MAINWINDOW_H
    
    #include "CSceneView.h"
    
    CSceneView::CSceneView() : QGraphicsScene()
    {
        m_GScene = new QGraphicsScene(this);
        m_GScene_2 = new QGraphicsScene(this);
    }
    
    
    // get/set
    void CSceneView::SetController(CThreadController *controller)
    {
        std::cout << "================ CSceneView::SetController ================ \n" << std::flush;
        m_threadcontroller = controller;
    }
    
    void CSceneView::DisPlayView()
    {
        std::cout << "================ CSceneView::DisPlayView ================ \n" << std::flush;
    /*
        m_GScene->clear();
        m_GScene_2->clear();
        m_GScene = new QGraphicsScene(this);
        m_GScene_2 = new QGraphicsScene(this);
    */
        int i = 0;
        int j = 0;
    
        while(i < 20000)
        {
            while(j < 20000)
            {
                m_GScene->addEllipse((j), (i), 1, 1);
                m_GScene_2->addEllipse((i), (j), 1, 1);
                j++;
            }
            i++;
        }
    
        emit EmitGView(m_GScene);
        emit EmitGView2(m_GScene_2);
    }
    
    
    void CSceneView::ReceiveDisPlayView()
    {
        std::cout << "================ CSceneView::ReceiveDisPlayView ================ \n" << std::flush;
        QString s = QString::number((long long)(this->thread()), 16);
        std::cout << "CSceneView   this->thread() = " << s.toStdString() << '\n' << std::flush;
    
        // new scene so two threads are not using same pointer at same time
        m_GScene->clear();
        m_GScene_2->clear();
        //m_GScene = new QGraphicsScene(this);
        //m_GScene_2 = new QGraphicsScene(this);
    
        DisPlayView();
        //TestArray();
    }
    
    #ifndef CSCENEVIEW_H
    #define CSCENEVIEW_H
    
    #include <QGraphicsScene>
    #include <QObject>
    #include <iostream>
    
    class CThreadController;
    
    class CSceneView : public QGraphicsScene
    {
        Q_OBJECT
        // data
    public:
        CThreadController *m_threadcontroller;
        QGraphicsScene * m_GScene;
        QGraphicsScene * m_GScene_2;
    
        // constructor
        CSceneView();
    
        // get/set
        void SetController(CThreadController *controller);
    
        // function
        void DisPlayView();
        // signals
    signals:
        void EmitGView(QGraphicsScene *scene);
        void EmitGView2(QGraphicsScene *scene);
        void EmitDisPlayView();
    
    public slots:
        void ReceiveDisPlayView();
    
    };
    
    #endif // CSCENEVIEW_H
    
    #include "CThreadController.h"
    
    CThreadController::CThreadController() : QThread()
    {
        m_threadsceneview = new QThread();
    }
    
    void CThreadController::SetMainWindow(MainWindow *w)           //?? : public QMainWindow
    {
        std::cout << "CThreadController w = " << w << '\n' << std::flush;
        m_mainwindow = w;
    }
    
    void CThreadController::SetSceneView(CSceneView *sceneview) //?? : public QGraphicsScene
    {
        std::cout << "CThreadController sceneview = " << sceneview << '\n' << std::flush;
        m_sceneview = sceneview;
        m_sceneview->moveToThread(m_threadsceneview);
        connect(m_threadsceneview, &QThread::finished, m_sceneview, &QObject::deleteLater);
        connect(m_threadsceneview, &QThread::finished, m_threadsceneview, &QThread::deleteLater);
        m_threadsceneview->start();
    }
    
    void CThreadController::SetViewLoop(CViewLoop *vloop) //?? : public QThread
    {
        std::cout << "CThreadController vloop = " << vloop << '\n' << std::flush;
        std::cout << "CThreadController m_threadvloop = " << m_threadvloop << '\n' << std::flush;
        m_threadvloop = vloop;
        connect(m_threadvloop, &QThread::finished, m_threadvloop, &QObject::deleteLater);
        connect(m_threadvloop, &QThread::finished, m_threadvloop, &QThread::deleteLater);
        m_threadvloop->start();
    }
    
    // function
    void CThreadController::startThreads()
    {
        std::cout << "CThreadController::startThreads begin\n" << std::flush;
        std::cout << "CThreadController::startThreads m_mainwindow = " << m_mainwindow << '\n' << std::flush;
        std::cout << "CThreadController::startThreads m_sceneview = " << m_sceneview << '\n' << std::flush;
    
        //?? CSeneView -> mainwindow
        connect(m_sceneview, &CSceneView::EmitGView, m_mainwindow, &MainWindow::ReceiveGView);
        connect(m_sceneview, &CSceneView::EmitGView2, m_mainwindow, &MainWindow::ReceiveGView2);
    
        //?? MainWindow -> CSeneView
        connect(m_mainwindow, &MainWindow::EmitDisPlayView, m_sceneview,
                &CSceneView::ReceiveDisPlayView);
    
        //?? CSeneView -> CSeneView
        connect(m_sceneview, &CSceneView::EmitDisPlayView, m_sceneview,
                &CSceneView::ReceiveDisPlayView);
    
        //?? CViewLoop -> CSeneView
        connect(m_threadvloop, &CViewLoop::EmitDisPlayView, m_sceneview,
                &CSceneView::ReceiveDisPlayView);
    
    
    }
    
    void CThreadController::ShowPointers()
    {
        QString qs = QString::number((long long)(QThread::currentThreadId()), 16);
        std::cout << "CThreadController   QThread::currentThreadId() = " << qs.toStdString() << '\n' << std::flush;
        std::cout << "CThreadController::ShowPointers m_threadvloop = " << m_threadvloop << '\n' << std::flush;
        std::cout << "CThreadController::ShowPointers m_mainwindow = " << m_mainwindow << '\n' << std::flush;
        std::cout << "CThreadController::ShowPointers m_sceneview = " << m_sceneview << '\n' << std::flush;
    }
    
    #ifndef CTHREADCONTROLLER_H
    #define CTHREADCONTROLLER_H
    
    #include "CMainWindow.h"
    #include "CSceneView.h"
    #include "CViewLoop.h"
    #include <QObject>
    #include <QThread>
    
    class CThreadController : public QThread
    {
        Q_OBJECT
    private:
        // data
        MainWindow *m_mainwindow;                    //?? : public QMainWindow
        CSceneView *m_sceneview;        //?? : public QGraphicsScene
        QThread* m_threadsceneview;
        CViewLoop *m_threadvloop;       //?? : public QThread
    
    public:
        CThreadController();
    
        // get/set
        void SetMainWindow(MainWindow *w);
        void SetSceneView(CSceneView *sceneview);
        void SetViewLoop(CViewLoop *vloop);
    
        // function
        void startThreads();
        void ShowPointers();
    };
    
    #endif // CTHREADCONTROLLER_H
    
    //#include "CSceneView.h"
    #include "CViewLoop.h"
    
    CViewLoop::CViewLoop()
    {
        m_sState = "error";
    }
    
    // get/set
    void CViewLoop::SetState(std::string s)
    {
        m_sState = s;
    }
    
    // function
    void CViewLoop::Print(std::string s)
    {
        std::cout << s << '\n' << std::flush;
        m_file << s << '\n' << std::flush;
    }
    
    void CViewLoop::run()
    {
        /* ... here is the expensive or blocking operation ... */
        int runtime = 10;
        int i = 0;
        while(true)
        {
            if( (m_sState == "error") || (m_sState == "run"))
            {
                Print("CViewLoop::run 'error' or 'run' i = " + std::to_string(i));
                emit EmitDisPlayView();
                sleep(runtime); //?? 1 = 1 seconds, 5 = 5 seconds
                i++;
            }
            else
            {
                Print("CViewLoop::run 'else'");
                this->sleep(40);
            }
        }
    
        Print("CViewLoop::run exit");
    }
    
    #ifndef CVIEWLOOP_H
    #define CVIEWLOOP_H
    
    #include <fstream>
    #include <iostream>
    #include <QObject>
    #include <QThread>
    
    //class CSceneView;
    
    class CViewLoop : public QThread
    {
        Q_OBJECT
    //?? data
    private:
        std::ofstream m_file;
        std::string m_sState;
        //CSceneView *m_scene;
    
    public:
        // constructors
        CViewLoop();
    
        // get/set
        void SetState(std::string s);
        //void SetSceneView(CSceneView *scene);
    
        // functions
        void Print(std::string s);
        void run() override;
    
        // signals
    signals:
        void EmitDisPlayView();
    
    };
    
    #endif // CVIEWLOOP_H
    

    if

    m_GScene = new QGraphicsScene(this);
    

    is only in constructor, then it will run , but sigfaults or locks up dependent on how often a button and which button is clicked.
    if it is used each time scene is updated, randomly sigfaults, around 2 to 20 updates.
    i moved it between two functions, think one function lasted longer that the other, but could not figure out how, then i ran same program multiple times, and noticed that sigfault was random.
    It seems updating scene at same time as scene would be a cause of sigfault, so I made new QGraphicsScene(this); each time. I tried to pass a copy, but seems copy can not be made of scene, could not even write a copy constructor for it.

    How to update scene in one thread and and shown on another thread?

    JonBJ S 3 Replies Last reply
    0
    • M micha_eleric

      Trying to use one thread to update scene, and another thread to show, but sigfaults if scene id updated to often.

      #include "CThreadController.h"
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
      
          CThreadController threcon;
          MainWindow w;
          CSceneView scene;
          CViewLoop vloop;
      
          w.SetController(&threcon);
          scene.SetController(&threcon);
      
          threcon.SetMainWindow(&w);
          threcon.SetSceneView(&scene);
          threcon.SetViewLoop(&vloop);
      
          threcon.startThreads();
          threcon.ShowPointers();
          w.show();
          return a.exec();
      }
      
      #include "CMainWindow.h"
      #include "CThreadController.h"
      
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
          , m_ui(new Ui::MainWindow)
      {
          m_ui->setupUi(this);
      }
      
      MainWindow::~MainWindow()
      {
          delete m_ui;
      }
      
      void MainWindow::SetController(CThreadController *controller)
      {
          m_threadcontroller = controller;
          connect(m_ui->pushButton, &QPushButton::clicked,this, &MainWindow::Run);
      }
      
      void MainWindow::ReceiveGView(QGraphicsScene *scene)
      {
          std::cout << "================ MainWindow::ReceiveGView ================ \n" << std::flush;
          std::cout << "scene = " << scene << '\n' << std::flush;
          m_ui->graphicsView->setScene(scene);
          m_ui->graphicsView->show();
          // want to delete scene here, to save memory
          //scene->clear(); //causes crash [not supprised]
      }
      
      void MainWindow::ReceiveGView2(QGraphicsScene *scene)
      {
          std::cout << "================ MainWindow::ReceiveGView2 ================ \n" << std::flush;
          m_ui->graphicsView_2->setScene(scene);
          m_ui->graphicsView_2->show();
      }
      
      void MainWindow::Run()
      {
          std::cout << "================ MainWindow::Run ================ \n" << std::flush;
          emit EmitDisPlayView();
      }
      
      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H
      
      #include <QApplication>
      #include <QCoreApplication>
      #include <QDebug>
      #include <QGraphicsScene>
      #include <QtGui>
      #include <QMainWindow>
      //#include <QSerialPort>
      #include <QThread>
      #include <cstring>
      #include <fstream>
      #include <functional>
      #include <iostream>
      #include <sstream>
      #include <string>
      #include "ui_mainwindow.h"
      
      QT_BEGIN_NAMESPACE
      namespace Ui { class MainWindow; }
      QT_END_NAMESPACE
      
      class CThreadController;
      
      class MainWindow : public QMainWindow
      {
          Q_OBJECT
      
      private:
          Ui::MainWindow *m_ui;
          CThreadController *m_threadcontroller;
      
      public:
          MainWindow(QWidget *parent = nullptr);
          ~MainWindow();
      
          void SetController(CThreadController *controller);
          void ReceiveGView(QGraphicsScene *scene);
          void ReceiveGView2(QGraphicsScene *scene);
          void Run();
      
          // signals
      signals:
          void EmitDisPlayView();
      
      };
      #endif // MAINWINDOW_H
      
      #include "CSceneView.h"
      
      CSceneView::CSceneView() : QGraphicsScene()
      {
          m_GScene = new QGraphicsScene(this);
          m_GScene_2 = new QGraphicsScene(this);
      }
      
      
      // get/set
      void CSceneView::SetController(CThreadController *controller)
      {
          std::cout << "================ CSceneView::SetController ================ \n" << std::flush;
          m_threadcontroller = controller;
      }
      
      void CSceneView::DisPlayView()
      {
          std::cout << "================ CSceneView::DisPlayView ================ \n" << std::flush;
      /*
          m_GScene->clear();
          m_GScene_2->clear();
          m_GScene = new QGraphicsScene(this);
          m_GScene_2 = new QGraphicsScene(this);
      */
          int i = 0;
          int j = 0;
      
          while(i < 20000)
          {
              while(j < 20000)
              {
                  m_GScene->addEllipse((j), (i), 1, 1);
                  m_GScene_2->addEllipse((i), (j), 1, 1);
                  j++;
              }
              i++;
          }
      
          emit EmitGView(m_GScene);
          emit EmitGView2(m_GScene_2);
      }
      
      
      void CSceneView::ReceiveDisPlayView()
      {
          std::cout << "================ CSceneView::ReceiveDisPlayView ================ \n" << std::flush;
          QString s = QString::number((long long)(this->thread()), 16);
          std::cout << "CSceneView   this->thread() = " << s.toStdString() << '\n' << std::flush;
      
          // new scene so two threads are not using same pointer at same time
          m_GScene->clear();
          m_GScene_2->clear();
          //m_GScene = new QGraphicsScene(this);
          //m_GScene_2 = new QGraphicsScene(this);
      
          DisPlayView();
          //TestArray();
      }
      
      #ifndef CSCENEVIEW_H
      #define CSCENEVIEW_H
      
      #include <QGraphicsScene>
      #include <QObject>
      #include <iostream>
      
      class CThreadController;
      
      class CSceneView : public QGraphicsScene
      {
          Q_OBJECT
          // data
      public:
          CThreadController *m_threadcontroller;
          QGraphicsScene * m_GScene;
          QGraphicsScene * m_GScene_2;
      
          // constructor
          CSceneView();
      
          // get/set
          void SetController(CThreadController *controller);
      
          // function
          void DisPlayView();
          // signals
      signals:
          void EmitGView(QGraphicsScene *scene);
          void EmitGView2(QGraphicsScene *scene);
          void EmitDisPlayView();
      
      public slots:
          void ReceiveDisPlayView();
      
      };
      
      #endif // CSCENEVIEW_H
      
      #include "CThreadController.h"
      
      CThreadController::CThreadController() : QThread()
      {
          m_threadsceneview = new QThread();
      }
      
      void CThreadController::SetMainWindow(MainWindow *w)           //?? : public QMainWindow
      {
          std::cout << "CThreadController w = " << w << '\n' << std::flush;
          m_mainwindow = w;
      }
      
      void CThreadController::SetSceneView(CSceneView *sceneview) //?? : public QGraphicsScene
      {
          std::cout << "CThreadController sceneview = " << sceneview << '\n' << std::flush;
          m_sceneview = sceneview;
          m_sceneview->moveToThread(m_threadsceneview);
          connect(m_threadsceneview, &QThread::finished, m_sceneview, &QObject::deleteLater);
          connect(m_threadsceneview, &QThread::finished, m_threadsceneview, &QThread::deleteLater);
          m_threadsceneview->start();
      }
      
      void CThreadController::SetViewLoop(CViewLoop *vloop) //?? : public QThread
      {
          std::cout << "CThreadController vloop = " << vloop << '\n' << std::flush;
          std::cout << "CThreadController m_threadvloop = " << m_threadvloop << '\n' << std::flush;
          m_threadvloop = vloop;
          connect(m_threadvloop, &QThread::finished, m_threadvloop, &QObject::deleteLater);
          connect(m_threadvloop, &QThread::finished, m_threadvloop, &QThread::deleteLater);
          m_threadvloop->start();
      }
      
      // function
      void CThreadController::startThreads()
      {
          std::cout << "CThreadController::startThreads begin\n" << std::flush;
          std::cout << "CThreadController::startThreads m_mainwindow = " << m_mainwindow << '\n' << std::flush;
          std::cout << "CThreadController::startThreads m_sceneview = " << m_sceneview << '\n' << std::flush;
      
          //?? CSeneView -> mainwindow
          connect(m_sceneview, &CSceneView::EmitGView, m_mainwindow, &MainWindow::ReceiveGView);
          connect(m_sceneview, &CSceneView::EmitGView2, m_mainwindow, &MainWindow::ReceiveGView2);
      
          //?? MainWindow -> CSeneView
          connect(m_mainwindow, &MainWindow::EmitDisPlayView, m_sceneview,
                  &CSceneView::ReceiveDisPlayView);
      
          //?? CSeneView -> CSeneView
          connect(m_sceneview, &CSceneView::EmitDisPlayView, m_sceneview,
                  &CSceneView::ReceiveDisPlayView);
      
          //?? CViewLoop -> CSeneView
          connect(m_threadvloop, &CViewLoop::EmitDisPlayView, m_sceneview,
                  &CSceneView::ReceiveDisPlayView);
      
      
      }
      
      void CThreadController::ShowPointers()
      {
          QString qs = QString::number((long long)(QThread::currentThreadId()), 16);
          std::cout << "CThreadController   QThread::currentThreadId() = " << qs.toStdString() << '\n' << std::flush;
          std::cout << "CThreadController::ShowPointers m_threadvloop = " << m_threadvloop << '\n' << std::flush;
          std::cout << "CThreadController::ShowPointers m_mainwindow = " << m_mainwindow << '\n' << std::flush;
          std::cout << "CThreadController::ShowPointers m_sceneview = " << m_sceneview << '\n' << std::flush;
      }
      
      #ifndef CTHREADCONTROLLER_H
      #define CTHREADCONTROLLER_H
      
      #include "CMainWindow.h"
      #include "CSceneView.h"
      #include "CViewLoop.h"
      #include <QObject>
      #include <QThread>
      
      class CThreadController : public QThread
      {
          Q_OBJECT
      private:
          // data
          MainWindow *m_mainwindow;                    //?? : public QMainWindow
          CSceneView *m_sceneview;        //?? : public QGraphicsScene
          QThread* m_threadsceneview;
          CViewLoop *m_threadvloop;       //?? : public QThread
      
      public:
          CThreadController();
      
          // get/set
          void SetMainWindow(MainWindow *w);
          void SetSceneView(CSceneView *sceneview);
          void SetViewLoop(CViewLoop *vloop);
      
          // function
          void startThreads();
          void ShowPointers();
      };
      
      #endif // CTHREADCONTROLLER_H
      
      //#include "CSceneView.h"
      #include "CViewLoop.h"
      
      CViewLoop::CViewLoop()
      {
          m_sState = "error";
      }
      
      // get/set
      void CViewLoop::SetState(std::string s)
      {
          m_sState = s;
      }
      
      // function
      void CViewLoop::Print(std::string s)
      {
          std::cout << s << '\n' << std::flush;
          m_file << s << '\n' << std::flush;
      }
      
      void CViewLoop::run()
      {
          /* ... here is the expensive or blocking operation ... */
          int runtime = 10;
          int i = 0;
          while(true)
          {
              if( (m_sState == "error") || (m_sState == "run"))
              {
                  Print("CViewLoop::run 'error' or 'run' i = " + std::to_string(i));
                  emit EmitDisPlayView();
                  sleep(runtime); //?? 1 = 1 seconds, 5 = 5 seconds
                  i++;
              }
              else
              {
                  Print("CViewLoop::run 'else'");
                  this->sleep(40);
              }
          }
      
          Print("CViewLoop::run exit");
      }
      
      #ifndef CVIEWLOOP_H
      #define CVIEWLOOP_H
      
      #include <fstream>
      #include <iostream>
      #include <QObject>
      #include <QThread>
      
      //class CSceneView;
      
      class CViewLoop : public QThread
      {
          Q_OBJECT
      //?? data
      private:
          std::ofstream m_file;
          std::string m_sState;
          //CSceneView *m_scene;
      
      public:
          // constructors
          CViewLoop();
      
          // get/set
          void SetState(std::string s);
          //void SetSceneView(CSceneView *scene);
      
          // functions
          void Print(std::string s);
          void run() override;
      
          // signals
      signals:
          void EmitDisPlayView();
      
      };
      
      #endif // CVIEWLOOP_H
      

      if

      m_GScene = new QGraphicsScene(this);
      

      is only in constructor, then it will run , but sigfaults or locks up dependent on how often a button and which button is clicked.
      if it is used each time scene is updated, randomly sigfaults, around 2 to 20 updates.
      i moved it between two functions, think one function lasted longer that the other, but could not figure out how, then i ran same program multiple times, and noticed that sigfault was random.
      It seems updating scene at same time as scene would be a cause of sigfault, so I made new QGraphicsScene(this); each time. I tried to pass a copy, but seems copy can not be made of scene, could not even write a copy constructor for it.

      How to update scene in one thread and and shown on another thread?

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @micha_eleric
      Qt requires that all UI updates only happen on the main thread. Secondary threads must not do UI stuff. They can do calculations (not involving UI) and communicate with the UI thread via signals/slots as required.

      On another matter, you cannot copy a QObject (defined to forbid copy constructor) or anything derived from it, which includes a QGraphicsScene, so no point wasting time on that.

      M 1 Reply Last reply
      1
      • JonBJ JonB

        @micha_eleric
        Qt requires that all UI updates only happen on the main thread. Secondary threads must not do UI stuff. They can do calculations (not involving UI) and communicate with the UI thread via signals/slots as required.

        On another matter, you cannot copy a QObject (defined to forbid copy constructor) or anything derived from it, which includes a QGraphicsScene, so no point wasting time on that.

        M Offline
        M Offline
        micha_eleric
        wrote on last edited by
        #3

        @JonB thanks. issue i have been having, is while scene is updating, gui freezes.

        JonBJ J.HilkJ 2 Replies Last reply
        0
        • M micha_eleric

          @JonB thanks. issue i have been having, is while scene is updating, gui freezes.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @micha_eleric Is there a further question here?

          1 Reply Last reply
          0
          • M micha_eleric

            Trying to use one thread to update scene, and another thread to show, but sigfaults if scene id updated to often.

            #include "CThreadController.h"
            
            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
            
                CThreadController threcon;
                MainWindow w;
                CSceneView scene;
                CViewLoop vloop;
            
                w.SetController(&threcon);
                scene.SetController(&threcon);
            
                threcon.SetMainWindow(&w);
                threcon.SetSceneView(&scene);
                threcon.SetViewLoop(&vloop);
            
                threcon.startThreads();
                threcon.ShowPointers();
                w.show();
                return a.exec();
            }
            
            #include "CMainWindow.h"
            #include "CThreadController.h"
            
            MainWindow::MainWindow(QWidget *parent)
                : QMainWindow(parent)
                , m_ui(new Ui::MainWindow)
            {
                m_ui->setupUi(this);
            }
            
            MainWindow::~MainWindow()
            {
                delete m_ui;
            }
            
            void MainWindow::SetController(CThreadController *controller)
            {
                m_threadcontroller = controller;
                connect(m_ui->pushButton, &QPushButton::clicked,this, &MainWindow::Run);
            }
            
            void MainWindow::ReceiveGView(QGraphicsScene *scene)
            {
                std::cout << "================ MainWindow::ReceiveGView ================ \n" << std::flush;
                std::cout << "scene = " << scene << '\n' << std::flush;
                m_ui->graphicsView->setScene(scene);
                m_ui->graphicsView->show();
                // want to delete scene here, to save memory
                //scene->clear(); //causes crash [not supprised]
            }
            
            void MainWindow::ReceiveGView2(QGraphicsScene *scene)
            {
                std::cout << "================ MainWindow::ReceiveGView2 ================ \n" << std::flush;
                m_ui->graphicsView_2->setScene(scene);
                m_ui->graphicsView_2->show();
            }
            
            void MainWindow::Run()
            {
                std::cout << "================ MainWindow::Run ================ \n" << std::flush;
                emit EmitDisPlayView();
            }
            
            #ifndef MAINWINDOW_H
            #define MAINWINDOW_H
            
            #include <QApplication>
            #include <QCoreApplication>
            #include <QDebug>
            #include <QGraphicsScene>
            #include <QtGui>
            #include <QMainWindow>
            //#include <QSerialPort>
            #include <QThread>
            #include <cstring>
            #include <fstream>
            #include <functional>
            #include <iostream>
            #include <sstream>
            #include <string>
            #include "ui_mainwindow.h"
            
            QT_BEGIN_NAMESPACE
            namespace Ui { class MainWindow; }
            QT_END_NAMESPACE
            
            class CThreadController;
            
            class MainWindow : public QMainWindow
            {
                Q_OBJECT
            
            private:
                Ui::MainWindow *m_ui;
                CThreadController *m_threadcontroller;
            
            public:
                MainWindow(QWidget *parent = nullptr);
                ~MainWindow();
            
                void SetController(CThreadController *controller);
                void ReceiveGView(QGraphicsScene *scene);
                void ReceiveGView2(QGraphicsScene *scene);
                void Run();
            
                // signals
            signals:
                void EmitDisPlayView();
            
            };
            #endif // MAINWINDOW_H
            
            #include "CSceneView.h"
            
            CSceneView::CSceneView() : QGraphicsScene()
            {
                m_GScene = new QGraphicsScene(this);
                m_GScene_2 = new QGraphicsScene(this);
            }
            
            
            // get/set
            void CSceneView::SetController(CThreadController *controller)
            {
                std::cout << "================ CSceneView::SetController ================ \n" << std::flush;
                m_threadcontroller = controller;
            }
            
            void CSceneView::DisPlayView()
            {
                std::cout << "================ CSceneView::DisPlayView ================ \n" << std::flush;
            /*
                m_GScene->clear();
                m_GScene_2->clear();
                m_GScene = new QGraphicsScene(this);
                m_GScene_2 = new QGraphicsScene(this);
            */
                int i = 0;
                int j = 0;
            
                while(i < 20000)
                {
                    while(j < 20000)
                    {
                        m_GScene->addEllipse((j), (i), 1, 1);
                        m_GScene_2->addEllipse((i), (j), 1, 1);
                        j++;
                    }
                    i++;
                }
            
                emit EmitGView(m_GScene);
                emit EmitGView2(m_GScene_2);
            }
            
            
            void CSceneView::ReceiveDisPlayView()
            {
                std::cout << "================ CSceneView::ReceiveDisPlayView ================ \n" << std::flush;
                QString s = QString::number((long long)(this->thread()), 16);
                std::cout << "CSceneView   this->thread() = " << s.toStdString() << '\n' << std::flush;
            
                // new scene so two threads are not using same pointer at same time
                m_GScene->clear();
                m_GScene_2->clear();
                //m_GScene = new QGraphicsScene(this);
                //m_GScene_2 = new QGraphicsScene(this);
            
                DisPlayView();
                //TestArray();
            }
            
            #ifndef CSCENEVIEW_H
            #define CSCENEVIEW_H
            
            #include <QGraphicsScene>
            #include <QObject>
            #include <iostream>
            
            class CThreadController;
            
            class CSceneView : public QGraphicsScene
            {
                Q_OBJECT
                // data
            public:
                CThreadController *m_threadcontroller;
                QGraphicsScene * m_GScene;
                QGraphicsScene * m_GScene_2;
            
                // constructor
                CSceneView();
            
                // get/set
                void SetController(CThreadController *controller);
            
                // function
                void DisPlayView();
                // signals
            signals:
                void EmitGView(QGraphicsScene *scene);
                void EmitGView2(QGraphicsScene *scene);
                void EmitDisPlayView();
            
            public slots:
                void ReceiveDisPlayView();
            
            };
            
            #endif // CSCENEVIEW_H
            
            #include "CThreadController.h"
            
            CThreadController::CThreadController() : QThread()
            {
                m_threadsceneview = new QThread();
            }
            
            void CThreadController::SetMainWindow(MainWindow *w)           //?? : public QMainWindow
            {
                std::cout << "CThreadController w = " << w << '\n' << std::flush;
                m_mainwindow = w;
            }
            
            void CThreadController::SetSceneView(CSceneView *sceneview) //?? : public QGraphicsScene
            {
                std::cout << "CThreadController sceneview = " << sceneview << '\n' << std::flush;
                m_sceneview = sceneview;
                m_sceneview->moveToThread(m_threadsceneview);
                connect(m_threadsceneview, &QThread::finished, m_sceneview, &QObject::deleteLater);
                connect(m_threadsceneview, &QThread::finished, m_threadsceneview, &QThread::deleteLater);
                m_threadsceneview->start();
            }
            
            void CThreadController::SetViewLoop(CViewLoop *vloop) //?? : public QThread
            {
                std::cout << "CThreadController vloop = " << vloop << '\n' << std::flush;
                std::cout << "CThreadController m_threadvloop = " << m_threadvloop << '\n' << std::flush;
                m_threadvloop = vloop;
                connect(m_threadvloop, &QThread::finished, m_threadvloop, &QObject::deleteLater);
                connect(m_threadvloop, &QThread::finished, m_threadvloop, &QThread::deleteLater);
                m_threadvloop->start();
            }
            
            // function
            void CThreadController::startThreads()
            {
                std::cout << "CThreadController::startThreads begin\n" << std::flush;
                std::cout << "CThreadController::startThreads m_mainwindow = " << m_mainwindow << '\n' << std::flush;
                std::cout << "CThreadController::startThreads m_sceneview = " << m_sceneview << '\n' << std::flush;
            
                //?? CSeneView -> mainwindow
                connect(m_sceneview, &CSceneView::EmitGView, m_mainwindow, &MainWindow::ReceiveGView);
                connect(m_sceneview, &CSceneView::EmitGView2, m_mainwindow, &MainWindow::ReceiveGView2);
            
                //?? MainWindow -> CSeneView
                connect(m_mainwindow, &MainWindow::EmitDisPlayView, m_sceneview,
                        &CSceneView::ReceiveDisPlayView);
            
                //?? CSeneView -> CSeneView
                connect(m_sceneview, &CSceneView::EmitDisPlayView, m_sceneview,
                        &CSceneView::ReceiveDisPlayView);
            
                //?? CViewLoop -> CSeneView
                connect(m_threadvloop, &CViewLoop::EmitDisPlayView, m_sceneview,
                        &CSceneView::ReceiveDisPlayView);
            
            
            }
            
            void CThreadController::ShowPointers()
            {
                QString qs = QString::number((long long)(QThread::currentThreadId()), 16);
                std::cout << "CThreadController   QThread::currentThreadId() = " << qs.toStdString() << '\n' << std::flush;
                std::cout << "CThreadController::ShowPointers m_threadvloop = " << m_threadvloop << '\n' << std::flush;
                std::cout << "CThreadController::ShowPointers m_mainwindow = " << m_mainwindow << '\n' << std::flush;
                std::cout << "CThreadController::ShowPointers m_sceneview = " << m_sceneview << '\n' << std::flush;
            }
            
            #ifndef CTHREADCONTROLLER_H
            #define CTHREADCONTROLLER_H
            
            #include "CMainWindow.h"
            #include "CSceneView.h"
            #include "CViewLoop.h"
            #include <QObject>
            #include <QThread>
            
            class CThreadController : public QThread
            {
                Q_OBJECT
            private:
                // data
                MainWindow *m_mainwindow;                    //?? : public QMainWindow
                CSceneView *m_sceneview;        //?? : public QGraphicsScene
                QThread* m_threadsceneview;
                CViewLoop *m_threadvloop;       //?? : public QThread
            
            public:
                CThreadController();
            
                // get/set
                void SetMainWindow(MainWindow *w);
                void SetSceneView(CSceneView *sceneview);
                void SetViewLoop(CViewLoop *vloop);
            
                // function
                void startThreads();
                void ShowPointers();
            };
            
            #endif // CTHREADCONTROLLER_H
            
            //#include "CSceneView.h"
            #include "CViewLoop.h"
            
            CViewLoop::CViewLoop()
            {
                m_sState = "error";
            }
            
            // get/set
            void CViewLoop::SetState(std::string s)
            {
                m_sState = s;
            }
            
            // function
            void CViewLoop::Print(std::string s)
            {
                std::cout << s << '\n' << std::flush;
                m_file << s << '\n' << std::flush;
            }
            
            void CViewLoop::run()
            {
                /* ... here is the expensive or blocking operation ... */
                int runtime = 10;
                int i = 0;
                while(true)
                {
                    if( (m_sState == "error") || (m_sState == "run"))
                    {
                        Print("CViewLoop::run 'error' or 'run' i = " + std::to_string(i));
                        emit EmitDisPlayView();
                        sleep(runtime); //?? 1 = 1 seconds, 5 = 5 seconds
                        i++;
                    }
                    else
                    {
                        Print("CViewLoop::run 'else'");
                        this->sleep(40);
                    }
                }
            
                Print("CViewLoop::run exit");
            }
            
            #ifndef CVIEWLOOP_H
            #define CVIEWLOOP_H
            
            #include <fstream>
            #include <iostream>
            #include <QObject>
            #include <QThread>
            
            //class CSceneView;
            
            class CViewLoop : public QThread
            {
                Q_OBJECT
            //?? data
            private:
                std::ofstream m_file;
                std::string m_sState;
                //CSceneView *m_scene;
            
            public:
                // constructors
                CViewLoop();
            
                // get/set
                void SetState(std::string s);
                //void SetSceneView(CSceneView *scene);
            
                // functions
                void Print(std::string s);
                void run() override;
            
                // signals
            signals:
                void EmitDisPlayView();
            
            };
            
            #endif // CVIEWLOOP_H
            

            if

            m_GScene = new QGraphicsScene(this);
            

            is only in constructor, then it will run , but sigfaults or locks up dependent on how often a button and which button is clicked.
            if it is used each time scene is updated, randomly sigfaults, around 2 to 20 updates.
            i moved it between two functions, think one function lasted longer that the other, but could not figure out how, then i ran same program multiple times, and noticed that sigfault was random.
            It seems updating scene at same time as scene would be a cause of sigfault, so I made new QGraphicsScene(this); each time. I tried to pass a copy, but seems copy can not be made of scene, could not even write a copy constructor for it.

            How to update scene in one thread and and shown on another thread?

            S Offline
            S Offline
            starkm42
            wrote on last edited by starkm42
            #5

            @micha_eleric as mentioned by @JonB, i am afraid you cannot do drawEclipse in worker thread, refer here : https://doc.qt.io/qt-6/thread-basics.html#qobject-and-threads

            only certain QPaintDevices which do not inherit QObject can be worked on in a Worker Thread i.e. QImage.

            when you run your example you might get something like below

            QCoreApplication::sendPostedEvents: Cannot send posted events for objects in another thread
            

            this is indicating the above point of why this is not feasible.

            also try looking to parameterized constructors, instead of setter methods. and try to limit connect calls to constructor of the class. latter suggestion is just for readability purpose.

            1 Reply Last reply
            1
            • S Offline
              S Offline
              SimonSchroeder
              wrote on last edited by
              #6

              You must make sure that you do not change the scene while it is being drawn. Otherwise the change might change a pointer (and delete the underlying object) which the GUI thread is currently accessing. This will definitely blow up.

              The best advice is to do some sort of double buffering: Use 2 different pointers to QGraphicsScene. Use one pointer to change the scene and the other to display inside the GUI. The GUI thread needs to lock a mutex while drawing (and unlock it afterwards). After doing your changes in the other thread, also lock the mutex and swap the two pointers. Now, you are thread safe.

              1 Reply Last reply
              0
              • M micha_eleric

                @JonB thanks. issue i have been having, is while scene is updating, gui freezes.

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #7

                @micha_eleric said in Threading scene:

                @JonB thanks. issue i have been having, is while scene is updating, gui freezes.

                you're drawing/updating 400 000 000 - 400 million! - objects on a CPU based renderer and asking yourself why the guy freezes ?


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                1 Reply Last reply
                2
                • M micha_eleric

                  Trying to use one thread to update scene, and another thread to show, but sigfaults if scene id updated to often.

                  #include "CThreadController.h"
                  
                  int main(int argc, char *argv[])
                  {
                      QApplication a(argc, argv);
                  
                      CThreadController threcon;
                      MainWindow w;
                      CSceneView scene;
                      CViewLoop vloop;
                  
                      w.SetController(&threcon);
                      scene.SetController(&threcon);
                  
                      threcon.SetMainWindow(&w);
                      threcon.SetSceneView(&scene);
                      threcon.SetViewLoop(&vloop);
                  
                      threcon.startThreads();
                      threcon.ShowPointers();
                      w.show();
                      return a.exec();
                  }
                  
                  #include "CMainWindow.h"
                  #include "CThreadController.h"
                  
                  MainWindow::MainWindow(QWidget *parent)
                      : QMainWindow(parent)
                      , m_ui(new Ui::MainWindow)
                  {
                      m_ui->setupUi(this);
                  }
                  
                  MainWindow::~MainWindow()
                  {
                      delete m_ui;
                  }
                  
                  void MainWindow::SetController(CThreadController *controller)
                  {
                      m_threadcontroller = controller;
                      connect(m_ui->pushButton, &QPushButton::clicked,this, &MainWindow::Run);
                  }
                  
                  void MainWindow::ReceiveGView(QGraphicsScene *scene)
                  {
                      std::cout << "================ MainWindow::ReceiveGView ================ \n" << std::flush;
                      std::cout << "scene = " << scene << '\n' << std::flush;
                      m_ui->graphicsView->setScene(scene);
                      m_ui->graphicsView->show();
                      // want to delete scene here, to save memory
                      //scene->clear(); //causes crash [not supprised]
                  }
                  
                  void MainWindow::ReceiveGView2(QGraphicsScene *scene)
                  {
                      std::cout << "================ MainWindow::ReceiveGView2 ================ \n" << std::flush;
                      m_ui->graphicsView_2->setScene(scene);
                      m_ui->graphicsView_2->show();
                  }
                  
                  void MainWindow::Run()
                  {
                      std::cout << "================ MainWindow::Run ================ \n" << std::flush;
                      emit EmitDisPlayView();
                  }
                  
                  #ifndef MAINWINDOW_H
                  #define MAINWINDOW_H
                  
                  #include <QApplication>
                  #include <QCoreApplication>
                  #include <QDebug>
                  #include <QGraphicsScene>
                  #include <QtGui>
                  #include <QMainWindow>
                  //#include <QSerialPort>
                  #include <QThread>
                  #include <cstring>
                  #include <fstream>
                  #include <functional>
                  #include <iostream>
                  #include <sstream>
                  #include <string>
                  #include "ui_mainwindow.h"
                  
                  QT_BEGIN_NAMESPACE
                  namespace Ui { class MainWindow; }
                  QT_END_NAMESPACE
                  
                  class CThreadController;
                  
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                  
                  private:
                      Ui::MainWindow *m_ui;
                      CThreadController *m_threadcontroller;
                  
                  public:
                      MainWindow(QWidget *parent = nullptr);
                      ~MainWindow();
                  
                      void SetController(CThreadController *controller);
                      void ReceiveGView(QGraphicsScene *scene);
                      void ReceiveGView2(QGraphicsScene *scene);
                      void Run();
                  
                      // signals
                  signals:
                      void EmitDisPlayView();
                  
                  };
                  #endif // MAINWINDOW_H
                  
                  #include "CSceneView.h"
                  
                  CSceneView::CSceneView() : QGraphicsScene()
                  {
                      m_GScene = new QGraphicsScene(this);
                      m_GScene_2 = new QGraphicsScene(this);
                  }
                  
                  
                  // get/set
                  void CSceneView::SetController(CThreadController *controller)
                  {
                      std::cout << "================ CSceneView::SetController ================ \n" << std::flush;
                      m_threadcontroller = controller;
                  }
                  
                  void CSceneView::DisPlayView()
                  {
                      std::cout << "================ CSceneView::DisPlayView ================ \n" << std::flush;
                  /*
                      m_GScene->clear();
                      m_GScene_2->clear();
                      m_GScene = new QGraphicsScene(this);
                      m_GScene_2 = new QGraphicsScene(this);
                  */
                      int i = 0;
                      int j = 0;
                  
                      while(i < 20000)
                      {
                          while(j < 20000)
                          {
                              m_GScene->addEllipse((j), (i), 1, 1);
                              m_GScene_2->addEllipse((i), (j), 1, 1);
                              j++;
                          }
                          i++;
                      }
                  
                      emit EmitGView(m_GScene);
                      emit EmitGView2(m_GScene_2);
                  }
                  
                  
                  void CSceneView::ReceiveDisPlayView()
                  {
                      std::cout << "================ CSceneView::ReceiveDisPlayView ================ \n" << std::flush;
                      QString s = QString::number((long long)(this->thread()), 16);
                      std::cout << "CSceneView   this->thread() = " << s.toStdString() << '\n' << std::flush;
                  
                      // new scene so two threads are not using same pointer at same time
                      m_GScene->clear();
                      m_GScene_2->clear();
                      //m_GScene = new QGraphicsScene(this);
                      //m_GScene_2 = new QGraphicsScene(this);
                  
                      DisPlayView();
                      //TestArray();
                  }
                  
                  #ifndef CSCENEVIEW_H
                  #define CSCENEVIEW_H
                  
                  #include <QGraphicsScene>
                  #include <QObject>
                  #include <iostream>
                  
                  class CThreadController;
                  
                  class CSceneView : public QGraphicsScene
                  {
                      Q_OBJECT
                      // data
                  public:
                      CThreadController *m_threadcontroller;
                      QGraphicsScene * m_GScene;
                      QGraphicsScene * m_GScene_2;
                  
                      // constructor
                      CSceneView();
                  
                      // get/set
                      void SetController(CThreadController *controller);
                  
                      // function
                      void DisPlayView();
                      // signals
                  signals:
                      void EmitGView(QGraphicsScene *scene);
                      void EmitGView2(QGraphicsScene *scene);
                      void EmitDisPlayView();
                  
                  public slots:
                      void ReceiveDisPlayView();
                  
                  };
                  
                  #endif // CSCENEVIEW_H
                  
                  #include "CThreadController.h"
                  
                  CThreadController::CThreadController() : QThread()
                  {
                      m_threadsceneview = new QThread();
                  }
                  
                  void CThreadController::SetMainWindow(MainWindow *w)           //?? : public QMainWindow
                  {
                      std::cout << "CThreadController w = " << w << '\n' << std::flush;
                      m_mainwindow = w;
                  }
                  
                  void CThreadController::SetSceneView(CSceneView *sceneview) //?? : public QGraphicsScene
                  {
                      std::cout << "CThreadController sceneview = " << sceneview << '\n' << std::flush;
                      m_sceneview = sceneview;
                      m_sceneview->moveToThread(m_threadsceneview);
                      connect(m_threadsceneview, &QThread::finished, m_sceneview, &QObject::deleteLater);
                      connect(m_threadsceneview, &QThread::finished, m_threadsceneview, &QThread::deleteLater);
                      m_threadsceneview->start();
                  }
                  
                  void CThreadController::SetViewLoop(CViewLoop *vloop) //?? : public QThread
                  {
                      std::cout << "CThreadController vloop = " << vloop << '\n' << std::flush;
                      std::cout << "CThreadController m_threadvloop = " << m_threadvloop << '\n' << std::flush;
                      m_threadvloop = vloop;
                      connect(m_threadvloop, &QThread::finished, m_threadvloop, &QObject::deleteLater);
                      connect(m_threadvloop, &QThread::finished, m_threadvloop, &QThread::deleteLater);
                      m_threadvloop->start();
                  }
                  
                  // function
                  void CThreadController::startThreads()
                  {
                      std::cout << "CThreadController::startThreads begin\n" << std::flush;
                      std::cout << "CThreadController::startThreads m_mainwindow = " << m_mainwindow << '\n' << std::flush;
                      std::cout << "CThreadController::startThreads m_sceneview = " << m_sceneview << '\n' << std::flush;
                  
                      //?? CSeneView -> mainwindow
                      connect(m_sceneview, &CSceneView::EmitGView, m_mainwindow, &MainWindow::ReceiveGView);
                      connect(m_sceneview, &CSceneView::EmitGView2, m_mainwindow, &MainWindow::ReceiveGView2);
                  
                      //?? MainWindow -> CSeneView
                      connect(m_mainwindow, &MainWindow::EmitDisPlayView, m_sceneview,
                              &CSceneView::ReceiveDisPlayView);
                  
                      //?? CSeneView -> CSeneView
                      connect(m_sceneview, &CSceneView::EmitDisPlayView, m_sceneview,
                              &CSceneView::ReceiveDisPlayView);
                  
                      //?? CViewLoop -> CSeneView
                      connect(m_threadvloop, &CViewLoop::EmitDisPlayView, m_sceneview,
                              &CSceneView::ReceiveDisPlayView);
                  
                  
                  }
                  
                  void CThreadController::ShowPointers()
                  {
                      QString qs = QString::number((long long)(QThread::currentThreadId()), 16);
                      std::cout << "CThreadController   QThread::currentThreadId() = " << qs.toStdString() << '\n' << std::flush;
                      std::cout << "CThreadController::ShowPointers m_threadvloop = " << m_threadvloop << '\n' << std::flush;
                      std::cout << "CThreadController::ShowPointers m_mainwindow = " << m_mainwindow << '\n' << std::flush;
                      std::cout << "CThreadController::ShowPointers m_sceneview = " << m_sceneview << '\n' << std::flush;
                  }
                  
                  #ifndef CTHREADCONTROLLER_H
                  #define CTHREADCONTROLLER_H
                  
                  #include "CMainWindow.h"
                  #include "CSceneView.h"
                  #include "CViewLoop.h"
                  #include <QObject>
                  #include <QThread>
                  
                  class CThreadController : public QThread
                  {
                      Q_OBJECT
                  private:
                      // data
                      MainWindow *m_mainwindow;                    //?? : public QMainWindow
                      CSceneView *m_sceneview;        //?? : public QGraphicsScene
                      QThread* m_threadsceneview;
                      CViewLoop *m_threadvloop;       //?? : public QThread
                  
                  public:
                      CThreadController();
                  
                      // get/set
                      void SetMainWindow(MainWindow *w);
                      void SetSceneView(CSceneView *sceneview);
                      void SetViewLoop(CViewLoop *vloop);
                  
                      // function
                      void startThreads();
                      void ShowPointers();
                  };
                  
                  #endif // CTHREADCONTROLLER_H
                  
                  //#include "CSceneView.h"
                  #include "CViewLoop.h"
                  
                  CViewLoop::CViewLoop()
                  {
                      m_sState = "error";
                  }
                  
                  // get/set
                  void CViewLoop::SetState(std::string s)
                  {
                      m_sState = s;
                  }
                  
                  // function
                  void CViewLoop::Print(std::string s)
                  {
                      std::cout << s << '\n' << std::flush;
                      m_file << s << '\n' << std::flush;
                  }
                  
                  void CViewLoop::run()
                  {
                      /* ... here is the expensive or blocking operation ... */
                      int runtime = 10;
                      int i = 0;
                      while(true)
                      {
                          if( (m_sState == "error") || (m_sState == "run"))
                          {
                              Print("CViewLoop::run 'error' or 'run' i = " + std::to_string(i));
                              emit EmitDisPlayView();
                              sleep(runtime); //?? 1 = 1 seconds, 5 = 5 seconds
                              i++;
                          }
                          else
                          {
                              Print("CViewLoop::run 'else'");
                              this->sleep(40);
                          }
                      }
                  
                      Print("CViewLoop::run exit");
                  }
                  
                  #ifndef CVIEWLOOP_H
                  #define CVIEWLOOP_H
                  
                  #include <fstream>
                  #include <iostream>
                  #include <QObject>
                  #include <QThread>
                  
                  //class CSceneView;
                  
                  class CViewLoop : public QThread
                  {
                      Q_OBJECT
                  //?? data
                  private:
                      std::ofstream m_file;
                      std::string m_sState;
                      //CSceneView *m_scene;
                  
                  public:
                      // constructors
                      CViewLoop();
                  
                      // get/set
                      void SetState(std::string s);
                      //void SetSceneView(CSceneView *scene);
                  
                      // functions
                      void Print(std::string s);
                      void run() override;
                  
                      // signals
                  signals:
                      void EmitDisPlayView();
                  
                  };
                  
                  #endif // CVIEWLOOP_H
                  

                  if

                  m_GScene = new QGraphicsScene(this);
                  

                  is only in constructor, then it will run , but sigfaults or locks up dependent on how often a button and which button is clicked.
                  if it is used each time scene is updated, randomly sigfaults, around 2 to 20 updates.
                  i moved it between two functions, think one function lasted longer that the other, but could not figure out how, then i ran same program multiple times, and noticed that sigfault was random.
                  It seems updating scene at same time as scene would be a cause of sigfault, so I made new QGraphicsScene(this); each time. I tried to pass a copy, but seems copy can not be made of scene, could not even write a copy constructor for it.

                  How to update scene in one thread and and shown on another thread?

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #8

                  @micha_eleric
                  I had not noticed, but as @J-Hilk has said 400,000,000 is a lot of items to draw ;-) Not to mention, this is a lot for the user to look at/I'm not sure there are even that many pixels on the screen! But I guess you will see this is just a test.

                  If you have a "lot" of add/move/delete operations to perform, you must either (a) do the operations in batches on a timer from a "queue" (at least conceptually), presumably from the UI thread, so that the UI has time to render them and remains responsive, or (b) if @SimonSchroeder's principle of "double-buffering"/mutexing works from a thread you would have to release the mutex periodically after batches performed so that the UI thread gets some time to process the updates without blocking on a mutex for too long.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved