Using QThread::create() from Qt 6+
-
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!
-
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!
@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?
-
@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?
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?
-
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?
@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 functionworkerThread = 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.
-
@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 functionworkerThread = 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.
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. -
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.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.
-
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.@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.