简体   繁体   中英

Qt How to update main windows from running thread , the right way

I have simple application that in the main view I have QListview . my flow going like this I need to know if it right
1.App starts and start single thread , also see signal/slot connect between the thread object and the main app
2.Thread gets data from remote server as xml format its and sets the data into object container (class that represent the data )
3.when the data is ready in the object it trigger SIGNAL back to the main app (the signal/slot from section 1)
4.The SIGNAL invoking update function that sets the formatted data into the QListView via its model (QAbstractListModel)

The problem is when stage 4 is happening I see some frize in the application for 2-3 seconds that makes me wonder what is wrong here .

UPDATE:
after profiling the app with sleepy it looks like the delay in the app im not sure but is shows in the Exclusive column very high number 322.35s. in my Thread that calls the http request inside the run method i have this code that couse the thread to pause.

void RequestThread::run()
{
          m_RequestThreadTimer = new QTimer();
          connect(m_RequestThreadTimer, SIGNAL(timeout()),
                  this,SLOT(fire(),Qt::DirectConnection));
          QVariant val(GetValFromConfig());       
          int interval = val.toInt();
          m_RequestThreadTimer->setInterval(interval);
          m_RequestThreadTimer->start();    
          QThread::exec();
}

but now is the question how to improve it ?

I suspect that since you create the timer in the QThread::run() method the slot the timer connects to is being called in the context of the main thread.

You don't need to subclass QThread to run code in its own thread.

Just subclass a QObject, add the functionality you want, create a QThread instance, start it and use the QObject::moveToThread() method to set the QObject's thread affinity to the new thread.

    worker = new WorkerClass;
    connect(worker,SIGNAL(response(QString)),this,SLOT(response(QString)));
    QThread *t = new QThread;
    t->start();
    worker->moveToThread(t);

    //Start it either like this or by emitting a signal connected to the startWorking slot
    QMetaObject::invokeMethod(worker,"startWorking",Qt::QueuedConnection);

I suggest you to use the QEventloop in the case of the thread.

Start the event loop in the main

//start the function to get data from remote server
GetData::getInstance()->StratReading();
QEventLoop loop; //loop to continue the reading.
loop.connect(GetData::getInstance(),SIGNAL(ReadingFinished()),SLOT(quit()));
loop.exec();

GetData::StratReading()
{
//sets the data into object container 
//the data is ready in the object it trigger SIGNAL to main function to update to Ui
emit ReadingFinished(); //this will quit the loop
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM