Qt如何以正确的方式从正在运行的线程更新主窗口

时间:2011-12-29 06:20:13

标签: c++ multithreading qt

我有简单的应用程序,在主视图中我有QListview。我的流程是这样的,我需要知道它是否正确 1.App启动并启动单线程,也可以看到线程对象和主应用程序之间的信号/槽连接 2.Thread从远程服务器获取数据为xml格式,并将数据设置为对象容器(表示数据的类) 3.当数据在对象中准备就绪时,它会触发SIGNAL返回主应用程序(第1部分的信号/插槽)
4. SIGNAL调用更新函数,通过其模型将格式化数据设置为QListView(QAbstractListModel)

问题是当第4阶段发生时我在应用程序中看到一些frize 2-3秒,这让我想知道这里有什么问题。

更新
使用sleepy对应用进行概要分析后 看起来应用程序中的延迟我不确定但是在Exclusive列中显示 非常高的322.35s。 在我的线程中调用run方法中的http请求我有这个代码让线程暂停。

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();
}

但现在问题是如何改进它?

2 个答案:

答案 0 :(得分:3)

我怀疑由于您在QThread :: run()方法中创建了计时器,因此在主线程的上下文中调用计时器连接的插槽。

您不需要将QThread子类化为在自己的线程中运行代码。

只需子类化QObject,添加所需的功能,创建QThread实例,启动它并使用QObject :: moveToThread()方法将QObject的线程关联设置为新线程。

    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);

答案 1 :(得分:0)

我建议你在线程的情况下使用QEventloop。

在主

中启动事件循环
//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
}