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. Widgets must be created in the GUI thread

Widgets must be created in the GUI thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 4 Posters 6.0k 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.
  • R_IrudezuR Offline
    R_IrudezuR Offline
    R_Irudezu
    wrote on last edited by R_Irudezu
    #1

    I have a callback function which runs in another thread. Callback function emits some parameters to GUI thread, when i try to use this parameters for drawing qgraphicsScene, i'm getting these error.

    Here's files:
    workerthread.h:

    class workerThread : public QThread
    {
        Q_OBJECT
    public:
        explicit workerThread(QObject *parent = 0);
    
    signals:
        void sendLocationsFromThread(int, int, int, int);
    };
    
    extern workerThread *w1;
    
    #endif // WORKERTHREAD_H
    

    workerthread.cpp:

    workerThread *w1 = new workerThread();
    void CallBack(some params)
    {
        //this function comes from an external library
        //some process
        emit  w1->sendLocationsFromThread(x, y, w, h);
    }
    workerThread::workerThread(QObject *parent) : QThread(parent)
    {
        //some dll load libraries
    }
    

    mainwindow.h:

    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
        QGraphicsView **graphicsViews;
    
        void drawGraphicsView(int, int, int, int, some params)
    
    public slots:
        void onLocationChanged(int, int, int, int);
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    

    mainwindow.cpp:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
    bool threadConn = connect(w1, SIGNAL(sendLocationsFromThread(int, int, int, int)), this,
                       SLOT(onLocationChanged(int, int, int, int)), Qt::DirectConnection);
    w1->start(QThread::HighPriority);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
        w1->terminate();
    }
    
    void MainWindow::onLocationChanged(int x, int y, int w, int h)
    {
        // creating some params ( create qgraphicView and its specifications etc)
        graphicsViews= new QGraphicsView* [5];
        for(int i = 0; i < 5; i++)
        {
            graphicsViews[i] = new QGraphicsView(ui->someWidget); //error occurs with this line
            drawGraphicsView(int x, int y, int w, int h, some params);
        }
    }
    
    void MainWindow::drawNewGraphicsView(int x, int y, int w, int h, some params)
    {
        //draw somethings on UI with using these parameters
    }
    

    Drawing or something else working fine, such as when i try to trigger draw function with a button, it's ok. But when i use onLocationChanged function it gives error that i specified in the title.

    I used qDebug to see which function works in which thread. onLocationChanged and CallBack is in the same thread. I supposed onLocationChanged must be in the GUI thread, because it is a SLOT of mainwindow.h

    How can i solve this problem? Thanks in advance for any help.

    Keizoku wa chikaranari.

    1 Reply Last reply
    0
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Qt Champions 2022
      wrote on last edited by
      #2

      Your culprit is Qt::DirectConnection. Why are you passing it as direct connection ? Just remove 5th argument(Qt::DirectConnection) and it should work.

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      R_IrudezuR 1 Reply Last reply
      2
      • dheerendraD dheerendra

        Your culprit is Qt::DirectConnection. Why are you passing it as direct connection ? Just remove 5th argument(Qt::DirectConnection) and it should work.

        R_IrudezuR Offline
        R_IrudezuR Offline
        R_Irudezu
        wrote on last edited by R_Irudezu
        #3

        @dheerendra Mr. Dheerendra, if i remove the 5th parameter just like you said, onLocationChanged in the MainWindow.cpp is not working, i mean qDebug() s in it's not shown so that means function is not being processing i think.

        But when i removed Qt::DirectConnection, its not throw any error.
        By the way can you explain why this parameter causes block my program?

        Keizoku wa chikaranari.

        1 Reply Last reply
        0
        • R_IrudezuR Offline
          R_IrudezuR Offline
          R_Irudezu
          wrote on last edited by
          #4

          When i set the 5th parameter as Qt::BlockingQueuedConnection
          code is working now. Thank you Mr. Dheerendra, I am so grateful.

          Keizoku wa chikaranari.

          1 Reply Last reply
          0
          • dheerendraD Offline
            dheerendraD Offline
            dheerendra
            Qt Champions 2022
            wrote on last edited by
            #5

            You should never use DirectConnection unless know we know why we are using. Communication between threads should be asynchronous. By default is it QuedConnection between threads. So thread context of signal and slots will be different. If you pass the direct connection, you are telling to execute the slots in worker thread. UI object should be created only in Mainthread. Due to this it gave you error. Why do you want pass BlockedQConnection ? Do you want to wait the worker thread till main thread finishes the job ?

            Dheerendra
            @Community Service
            Certified Qt Specialist
            http://www.pthinks.com

            R_IrudezuR 1 Reply Last reply
            0
            • dheerendraD dheerendra

              You should never use DirectConnection unless know we know why we are using. Communication between threads should be asynchronous. By default is it QuedConnection between threads. So thread context of signal and slots will be different. If you pass the direct connection, you are telling to execute the slots in worker thread. UI object should be created only in Mainthread. Due to this it gave you error. Why do you want pass BlockedQConnection ? Do you want to wait the worker thread till main thread finishes the job ?

              R_IrudezuR Offline
              R_IrudezuR Offline
              R_Irudezu
              wrote on last edited by
              #6

              @dheerendra No, i want to work them to asynchronously, at the same time. But like i said, without

              Qt::BlockingQueuedConnection
              

              inside if the onLocationChanged function is not working.

              Keizoku wa chikaranari.

              jsulmJ J.HilkJ 2 Replies Last reply
              0
              • dheerendraD Offline
                dheerendraD Offline
                dheerendra
                Qt Champions 2022
                wrote on last edited by
                #7

                Surprise. If it is working for Qt::BlockedQueuedConnection it should work without that also. if you don't pass 5th param, slot is never called ? or is it called later ?

                Dheerendra
                @Community Service
                Certified Qt Specialist
                http://www.pthinks.com

                1 Reply Last reply
                0
                • R_IrudezuR R_Irudezu

                  @dheerendra No, i want to work them to asynchronously, at the same time. But like i said, without

                  Qt::BlockingQueuedConnection
                  

                  inside if the onLocationChanged function is not working.

                  jsulmJ Offline
                  jsulmJ Offline
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @R_Irudezu said in Widgets must be created in the GUI thread:

                  Qt::BlockingQueuedConnection

                  You should use Qt::QueuedConnection
                  If it does not work then it means that you're blocking the event loop somewhere.

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  2
                  • R_IrudezuR R_Irudezu

                    @dheerendra No, i want to work them to asynchronously, at the same time. But like i said, without

                    Qt::BlockingQueuedConnection
                    

                    inside if the onLocationChanged function is not working.

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

                    @R_Irudezu

                    show us more of your workerthread.h: especially your overwritten run function.
                    You decided to go with deriving QThread instead of the worker approach, so you have to manage the thread-event loop yourself. There's a lot that one can do wrong in that place

                    As a reminder, I would really suggest going with the worker object and moveToThread:
                    https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/


                    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.

                    R_IrudezuR 1 Reply Last reply
                    2
                    • J.HilkJ J.Hilk

                      @R_Irudezu

                      show us more of your workerthread.h: especially your overwritten run function.
                      You decided to go with deriving QThread instead of the worker approach, so you have to manage the thread-event loop yourself. There's a lot that one can do wrong in that place

                      As a reminder, I would really suggest going with the worker object and moveToThread:
                      https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

                      R_IrudezuR Offline
                      R_IrudezuR Offline
                      R_Irudezu
                      wrote on last edited by R_Irudezu
                      #10

                      @J.Hilk nothing more is in workerthread.h but i'm gonna write here workerthread.cpp with more details.

                      workerthread.cpp:

                      #include "workerthread.h"
                      #include "mainwindow.h"
                      
                      #include <QtCore>
                      #include <QDebug>
                      
                      void callBack(LibraryConnect *connection, LıbraryStruct *drawStruct, uint32_t drawCount)
                      {
                          // dataType struct is keeps some specifications about locations ()
                          if (count> 0)
                          {
                              for (uint32_t i = 0; i < drawCount; i++)
                              {
                                  int x = drawStruct[i].Location.x;
                                  int y = drawStruct[i].Location.y;
                                  int w = drawStruct[i].Location.w;
                                  int h = drawStruct[i].Location.h;
                      
                                  emit  w1->sendFaceLocationsFromThread(x, y, w, h);
                              }
                          }
                      }
                      

                      that's all, in the constructor i'm just initializing some some library functions with using

                      GetProcAddress 
                      //and
                      MAKEINTRESOURCEA(ordinal_number)
                      
                      int connection_return = LibraryConnect ("192.168... ip", port_number);
                      //if returns 0, callBack function starts running 
                      

                      Keizoku wa chikaranari.

                      J.HilkJ 1 Reply Last reply
                      0
                      • R_IrudezuR Offline
                        R_IrudezuR Offline
                        R_Irudezu
                        wrote on last edited by
                        #11

                        @jsulm @dheerendra i upload the callback function above

                        Keizoku wa chikaranari.

                        1 Reply Last reply
                        0
                        • dheerendraD Offline
                          dheerendraD Offline
                          dheerendra
                          Qt Champions 2022
                          wrote on last edited by
                          #12

                          I lost the context of issue. If I remember the issue, if you don’t pass 5th parameter slot is not called. This the issue you have now. I suspect slot may be executed fast and u r not able to see change. Just place few debugs in slot and check whether debugs are coming. Comment everything else in slot.

                          Dheerendra
                          @Community Service
                          Certified Qt Specialist
                          http://www.pthinks.com

                          1 Reply Last reply
                          0
                          • R_IrudezuR R_Irudezu

                            @J.Hilk nothing more is in workerthread.h but i'm gonna write here workerthread.cpp with more details.

                            workerthread.cpp:

                            #include "workerthread.h"
                            #include "mainwindow.h"
                            
                            #include <QtCore>
                            #include <QDebug>
                            
                            void callBack(LibraryConnect *connection, LıbraryStruct *drawStruct, uint32_t drawCount)
                            {
                                // dataType struct is keeps some specifications about locations ()
                                if (count> 0)
                                {
                                    for (uint32_t i = 0; i < drawCount; i++)
                                    {
                                        int x = drawStruct[i].Location.x;
                                        int y = drawStruct[i].Location.y;
                                        int w = drawStruct[i].Location.w;
                                        int h = drawStruct[i].Location.h;
                            
                                        emit  w1->sendFaceLocationsFromThread(x, y, w, h);
                                    }
                                }
                            }
                            

                            that's all, in the constructor i'm just initializing some some library functions with using

                            GetProcAddress 
                            //and
                            MAKEINTRESOURCEA(ordinal_number)
                            
                            int connection_return = LibraryConnect ("192.168... ip", port_number);
                            //if returns 0, callBack function starts running 
                            
                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #13

                            @R_Irudezu
                            I totaly forgot to answer, I'm sorry.

                            So let me clear something up.

                            If you pass a connect Direct Connection the slot is executed in the emitter's thread, which is not necessarily the receiver's thread.

                            Blocking Queued Connection the slot is invoked as for the Queued Connection, except the current thread blocks until the slot returns. But using this type to connect objects in the same thread will cause deadlock. So you're doing some kind of threading I guess.

                            Usually, if you make a class that has QThread as base class, you have to overwrite run. run() is the starting point of the thread. After calling start(), the newly created thread calls this function. And only stuff created inside run will actually live in the new thread. However you're calling start and your callback function is part of the new QThread class, so that should work also.

                            For your case, I would maybe suggest looking intp QtConcurrent, it's a high lvl threading api and accepts function pointers as parameters. Seems suited for your case.


                            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
                            1
                            • R_IrudezuR Offline
                              R_IrudezuR Offline
                              R_Irudezu
                              wrote on last edited by
                              #14

                              Thank you, I will check it out.

                              @dheerendra @J-Hilk

                              Keizoku wa chikaranari.

                              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