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. Creating widgets in "another" thread...

Creating widgets in "another" thread...

Scheduled Pinned Locked Moved Unsolved General and Desktop
qthreadqeventloopqwidgetparent
19 Posts 7 Posters 11.1k 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.
  • D Dariusz
    28 Nov 2019, 05:06

    Hey

    Before all I know I cant make widget in another thread, or at least make it and parent to widget in different thread... thus... how can I call main thread from my sub thread, create widgets and then return to continue my function?

    say

    stuff::doStuff(){ // called from thread.
         processData();
         if(!widgetInitialized()){
              mainThread::takeControl::createWidgets();
         } //// wait for it to finish.
         populateWidgetsWithData();
    }
    

    Any hints?

    TIA

    J Offline
    J Offline
    jsulm
    Lifetime Qt Champion
    wrote on 28 Nov 2019, 05:16 last edited by
    #2

    @Dariusz said in Creating widgets in "another" thread...:

    how can I call main thread from my sub thread

    Using signals/slots.
    But you should not create the widgets in another thread than main thread!
    Why do you want to do so? I don't see the point. This another thread can do what it is supposed to do and then notify the main thread via signal and main thread then can create the widget.

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

    1 Reply Last reply
    1
    • D Offline
      D Offline
      Dariusz
      wrote on 28 Nov 2019, 05:22 last edited by
      #3

      Its the current app design I'm afraid.

      When app starts it creates all attribute widget containers, but cant initialize them untill an actuall node with data is created. Now when user click on node (in treeView) then I emit signal to my worker thread to handle selection, this has to process data / display it. At this point the attribute widget sees data for 1st time and has to finish initialization... Its a bit.. "backward" I'm thinking of remaking it.

      Atm I did

                          QMetaObject::invokeMethod(qApp, [&, sType, node, name = node->getIcName()]() {initializeWidget();populateWidget();},Qt::QueuedConnection);
      

      To push it back to main thread. Even tho its still "slow" to update/display data. In past I did everything in main thread, but every time user selected an item, it was taking 1-2 + seconds to populate the widget with data... Killing interactivity. Tricky...

      Its frustrating that widget creation happens in main thread the same that user uses to control widgets... feels like entire widget system should live in another thread and any interaction with it should be done via signals/slots. Then user could select/deselect items and see updates after worker thread process them ? Not sure... maybe I'm thinking wrong :- (

      J 1 Reply Last reply 28 Nov 2019, 05:43
      0
      • D Dariusz
        28 Nov 2019, 05:22

        Its the current app design I'm afraid.

        When app starts it creates all attribute widget containers, but cant initialize them untill an actuall node with data is created. Now when user click on node (in treeView) then I emit signal to my worker thread to handle selection, this has to process data / display it. At this point the attribute widget sees data for 1st time and has to finish initialization... Its a bit.. "backward" I'm thinking of remaking it.

        Atm I did

                            QMetaObject::invokeMethod(qApp, [&, sType, node, name = node->getIcName()]() {initializeWidget();populateWidget();},Qt::QueuedConnection);
        

        To push it back to main thread. Even tho its still "slow" to update/display data. In past I did everything in main thread, but every time user selected an item, it was taking 1-2 + seconds to populate the widget with data... Killing interactivity. Tricky...

        Its frustrating that widget creation happens in main thread the same that user uses to control widgets... feels like entire widget system should live in another thread and any interaction with it should be done via signals/slots. Then user could select/deselect items and see updates after worker thread process them ? Not sure... maybe I'm thinking wrong :- (

        J Offline
        J Offline
        jsulm
        Lifetime Qt Champion
        wrote on 28 Nov 2019, 05:43 last edited by
        #4

        @Dariusz I don't understand why initialisation of a widget can take so long if data is already available.
        Usually it works like this: worker thread does all needed processing and emit a signal with all needed data when finished. The UI thread gets that data in the slot and updates the UI. So, does all your processing happen in the second thread and the UI thread only updates the UI? If so, how can it be so slow? How do you update the UI?

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

        D 1 Reply Last reply 28 Nov 2019, 16:36
        2
        • J jsulm
          28 Nov 2019, 05:43

          @Dariusz I don't understand why initialisation of a widget can take so long if data is already available.
          Usually it works like this: worker thread does all needed processing and emit a signal with all needed data when finished. The UI thread gets that data in the slot and updates the UI. So, does all your processing happen in the second thread and the UI thread only updates the UI? If so, how can it be so slow? How do you update the UI?

          D Offline
          D Offline
          Dariusz
          wrote on 28 Nov 2019, 16:36 last edited by
          #5

          @jsulm Neither do I, its fairly complex system. I'm slowly going over it to see how I can rewrite it. However, in meantime is this action somehow possible? >

          stuff::doStuff(){ // called from thread.
               processData();
               if(!widgetInitialized()){
                    mainThread::takeControl::createWidgets();
               } //// wait for it to finish.
               populateWidgetsWithData();
          }
          ```'
          ?
          1 Reply Last reply
          0
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 28 Nov 2019, 17:14 last edited by
            #6

            Hi,

            As already said, no. Don't manipulate widgets from a secondary thread.

            You can get inspiration from QFileSystemModel. The data handling is threaded and the model notifies the view when new things have arrived.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            D 1 Reply Last reply 28 Nov 2019, 17:19
            1
            • S SGaist
              28 Nov 2019, 17:14

              Hi,

              As already said, no. Don't manipulate widgets from a secondary thread.

              You can get inspiration from QFileSystemModel. The data handling is threaded and the model notifies the view when new things have arrived.

              D Offline
              D Offline
              Dariusz
              wrote on 28 Nov 2019, 17:19 last edited by
              #7

              @SGaist I'm trying to go back to main thread to create widget and then return to my worker thread to finish processing data... Not do updates on widgets from my thread. I take there is no way to do this then ? I know we can do QFuture if we want to wait on some worker threads to do their work, but can worker thread send work to main thread and wait for that to finish ?

              J 1 Reply Last reply 28 Nov 2019, 18:17
              0
              • D Dariusz
                28 Nov 2019, 17:19

                @SGaist I'm trying to go back to main thread to create widget and then return to my worker thread to finish processing data... Not do updates on widgets from my thread. I take there is no way to do this then ? I know we can do QFuture if we want to wait on some worker threads to do their work, but can worker thread send work to main thread and wait for that to finish ?

                J Offline
                J Offline
                JonB
                wrote on 28 Nov 2019, 18:17 last edited by
                #8

                @Dariusz
                It's the "waiting" in the middle of code thread for the UI thread that is the issue. Can you at least split your processing thread so that the part after creating a widget is separated off from the part before. Then you can use signals & slots to communicate between the threads.

                D 1 Reply Last reply 29 Nov 2019, 06:40
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 28 Nov 2019, 21:32 last edited by
                  #9

                  Then use signals and slots with Qt::BlockingQueuedConnection as the connection type.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  1
                  • J JonB
                    28 Nov 2019, 18:17

                    @Dariusz
                    It's the "waiting" in the middle of code thread for the UI thread that is the issue. Can you at least split your processing thread so that the part after creating a widget is separated off from the part before. Then you can use signals & slots to communicate between the threads.

                    D Offline
                    D Offline
                    Dariusz
                    wrote on 29 Nov 2019, 06:40 last edited by Dariusz
                    #10

                    @JonB Hey

                    Ok so I decided to go over the code and rebuild the system....

                    I have now 4 operation.

                    1. Initialize widgets on app startup - fine - runs in main loop at app start.
                    2. Pre-populate widgets with data = Each widget I have is a subclass of Qt widget, it contains a "cached" member which holds "new" value so that finding data/preparring data is stored there. - runs in a worker thread
                    3. Populate all widgets with data = essentially use cached value and set as widgetData. = run in the Main thread. / these widgets may be hidden/visible at this time
                    4. Display proper widgets, as they will depend upon selection. - here is where they become visible = done in Main Thread.

                    With this "new" system... As far as I can tell, point 1 and 2 are fine. Point 3-4 can be slow. I can have a number of data sets, say 20 QWidgets ech containing 50-100 QlineEdits + so there might be 500+ widgets that needs updating at a time.

                    When I click now, its fairly fast. A tiny lag but nothing as big as last time. I have some ideas how I could optimize it further, mainly fire updates depending on selection, whenever its single click or multi selection(ctrl/shift).

                    Other than that no idea how to optimize it further. At this points it seems to be just Qt related as all the point 3/4 is doing is updating widgets width data & displaying them.


                    @SGaist said in Creating widgets in "another" thread...:

                    Then use signals and slots with Qt::BlockingQueuedConnection as the connection type.

                    Woa this takes control over main thread & return afterwards?! Sweeeeeet! Will try it, I have some ideas now :D

                    J.HilkJ J 2 Replies Last reply 29 Nov 2019, 06:49
                    0
                    • D Dariusz
                      29 Nov 2019, 06:40

                      @JonB Hey

                      Ok so I decided to go over the code and rebuild the system....

                      I have now 4 operation.

                      1. Initialize widgets on app startup - fine - runs in main loop at app start.
                      2. Pre-populate widgets with data = Each widget I have is a subclass of Qt widget, it contains a "cached" member which holds "new" value so that finding data/preparring data is stored there. - runs in a worker thread
                      3. Populate all widgets with data = essentially use cached value and set as widgetData. = run in the Main thread. / these widgets may be hidden/visible at this time
                      4. Display proper widgets, as they will depend upon selection. - here is where they become visible = done in Main Thread.

                      With this "new" system... As far as I can tell, point 1 and 2 are fine. Point 3-4 can be slow. I can have a number of data sets, say 20 QWidgets ech containing 50-100 QlineEdits + so there might be 500+ widgets that needs updating at a time.

                      When I click now, its fairly fast. A tiny lag but nothing as big as last time. I have some ideas how I could optimize it further, mainly fire updates depending on selection, whenever its single click or multi selection(ctrl/shift).

                      Other than that no idea how to optimize it further. At this points it seems to be just Qt related as all the point 3/4 is doing is updating widgets width data & displaying them.


                      @SGaist said in Creating widgets in "another" thread...:

                      Then use signals and slots with Qt::BlockingQueuedConnection as the connection type.

                      Woa this takes control over main thread & return afterwards?! Sweeeeeet! Will try it, I have some ideas now :D

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on 29 Nov 2019, 06:49 last edited by
                      #11

                      @Dariusz have you tried this in release mode as well ? 500 widgets is a number that should be easily handled.


                      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.

                      D 1 Reply Last reply 29 Nov 2019, 06:51
                      0
                      • J.HilkJ J.Hilk
                        29 Nov 2019, 06:49

                        @Dariusz have you tried this in release mode as well ? 500 widgets is a number that should be easily handled.

                        D Offline
                        D Offline
                        Dariusz
                        wrote on 29 Nov 2019, 06:51 last edited by
                        #12

                        @J-Hilk I'm developing now in Release with Debug info in Release "mode"... its a bit confusing, but as far as I can tell its the "fast" mode. In debug only mode it is a lot slower. But thats due to filtering arrays/etc/etc so I think its "normal"

                        J.HilkJ 1 Reply Last reply 29 Nov 2019, 06:54
                        0
                        • D Dariusz
                          29 Nov 2019, 06:51

                          @J-Hilk I'm developing now in Release with Debug info in Release "mode"... its a bit confusing, but as far as I can tell its the "fast" mode. In debug only mode it is a lot slower. But thats due to filtering arrays/etc/etc so I think its "normal"

                          J.HilkJ Offline
                          J.HilkJ Offline
                          J.Hilk
                          Moderators
                          wrote on 29 Nov 2019, 06:54 last edited by
                          #13

                          @Dariusz
                          you mean you call the compiler with -g -O3 ?


                          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.

                          D 1 Reply Last reply 29 Nov 2019, 06:58
                          0
                          • J.HilkJ J.Hilk
                            29 Nov 2019, 06:54

                            @Dariusz
                            you mean you call the compiler with -g -O3 ?

                            D Offline
                            D Offline
                            Dariusz
                            wrote on 29 Nov 2019, 06:58 last edited by
                            #14

                            @J-Hilk I'm not actually sure... I use cLion and one of their presets... when I did cmake print flags these were the flags:

                            CMAKE_CXX_FLAGS_RELWITHDEBINFO is /MD /Zi /O2 /Ob1 /DNDEBUG
                            
                            J.HilkJ 1 Reply Last reply 29 Nov 2019, 07:08
                            0
                            • D Dariusz
                              29 Nov 2019, 06:58

                              @J-Hilk I'm not actually sure... I use cLion and one of their presets... when I did cmake print flags these were the flags:

                              CMAKE_CXX_FLAGS_RELWITHDEBINFO is /MD /Zi /O2 /Ob1 /DNDEBUG
                              
                              J.HilkJ Offline
                              J.HilkJ Offline
                              J.Hilk
                              Moderators
                              wrote on 29 Nov 2019, 07:08 last edited by
                              #15

                              @Dariusz I'm not really fluent with make 🙈 But I think its equal to -g -O2

                              Never the less, there's still room for optimization and, removing the /DNDEBUG should increase the performance too.

                              You're currently in a fast debug build, and at the very least this should not be the production build :)


                              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
                              • S Offline
                                S Offline
                                SGaist
                                Lifetime Qt Champion
                                wrote on 29 Nov 2019, 07:32 last edited by
                                #16

                                @Dariusz said in Creating widgets in "another" thread...:

                                say 20 QWidgets ech containing 50-100 QlineEdits

                                When I see that many QLineEdit, I usually wonder if QTableView/Widget would not be a better fit to show the data.

                                Interested in AI ? www.idiap.ch
                                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                1 Reply Last reply
                                3
                                • D Dariusz
                                  29 Nov 2019, 06:40

                                  @JonB Hey

                                  Ok so I decided to go over the code and rebuild the system....

                                  I have now 4 operation.

                                  1. Initialize widgets on app startup - fine - runs in main loop at app start.
                                  2. Pre-populate widgets with data = Each widget I have is a subclass of Qt widget, it contains a "cached" member which holds "new" value so that finding data/preparring data is stored there. - runs in a worker thread
                                  3. Populate all widgets with data = essentially use cached value and set as widgetData. = run in the Main thread. / these widgets may be hidden/visible at this time
                                  4. Display proper widgets, as they will depend upon selection. - here is where they become visible = done in Main Thread.

                                  With this "new" system... As far as I can tell, point 1 and 2 are fine. Point 3-4 can be slow. I can have a number of data sets, say 20 QWidgets ech containing 50-100 QlineEdits + so there might be 500+ widgets that needs updating at a time.

                                  When I click now, its fairly fast. A tiny lag but nothing as big as last time. I have some ideas how I could optimize it further, mainly fire updates depending on selection, whenever its single click or multi selection(ctrl/shift).

                                  Other than that no idea how to optimize it further. At this points it seems to be just Qt related as all the point 3/4 is doing is updating widgets width data & displaying them.


                                  @SGaist said in Creating widgets in "another" thread...:

                                  Then use signals and slots with Qt::BlockingQueuedConnection as the connection type.

                                  Woa this takes control over main thread & return afterwards?! Sweeeeeet! Will try it, I have some ideas now :D

                                  J Offline
                                  J Offline
                                  JonB
                                  wrote on 29 Nov 2019, 08:08 last edited by JonB
                                  #17

                                  @Dariusz
                                  Sorry to make a post to just confirm what @SGaist has said above, but 20 * 75 == 1,500-odd line edits average. That's a lot! (And I pity the user who has to fill those in ;-) ) I think the suggestion that you look at the possibility of some kind of table instead needs reiterating. And @VRonin will then be here to ensure that you achieve this using item delegates instead of widgets in your table, so it will all be fast and not use up too much memory/resources ;-)

                                  1 Reply Last reply
                                  2
                                  • N Offline
                                    N Offline
                                    nintyfan
                                    wrote on 19 Nov 2023, 19:38 last edited by
                                    #18

                                    I have similar problem
                                    I am creating small wrapper around Qt. I need to process poll in another thread. QSocketNotifier is not solution - it lacks of HUP event support. So, I need to allow call new QPushButton (for example) inside another thread. Signal is not solution, because QApplication::exec could not been called yet. So, if I do not process widget creation in another loop, I will have dead lock.

                                    Christian EhrlicherC 1 Reply Last reply 20 Nov 2023, 05:39
                                    0
                                    • N nintyfan
                                      19 Nov 2023, 19:38

                                      I have similar problem
                                      I am creating small wrapper around Qt. I need to process poll in another thread. QSocketNotifier is not solution - it lacks of HUP event support. So, I need to allow call new QPushButton (for example) inside another thread. Signal is not solution, because QApplication::exec could not been called yet. So, if I do not process widget creation in another loop, I will have dead lock.

                                      Christian EhrlicherC Offline
                                      Christian EhrlicherC Offline
                                      Christian Ehrlicher
                                      Lifetime Qt Champion
                                      wrote on 20 Nov 2023, 05:39 last edited by
                                      #19

                                      @nintyfan said in Creating widgets in "another" thread...:

                                      Signal is not solution, because QApplication::exec could not been called yet

                                      So how do you show the push button then? Your design looks flawed.

                                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                      Visit the Qt Academy at https://academy.qt.io/catalog

                                      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