1. GUI系统设计原则
(1)所有界面组件的操作都只能在主线程中完成;因此,主线程也叫做UI线程!
(2)子线程通过信号和槽机制通知界面组件进行更新。
2. 多线程与界面组件通信的解决方案
(1)在子线程类中定义界面组件更新的信号(如,updateUI)
(2)在主窗口类中定义更新界面组件的槽函数(如,setInfo)
(3)使用异步的队列方式连接更新信号到槽(updateUI→setInfo)
①子线程通过发射信号的方式更新界面组件;
②所有的界面组件对象只能依附于主线程
3、代码如下:主界面定义槽函数(信号处理函数)
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
#include "ui_widget.h"
#include "UpdateThread.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0, Qt::WFlags flags = 0);
~Widget();
UpdateThread m_Thread;
private:
Ui::WidgetClass ui;
protected slots:
void appendText(QString text);
};
#endif // WIDGET_H
#include "widget.h"
Widget::Widget(QWidget *parent, Qt::WFlags flags)
: QWidget(parent, flags)
{
ui.setupUi(this);
//连接更新界面组件的信号和槽
connect(&m_Thread,SIGNAL(updateUI(QString)),
this,SLOT(appendText(QString)));
m_Thread.start();
}
Widget::~Widget()
{
}
void Widget::appendText(QString text)
{
ui.plainTextEdit->appendPlainText(text);
}
#ifndef UPDATETHREAD_H
#define UPDATETHREAD_H
#include <QThread>
class UpdateThread : public QThread
{
Q_OBJECT
public:
UpdateThread();
~UpdateThread();
protected:
void run();
signals://在子线程类中定义界面组件更新的信号
void updateUI(QString text);
};
#endif // UPDATETHREAD_H
#include "UpdateThread.h"
UpdateThread::UpdateThread()
: QThread()
{
}
UpdateThread::~UpdateThread()
{
}
void UpdateThread::run()
{
emit updateUI("Begin");//通知UI线程更新
for(int i=0;i<10;i++)
{
emit updateUI(QString::number(i));
sleep(1);
}
emit updateUI("End");
}
4. 小结
(1)现代GUI平台只允许在主线程中直接操作界面组件
(2)Qt中可以借助信号与槽机制在子线程中操作界面组件
(3)进行信号和槽连接必须采用异步的队列连接方式
(4)界面组件对象只能依附于主线程