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. Using QThread::create() from Qt 6+
Forum Updated to NodeBB v4.3 + New Features

Using QThread::create() from Qt 6+

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 3 Posters 747 Views 1 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.
  • C Offline
    C Offline
    clhallinan
    wrote on last edited by
    #1

    I am trying to use the QThread::create() function but I can't find a way to satisfy the compiler (exposing my lack of expertise in C++17, etc.). My project is configured for C++17 and I'm using Qt 6.5.

    My member function is declared like this:

    void MainWindow::waitForVisible(void)
    
    // Here is how I'm invoking QThread::create()
    workerThread = QThread::create<void (MainWindow::*)(void), int>(&MainWindow::waitForVisible, 0);
    

    I've also tried using a typedef like this:

    typedef void (MainWindow::*MainMemberFn)(void);
    
    workerThread = QThread::create<MainMemberFn, int>(&MainWindow::waitForVisible, 0);
    

    I've spent all day reasearching (not much on Google regarding this new syntax which calls std::invoke under the covers)

    I'm getting a very long and complicated compiler error basically saying: "error: no matching function for call to 'invoke'

    I'm sure I'm just not declaring and/or calling the function properly which is a templated function that looks like this:

    template <typename Function, typename Args> QThread *QThread::create(Function &&f, Args &&... args)
    

    Any help on how to properly use this function would be much appreciated!

    Christian EhrlicherC 1 Reply Last reply
    0
    • C clhallinan

      I am trying to use the QThread::create() function but I can't find a way to satisfy the compiler (exposing my lack of expertise in C++17, etc.). My project is configured for C++17 and I'm using Qt 6.5.

      My member function is declared like this:

      void MainWindow::waitForVisible(void)
      
      // Here is how I'm invoking QThread::create()
      workerThread = QThread::create<void (MainWindow::*)(void), int>(&MainWindow::waitForVisible, 0);
      

      I've also tried using a typedef like this:

      typedef void (MainWindow::*MainMemberFn)(void);
      
      workerThread = QThread::create<MainMemberFn, int>(&MainWindow::waitForVisible, 0);
      

      I've spent all day reasearching (not much on Google regarding this new syntax which calls std::invoke under the covers)

      I'm getting a very long and complicated compiler error basically saying: "error: no matching function for call to 'invoke'

      I'm sure I'm just not declaring and/or calling the function properly which is a templated function that looks like this:

      template <typename Function, typename Args> QThread *QThread::create(Function &&f, Args &&... args)
      

      Any help on how to properly use this function would be much appreciated!

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @clhallinan said in Using QThread::create() from Qt 6+:

      QThread::create<MainMemberFn, int>(&MainWindow::waitForVisible, 0);

      Is waitForVisible static? Otherwise I don't see how this should work in any way - how should the compiler know the instance?

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

      C 1 Reply Last reply
      1
      • Christian EhrlicherC Christian Ehrlicher

        @clhallinan said in Using QThread::create() from Qt 6+:

        QThread::create<MainMemberFn, int>(&MainWindow::waitForVisible, 0);

        Is waitForVisible static? Otherwise I don't see how this should work in any way - how should the compiler know the instance?

        C Offline
        C Offline
        clhallinan
        wrote on last edited by
        #3

        @Christian-Ehrlicher

        Hi thanks for your reply. It is not a static function.
        I also tried this:

        workerThread = QThread::create<void (MainWindow::*)(void), int>(&this->waitForVisible, 0);
        

        But that generates a compiler error:

        Cannot create a non-constant pointer to member function
        

        What is proper way to invoke QThread::create() in my case?

        Christian EhrlicherC 1 Reply Last reply
        0
        • C clhallinan

          @Christian-Ehrlicher

          Hi thanks for your reply. It is not a static function.
          I also tried this:

          workerThread = QThread::create<void (MainWindow::*)(void), int>(&this->waitForVisible, 0);
          

          But that generates a compiler error:

          Cannot create a non-constant pointer to member function
          

          What is proper way to invoke QThread::create() in my case?

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by Christian Ehrlicher
          #4

          @clhallinan said in Using QThread::create() from Qt 6+:

          (&this->waitForVisible, 0);

          Your really should start with basic c++ here...

          The only way is to pass a lambda which is catching this or using a static function

          workerThread = QThread::create([this]() { waitForVisible(); });
          

          But why do you need a thread at all? Your function signature looks like you're waiting for QWidget:::showEvent(). And additionally you must not access gui objects from another thread than the gui (main) thread.

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

          C 1 Reply Last reply
          1
          • Christian EhrlicherC Christian Ehrlicher

            @clhallinan said in Using QThread::create() from Qt 6+:

            (&this->waitForVisible, 0);

            Your really should start with basic c++ here...

            The only way is to pass a lambda which is catching this or using a static function

            workerThread = QThread::create([this]() { waitForVisible(); });
            

            But why do you need a thread at all? Your function signature looks like you're waiting for QWidget:::showEvent(). And additionally you must not access gui objects from another thread than the gui (main) thread.

            C Offline
            C Offline
            clhallinan
            wrote on last edited by clhallinan
            #5

            @Christian-Ehrlicher

            So this is the puzzle I've been trying to solve. I have an application created w/ QtCreator. My mainwindow is derived from a form. The nature of my app requires configuration before it can be used. Upon startup, after all my constructors have been called, the app checks for config, and if it finds an empty config database, it brings up a dialog to prompt the user to enter config data. But the dialog (QMessageBox) comes up before my mainwindow has been displayed, even though my mainwindow constructor (which contains the ui->setupUi(this)) has long since completed, and main.cpp calls w.show() as soon as the mainwindow constructor completes.

            I've tried waiting for isVisible(), overriding QWidget::event() to capture QEvent::show, and tried your suggestion to override QWidget::showEvent(), but still my dialog box come up before mainwindow, who's constructor has long since completed before this dialog is requested.

            Through experimentation, if I wait for a QEvent::UpdateRequest(), in my event() override, then my main window is displayed before my dialog.

            Not sure if this is enough information for any insight?
            Thanks again.

            Christian EhrlicherC JonBJ 2 Replies Last reply
            0
            • C clhallinan

              @Christian-Ehrlicher

              So this is the puzzle I've been trying to solve. I have an application created w/ QtCreator. My mainwindow is derived from a form. The nature of my app requires configuration before it can be used. Upon startup, after all my constructors have been called, the app checks for config, and if it finds an empty config database, it brings up a dialog to prompt the user to enter config data. But the dialog (QMessageBox) comes up before my mainwindow has been displayed, even though my mainwindow constructor (which contains the ui->setupUi(this)) has long since completed, and main.cpp calls w.show() as soon as the mainwindow constructor completes.

              I've tried waiting for isVisible(), overriding QWidget::event() to capture QEvent::show, and tried your suggestion to override QWidget::showEvent(), but still my dialog box come up before mainwindow, who's constructor has long since completed before this dialog is requested.

              Through experimentation, if I wait for a QEvent::UpdateRequest(), in my event() override, then my main window is displayed before my dialog.

              Not sure if this is enough information for any insight?
              Thanks again.

              Christian EhrlicherC Offline
              Christian EhrlicherC Offline
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Apart from the fact that I don't understand why you need to get the main window shown first I would override showEvent() and emit a queued signal in there to do the initialisation.

              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
              3
              • C clhallinan

                @Christian-Ehrlicher

                So this is the puzzle I've been trying to solve. I have an application created w/ QtCreator. My mainwindow is derived from a form. The nature of my app requires configuration before it can be used. Upon startup, after all my constructors have been called, the app checks for config, and if it finds an empty config database, it brings up a dialog to prompt the user to enter config data. But the dialog (QMessageBox) comes up before my mainwindow has been displayed, even though my mainwindow constructor (which contains the ui->setupUi(this)) has long since completed, and main.cpp calls w.show() as soon as the mainwindow constructor completes.

                I've tried waiting for isVisible(), overriding QWidget::event() to capture QEvent::show, and tried your suggestion to override QWidget::showEvent(), but still my dialog box come up before mainwindow, who's constructor has long since completed before this dialog is requested.

                Through experimentation, if I wait for a QEvent::UpdateRequest(), in my event() override, then my main window is displayed before my dialog.

                Not sure if this is enough information for any insight?
                Thanks again.

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

                @clhallinan said in Using QThread::create() from Qt 6+:

                The nature of my app requires configuration before it can be used.

                Then as @Christian-Ehrlicher has said why do you want to show the main window in any form if the application is not "ready" before the configuration parameters are available? Indeed, it would not surprise me if the main window itself has some dependency on these parameters and so should not be shown yet. Why not get the dialog for configuration shown and deal with (or not) before you even try to show the main window?

                void main()
                {
                    QApplication app();
                    if (!configurationIsComplete())
                    {
                        configurationDialog.exec();
                        // handle configuration stuff here or inside `configurationDialog`
                    }
                    QMainWindow mw;
                    mw.show();
                    return app.exec();
                }
                

                A lot of beginners seems to rush into threads. They are about the last thing you want to do, not the first. Not to mention Qt's restrictions on secondary threads accessing the UI in any shape or form. I certainly do not see any need/desire for a thread here.

                1 Reply Last reply
                2

                • Login

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