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. How to get Data from GUI into a thread?
Forum Updated to NodeBB v4.3 + New Features

How to get Data from GUI into a thread?

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 5 Posters 908 Views 2 Watching
  • 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
    mullman123
    wrote on 19 Jun 2023, 14:11 last edited by
    #1

    Hello,

    i am trying to get some GUI data which is entered in QtextEdits, etc... into a thread. I run the thread with thread_calculateutilization.start();
    And it works perfectly fine....
    Now i am asking what is the best way to exchange some data between my mainwindow and the thread? When i use slots and connects then i noticed that it can make some trouble because obviously the run() function is called before the emit signal reaches the thread. I also tried to hand over a struct with connects but it did not work...
    Now with this code i initialize my struct and set up the connects for my thread in:

    mainwindow.cpp

    
        // Create Struct for entered UI Data
        UIData = {
    
            // Lineconfig
            "Select type",
            1,
            "0",
            "0",
            "0",
            1,
    
            // Shuttleconfig
            "Select type",
            "0",
            "0",
    
            // Loaderconfig
            "Select type",
            "0",
            "0",
            "0",
    
            // Unloaderconfig
            0,
            "Select type",
            "0",
            "0",
            "0",
    
            // Parameters
            "0",
            "0",
    
            "0",
            "0",
            "0",
            "0",
    
            "0"
        };
    
        // set connects for our calculation thread
        connect(&thread_calculateutilization, &QThread::started, &utilizationcalculator, &calculationutilization::run);
        connect(&utilizationcalculator, &calculationutilization::calculationdone, this, &MainWindow::UtilizationTimeCalculated);
        connect(this, &MainWindow::started_calculationthread, &utilizationcalculator, &calculationutilization::recvdata);
    
        utilizationcalculator.moveToThread(&thread_calculateutilization);
    

    When i click the specific button i emit a signal to the thread with my struct as a handover parameter and start the thread afterwards.

    //Button actions
    void MainWindow::on_pushButton_CalculateTime_clicked()
    {
        emit started_calculationthread(UIData);
        thread_calculateutilization.start();
    }
    

    I Have defined my thread, struct and signal like this in the:

    maindow.h

    private:
        Ui::MainWindow *ui;
        QThread thread_calculateutilization;
        calculationutilization utilizationcalculator;
    
        struct DataComingFromUI
        {
            // Lineconfig
            QString Linetype;
            int MachineLines;
            QString MachinesLine1;
            QString MachinesLine2;
            QString SpacingBetweenMachines;
            bool LoadedStartupState;
    
            // Shuttleconfig
            QString Shuttletype;
            QString NumberStationsShuttle;
            QString NumberShelvesShuttle;
    
            // Loaderconfig
            QString Loadertype;
            QString NumberStationsLoader;
            QString NumberShelvesLoader;
            QString NumberLoaders;
    
            // Unloaderconfig
            bool UnloaderActive;
            QString Unloadertype;
            QString NumberStationsUnloader;
            QString NumberShelvesUnloader;
            QString NumberUnloaders;
    
            // Parameters
            QString LoadingTimeMachines;
            QString UnloadingTimeMachines;
    
            QString ShuttleVelocity;
            QString ShuttleAcceleration;
            QString ShuttleHomingTime;
            QString ShuttleLevelingTime;
    
            QString LoaderVelocity;
    
        };
        DataComingFromUI UIData;
    
    signals:
        void started_calculationthread(const DataComingFromUI& data);
    

    Now in the class for my thread i have defined things like this:

    calculationutilization.h

    #ifndef CALCULATIONUTILIZATION_H
    #define CALCULATIONUTILIZATION_H
    
    #include <QObject>
    
    class calculationutilization : public QObject
    {
        Q_OBJECT
    public:
        explicit calculationutilization(QObject *parent = nullptr);
    
    signals:
        void calculationdone(int time);
    
    private:
        int m_MachinesLine1 = 0;
        int m_MachinesLine2 = 0;
        struct DataComingFromUI
        {
            // Lineconfig
            QString Linetype;
            int MachineLines;
            QString MachinesLine1;
            QString MachinesLine2;
            QString SpacingBetweenMachines;
            bool LoadedStartupState;
    
            // Shuttleconfig
            QString Shuttletype;
            QString NumberStationsShuttle;
            QString NumberShelvesShuttle;
    
            // Loaderconfig
            QString Loadertype;
            QString NumberStationsLoader;
            QString NumberShelvesLoader;
            QString NumberLoaders;
    
            // Unloaderconfig
            bool UnloaderActive;
            QString Unloadertype;
            QString NumberStationsUnloader;
            QString NumberShelvesUnloader;
            QString NumberUnloaders;
    
            // Parameters
            QString LoadingTimeMachines;
            QString UnloadingTimeMachines;
    
            QString ShuttleVelocity;
            QString ShuttleAcceleration;
            QString ShuttleHomingTime;
            QString ShuttleLevelingTime;
    
            QString LoaderVelocity;
        };
    
    public slots:
        void run();
        void recvdata(const DataComingFromUI& data);
    
    
    };
    
    #endif // CALCULATIONUTILIZATION_H
    

    My question now is: what is the best way to transfer the data in my struct from my mainwindow/ui with a button click to the thread and then start the thread?

    Best Regards

    Christian EhrlicherC 1 Reply Last reply 19 Jun 2023, 15:06
    0
    • M mullman123
      19 Jun 2023, 14:11

      Hello,

      i am trying to get some GUI data which is entered in QtextEdits, etc... into a thread. I run the thread with thread_calculateutilization.start();
      And it works perfectly fine....
      Now i am asking what is the best way to exchange some data between my mainwindow and the thread? When i use slots and connects then i noticed that it can make some trouble because obviously the run() function is called before the emit signal reaches the thread. I also tried to hand over a struct with connects but it did not work...
      Now with this code i initialize my struct and set up the connects for my thread in:

      mainwindow.cpp

      
          // Create Struct for entered UI Data
          UIData = {
      
              // Lineconfig
              "Select type",
              1,
              "0",
              "0",
              "0",
              1,
      
              // Shuttleconfig
              "Select type",
              "0",
              "0",
      
              // Loaderconfig
              "Select type",
              "0",
              "0",
              "0",
      
              // Unloaderconfig
              0,
              "Select type",
              "0",
              "0",
              "0",
      
              // Parameters
              "0",
              "0",
      
              "0",
              "0",
              "0",
              "0",
      
              "0"
          };
      
          // set connects for our calculation thread
          connect(&thread_calculateutilization, &QThread::started, &utilizationcalculator, &calculationutilization::run);
          connect(&utilizationcalculator, &calculationutilization::calculationdone, this, &MainWindow::UtilizationTimeCalculated);
          connect(this, &MainWindow::started_calculationthread, &utilizationcalculator, &calculationutilization::recvdata);
      
          utilizationcalculator.moveToThread(&thread_calculateutilization);
      

      When i click the specific button i emit a signal to the thread with my struct as a handover parameter and start the thread afterwards.

      //Button actions
      void MainWindow::on_pushButton_CalculateTime_clicked()
      {
          emit started_calculationthread(UIData);
          thread_calculateutilization.start();
      }
      

      I Have defined my thread, struct and signal like this in the:

      maindow.h

      private:
          Ui::MainWindow *ui;
          QThread thread_calculateutilization;
          calculationutilization utilizationcalculator;
      
          struct DataComingFromUI
          {
              // Lineconfig
              QString Linetype;
              int MachineLines;
              QString MachinesLine1;
              QString MachinesLine2;
              QString SpacingBetweenMachines;
              bool LoadedStartupState;
      
              // Shuttleconfig
              QString Shuttletype;
              QString NumberStationsShuttle;
              QString NumberShelvesShuttle;
      
              // Loaderconfig
              QString Loadertype;
              QString NumberStationsLoader;
              QString NumberShelvesLoader;
              QString NumberLoaders;
      
              // Unloaderconfig
              bool UnloaderActive;
              QString Unloadertype;
              QString NumberStationsUnloader;
              QString NumberShelvesUnloader;
              QString NumberUnloaders;
      
              // Parameters
              QString LoadingTimeMachines;
              QString UnloadingTimeMachines;
      
              QString ShuttleVelocity;
              QString ShuttleAcceleration;
              QString ShuttleHomingTime;
              QString ShuttleLevelingTime;
      
              QString LoaderVelocity;
      
          };
          DataComingFromUI UIData;
      
      signals:
          void started_calculationthread(const DataComingFromUI& data);
      

      Now in the class for my thread i have defined things like this:

      calculationutilization.h

      #ifndef CALCULATIONUTILIZATION_H
      #define CALCULATIONUTILIZATION_H
      
      #include <QObject>
      
      class calculationutilization : public QObject
      {
          Q_OBJECT
      public:
          explicit calculationutilization(QObject *parent = nullptr);
      
      signals:
          void calculationdone(int time);
      
      private:
          int m_MachinesLine1 = 0;
          int m_MachinesLine2 = 0;
          struct DataComingFromUI
          {
              // Lineconfig
              QString Linetype;
              int MachineLines;
              QString MachinesLine1;
              QString MachinesLine2;
              QString SpacingBetweenMachines;
              bool LoadedStartupState;
      
              // Shuttleconfig
              QString Shuttletype;
              QString NumberStationsShuttle;
              QString NumberShelvesShuttle;
      
              // Loaderconfig
              QString Loadertype;
              QString NumberStationsLoader;
              QString NumberShelvesLoader;
              QString NumberLoaders;
      
              // Unloaderconfig
              bool UnloaderActive;
              QString Unloadertype;
              QString NumberStationsUnloader;
              QString NumberShelvesUnloader;
              QString NumberUnloaders;
      
              // Parameters
              QString LoadingTimeMachines;
              QString UnloadingTimeMachines;
      
              QString ShuttleVelocity;
              QString ShuttleAcceleration;
              QString ShuttleHomingTime;
              QString ShuttleLevelingTime;
      
              QString LoaderVelocity;
          };
      
      public slots:
          void run();
          void recvdata(const DataComingFromUI& data);
      
      
      };
      
      #endif // CALCULATIONUTILIZATION_H
      

      My question now is: what is the best way to transfer the data in my struct from my mainwindow/ui with a button click to the thread and then start the thread?

      Best Regards

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 19 Jun 2023, 15:06 last edited by
      #2

      emit the result within your calculationdone() signal.

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

      M 1 Reply Last reply 20 Jun 2023, 06:06
      2
      • Christian EhrlicherC Christian Ehrlicher
        19 Jun 2023, 15:06

        emit the result within your calculationdone() signal.

        M Offline
        M Offline
        mullman123
        wrote on 20 Jun 2023, 06:06 last edited by
        #3

        @Christian-Ehrlicher
        Yeah i know how to do that and it works.
        But that is the other way around (from thread to gui).
        Now i want to get all the GUI Data into my thread before working with the thread. (basically the struct DataComingFromUI in mainwindow.h) i declared it as private. But i dont get it to work as a handover parameter...

        JonBJ 1 Reply Last reply 20 Jun 2023, 06:25
        0
        • M mullman123
          20 Jun 2023, 06:06

          @Christian-Ehrlicher
          Yeah i know how to do that and it works.
          But that is the other way around (from thread to gui).
          Now i want to get all the GUI Data into my thread before working with the thread. (basically the struct DataComingFromUI in mainwindow.h) i declared it as private. But i dont get it to work as a handover parameter...

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on 20 Jun 2023, 06:25 last edited by
          #4

          @mullman123
          Exactly in the opposite direction --- send data from UI thread to secondary thread via signals, just as you would the other way round. Note that you do not pass data in a connect() call, you only specify what the type of the data will be. We do not know what

          When i use slots and connects then i noticed that it can make some trouble because obviously the run() function is called before the emit signal reaches the thread

          means.

          If you need help produce a minimal, compilable example of what you try --- you don't need hundreds of QStrings to illustrate a problem. Whether you pass a whole struct or a single int the principle is the same.

          M 1 Reply Last reply 20 Jun 2023, 06:42
          2
          • JonBJ JonB
            20 Jun 2023, 06:25

            @mullman123
            Exactly in the opposite direction --- send data from UI thread to secondary thread via signals, just as you would the other way round. Note that you do not pass data in a connect() call, you only specify what the type of the data will be. We do not know what

            When i use slots and connects then i noticed that it can make some trouble because obviously the run() function is called before the emit signal reaches the thread

            means.

            If you need help produce a minimal, compilable example of what you try --- you don't need hundreds of QStrings to illustrate a problem. Whether you pass a whole struct or a single int the principle is the same.

            M Offline
            M Offline
            mullman123
            wrote on 20 Jun 2023, 06:42 last edited by mullman123
            #5

            @JonB
            Yeah i tried it with a struct but there is an issue with compiling it. Even though it does not have any complains for passing it to the functions. Is there anything wrong with my connect? Or do i need to do anything specific with my struct?

            ce5a1900-f3c0-4725-bbd4-0c34e3e3a3ed-grafik.png

            J.HilkJ 1 Reply Last reply 20 Jun 2023, 06:46
            0
            • M mullman123
              20 Jun 2023, 06:42

              @JonB
              Yeah i tried it with a struct but there is an issue with compiling it. Even though it does not have any complains for passing it to the functions. Is there anything wrong with my connect? Or do i need to do anything specific with my struct?

              ce5a1900-f3c0-4725-bbd4-0c34e3e3a3ed-grafik.png

              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on 20 Jun 2023, 06:46 last edited by
              #6

              @mullman123 no, your code is wrong.

              struct DataComingFromUI is defined twice!

              once in calculationutilization and once in maindow

              also you might get away without it, but I would recommend adding a copy operator to your struct as well


              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.

              M 1 Reply Last reply 20 Jun 2023, 07:32
              1
              • J.HilkJ J.Hilk
                20 Jun 2023, 06:46

                @mullman123 no, your code is wrong.

                struct DataComingFromUI is defined twice!

                once in calculationutilization and once in maindow

                also you might get away without it, but I would recommend adding a copy operator to your struct as well

                M Offline
                M Offline
                mullman123
                wrote on 20 Jun 2023, 07:32 last edited by
                #7

                @J-Hilk
                Now i got it working. Thanks so far!
                The next problem would be how to get my Thread to wait until the data is received from the emit before finishing?
                Or is there a better way to pass over my struct to the run process of my thread?
                After calling my emit to the thread it does not arrive because i think the thread finishes before it. I am basically calling the recvdata() slot.

                My Button action in MainWindow.cpp:

                //Button actions
                void MainWindow::on_pushButton_CalculateTime_clicked()
                {
                    setGUIDataCalculateThread();
                    emit started_calculationthread(UIData);
                    thread_calculateutilization.start();
                }
                

                My thread/connect in calculationutilization.cpp

                void calculationutilization::run()
                {
                
                }
                
                void calculationutilization::recvdata(DataComingFromUI& data)
                {
                    data.Linetype = "Hello";
                }
                
                J.HilkJ 1 Reply Last reply 20 Jun 2023, 07:38
                0
                • S Offline
                  S Offline
                  SimonSchroeder
                  wrote on 20 Jun 2023, 07:37 last edited by
                  #8

                  If I understood correctly you have overwritten the run() method of your thread. Then, signal slot connections won't work because no event loop is running inside your thread. It is also not good practice anymore to override the run() method. Instead, just start your thread and the default implementation of run() will start an event loop. You then place a worker object inside that thread with a slot that would be connected to started_calculationthread(UIData). Your slot will get the data and your can use it to do your actual work.

                  A slight shortcut is to use

                  QThread::create([](const DataComingFromUI &data){ /* do the work */ }, UIData);
                  

                  Or just capture UIData with the lambda. In addition, you need to make sure to delete the thread object created by QThread::create by connecting to its finished signal.

                  1 Reply Last reply
                  0
                  • M mullman123
                    20 Jun 2023, 07:32

                    @J-Hilk
                    Now i got it working. Thanks so far!
                    The next problem would be how to get my Thread to wait until the data is received from the emit before finishing?
                    Or is there a better way to pass over my struct to the run process of my thread?
                    After calling my emit to the thread it does not arrive because i think the thread finishes before it. I am basically calling the recvdata() slot.

                    My Button action in MainWindow.cpp:

                    //Button actions
                    void MainWindow::on_pushButton_CalculateTime_clicked()
                    {
                        setGUIDataCalculateThread();
                        emit started_calculationthread(UIData);
                        thread_calculateutilization.start();
                    }
                    

                    My thread/connect in calculationutilization.cpp

                    void calculationutilization::run()
                    {
                    
                    }
                    
                    void calculationutilization::recvdata(DataComingFromUI& data)
                    {
                        data.Linetype = "Hello";
                    }
                    
                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on 20 Jun 2023, 07:38 last edited by
                    #9

                    @mullman123 said in How to get Data from GUI into a thread?:

                    void calculationutilization::run()
                    {

                    }

                    seeing this makes me doubt your thread is actually doing thread things.

                    What exactly is your set up, what method of "thread" are you using

                    Can you elaborate more, what exactly do you want to archive?
                    Is it simply some (long taking) operation on your data in the struct ?

                    If so, then there are easier methods than sub classing QThread, what you seem to have done here. In fact subclassing Thread is very, very early the way to go


                    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.

                    M 1 Reply Last reply 20 Jun 2023, 07:47
                    0
                    • J.HilkJ J.Hilk
                      20 Jun 2023, 07:38

                      @mullman123 said in How to get Data from GUI into a thread?:

                      void calculationutilization::run()
                      {

                      }

                      seeing this makes me doubt your thread is actually doing thread things.

                      What exactly is your set up, what method of "thread" are you using

                      Can you elaborate more, what exactly do you want to archive?
                      Is it simply some (long taking) operation on your data in the struct ?

                      If so, then there are easier methods than sub classing QThread, what you seem to have done here. In fact subclassing Thread is very, very early the way to go

                      M Offline
                      M Offline
                      mullman123
                      wrote on 20 Jun 2023, 07:47 last edited by
                      #10

                      @J-Hilk
                      What i want to do is use the data from the struct to calculate a simulation of many automated processes.
                      The Data from the GUI basically sets the parameters and config for the calculation.
                      Since it can happen that the calculation might take some time i defined it as a thread.

                      The function is not yet implemented because i struggled with handing over the data from GUI.
                      But the thread will do kinda lengthy calculations.

                      J.HilkJ 1 Reply Last reply 20 Jun 2023, 07:56
                      0
                      • M mullman123
                        20 Jun 2023, 07:47

                        @J-Hilk
                        What i want to do is use the data from the struct to calculate a simulation of many automated processes.
                        The Data from the GUI basically sets the parameters and config for the calculation.
                        Since it can happen that the calculation might take some time i defined it as a thread.

                        The function is not yet implemented because i struggled with handing over the data from GUI.
                        But the thread will do kinda lengthy calculations.

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on 20 Jun 2023, 07:56 last edited by
                        #11

                        @mullman123

                        alright, so not a fire and forget function, but you want to access the results.

                        I would suggest the worker thread approach than.

                        Make your calculating/processing class. make it so that your interface to that class is slots (passing data to the class) and signals (passing data from the class away) only.

                        When that is working, you can (literally) move it to its own thread in like 10 lines of code

                        I have this project, that covers all common ways of "threading "in qt:
                        https://github.com/DeiVadder/QtThreadExample

                        take a closer look at the "workerObject" project
                        https://github.com/DeiVadder/QtThreadExample/tree/master/projects/WorkerObject


                        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.

                        M 1 Reply Last reply 20 Jun 2023, 08:02
                        1
                        • J.HilkJ J.Hilk
                          20 Jun 2023, 07:56

                          @mullman123

                          alright, so not a fire and forget function, but you want to access the results.

                          I would suggest the worker thread approach than.

                          Make your calculating/processing class. make it so that your interface to that class is slots (passing data to the class) and signals (passing data from the class away) only.

                          When that is working, you can (literally) move it to its own thread in like 10 lines of code

                          I have this project, that covers all common ways of "threading "in qt:
                          https://github.com/DeiVadder/QtThreadExample

                          take a closer look at the "workerObject" project
                          https://github.com/DeiVadder/QtThreadExample/tree/master/projects/WorkerObject

                          M Offline
                          M Offline
                          mullman123
                          wrote on 20 Jun 2023, 08:02 last edited by
                          #12

                          @J-Hilk
                          Thanks for your detailed information.
                          I will try my luck and give some info what i achieved.

                          Thanks to everybody so far for the fast help.

                          1 Reply Last reply
                          1
                          • S Offline
                            S Offline
                            SimonSchroeder
                            wrote on 21 Jun 2023, 07:02 last edited by
                            #13

                            I have stumbled on the same kind of problems over and over again. You can find a simple wrapper for this kind of multithreading on GitHub: https://github.com/SimonSchroeder/QtThreadHelper

                            In your specific case you could just write it like this:

                            workerThread([](const DataComingFromUI & data){ ... }, UIData);
                            

                            No need to write a full class or something. It is basically an extension of QThread::create which will avoid memory leaks. The only thing to consider is that a new thread is created whenever you want to execute this. With enough work inside the function the overhead of creating a thread is negligible. Because the GUI will not freeze you have to be careful that this cannot be started several times at once such that not too many threads are running at the same time.

                            BTW, Qt also has QtConcurrent::run(). This uses a thread pool in the background (so, no oversubscribing of the CPU cores) and it makes it quite easy to run a function inside a thread as well.

                            1 Reply Last reply
                            0

                            1/13

                            19 Jun 2023, 14:11

                            • Login

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