首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > QT开发 >

QT如何避免耗时的操作

2013-07-01 
QT如何处理耗时的操作请问下如果在QT里面处理耗时的操作,以前我的做法是开一个线程去处理,但是QT在QWidget

QT如何处理耗时的操作
请问下如果在QT里面处理耗时的操作,以前我的做法是开一个线程去处理,但是QT在QWidget下面怎么开一个线程呢?我还要在线程控制UI界面该如何处理,求大神给一个可用的代码,感激
[解决办法]
建立一个线程来处理耗时的工作其实算是比较普遍的问题,但实际操作起来比较棘手。
这里给楼主一些简单的操作步骤:
1、建立一个工作类,派生于QObject,比如:Worker,用于执行耗时操作:

class Worker : public QObject
{
Q_OBJECT
public slots:
// 长时间的作业
void doWork()
{
// ...
emit progress("正在...");
// ...
// 通知当前线程退出,即投递一个退出事件
QThread::currentThread()->quit();
}
// ...
signals:
void progress(const QString &text); // 进度
// ...
};

2、建立一个QThread的子类,用于启动线程和消息循环:
class Launcher : public QThread
{
Q_OBJECT
protected:
void run()
{
exec(); // 执行事件循环
}
public:
void launchWorker(Worker *worker)
{
// 初始化worker
// ...
worker->moveToThread(this); // 把worker移动到当前线程
start(); // 启动线程
}
};

3、使用这2个类:
Launcher launcher;
Worker *worker = new Worker;
connect(worker, SIGNAL(progress(QString)), mainWindow, SLOT(updateProgress(QString)), Qt::QueuedConnection);
launcher.launchWorker(worker);
QMetaObject::invokeMethod(worker, "doWork", Qt::QueuedConnection);
launcher.wait();
delete worker;

注意,worker的progress signal和主窗口mainWindow(GUI线程某个响应的类)的updateProgess slot是通过QueuedConnection类型来连接的。因为当前在doWork里触发progress的时候,mainWindow可能还在响应事件(如窗口事件)或做其它事情。不要用DirectConnection类型来连接,避免出现未知的行为。
QMetaObject::invokeMethod调用doWork,这时也是用的QueuedConnection类型,即通过事件循环来执行doWork。
一个QObject对象属于创建它的线程,它能处理这个线程给他分配的事件。
注意worker和launcher都是属于GUI线程的,所以launchWorker里面把worker移动到了launcher线程,只有这样worker才能接收launcher线程里的事件。
请参考:
http://qt-project.org/doc/qt-4.8/thread-basics.html
http://qt-project.org/wiki/Threads_Events_QObjects

热点排行