Start a new thread from the constructor of a QMainWindow in Qt
-
21-12-2019 - |
質問
I have the MainWindow
class. In the constructor of this class I want to start a new thread that will do some work. But I get this error:
Assert failure in QWidget: "Widgets must be created in the GUI thread."
In this new thread I am not creating any widgets. This is what I have tried so far. Could someone help me on solving this problem? In don't have experience with signals and slots and I will really appreciate some advises.
newThread.h
#ifndef NEWTHREAD_H
#define NEWTHREAD_H
#include <QThread>
#include "mainwindow.h"
class NewThread : public QThread
{
Q_OBJECT
public:
explicit NewThread(QObject *parent = 0);
signals:
public slots:
protected:
void run();
};
#endif // NEWTHREAD_H
newThread.cpp
#include "newthread.h"
NewThread::NewThread(QObject *parent) :
QThread(parent) { }
void NewThread::run(){
MainWindow m;
m.updateInBackground();
}
MainWindow.cpp
MainWindow::MainWindow(QStringList applications, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ReadFromRegistry read;
this->setFixedSize(435,280);
ui->setupUi(this);
appsNames = applications;
this->apps = read.getApplicationsFromRegistry(appsNames);
ui->updateInBackgroundCkb->setChecked(false);
//read from settings.xml the time interval
QString time = RWXml::readSettingsFile();
if(time.compare("-1") != 0){
NewThread th;
while(true){
th.start();
th.sleep(time.toLong(0,10));
}
}
}
EDIT:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStringList apps;
QString app = "AppTest1";
apps.append(app);
app = "AppTest2";
apps.append(app);
app = "AppTest3";
apps.append(app);
MainWindow w(apps);
w.create();
w.show();
return a.exec();
}
I instantiate the MainWindow
in main. But i need to access the method from MainWindow
in the run method of the NewThread
. That's why it is instantiated in the NewThread
.
EDIT:
void MainWindow::updateInBackground(){
ClientSocket client;
for(Application ap : getApps()){
QString currentVersion = ap.getAppVersion();
QString appCode = ap.getAppCode();
QString appSerial = ap.getAppSerialNo();
client.connect();
QString message = "2//" + currentVersion + "//" + appCode + "//"+ appSerial;
//send message to the server
client.sendMessage(message);
//receiver message from the server
QString received = client.receiveMessage();
//check if the current version is the last one
if(received.compare("0") != 0){
//if is not the last one, set the new version
ap.setAppVersion(received);
//set the update date
ap.setCurrentDate();
//write in windows registry
WriteInRegistry::writeRegistry(ap);
//update the xml file containg the updates of this application
updateXMLFile(ap);
}
}
//read from registry
ReadFromRegistry read;
//populate the grid from the MainWindow with the new data
populateTable(read.getApplicationsFromRegistry(getAppsNames()));
client.closeConnection();
}
解決
Your issue with your code is that you create the mainwindow and the qt application in different threads. The main window seems to be created in your "new thread", whereas the qt application is not.
You also seem to have a circular dependency between the mainwindow constructor and the run method of the thread.
You would need to move the mainwindow creation into your main.cpp which is also a logical place for it.
That being said, please do take a look at the url below and all the references in the post for getting some further thoughts.