質問

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.

How to Use QThread in the Right Way (Part 1)

How to Use QThread in the Right Way (Part 2)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top