一、多线程与界面组件的通信
1、GUI设计原则
(1)、所有界面组件的操作都只能在主线程中完成
(2)、因此,主线程也叫UI线程
2、子线程对界面组件进行更新的解决方案-----信号与槽
(1)、在子线程类中定义界面更新信号(updateUI)
(2)、在窗口类中定义更新界面组件的槽函数(setInfo)
(3)、使用异步方式连接更新信号到槽函数(updateUI--->setInfo)
A、子线程通过发射信号的方式更新界面组件
B、所有界面组件对象只能依附主线程

#ifndef MYTHREAD_H #define MYTHREAD_H #include <QThread> #include <QString> class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = 0); signals: void UpdataUI(QString text); private: void run(); public slots: }; #endif // MYTHREAD_H

#include "MyThread.h" #include<QString> MyThread::MyThread(QObject *parent) : QThread(parent) { } void MyThread::run() { emit UpdataUI("begin"); for(int i=0; i<10; i++) { emit UpdataUI(QString::number(i)); sleep(1); } emit UpdataUI("end"); }

#ifndef WIDGET_H #define WIDGET_H #include <QtGui/QWidget> #include <QPlainTextEdit> #include "MyThread.h" class Widget : public QWidget { Q_OBJECT private: QPlainTextEdit* m_plaintext; MyThread mythread; protected slots: void setInfo(QString text); public: Widget(QWidget *parent = 0); ~Widget(); }; #endif // WIDGET_H

#include "Widget.h" Widget::Widget(QWidget *parent) : QWidget(parent) { m_plaintext = new QPlainTextEdit(this); m_plaintext->resize(160,160); m_plaintext->setReadOnly(true); connect(&mythread, SIGNAL(UpdataUI(QString)), this, SLOT(setInfo(QString))); mythread.start(); } void Widget::setInfo(QString text) { m_plaintext->appendPlainText(text); } Widget::~Widget() { }
#include <QtGui/QApplication> #include "Widget.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w;//依附于主线程,而发射信号的不依附主线程,故根据默认方式,这里已经是异步模式 w.show(); return a.exec(); }
二、小结
(1)、现代GUI平台只允许在主线程中直接操作界面组件
(2)、Qt中可以借助信号与槽的机制在子线程中操作界面组件
(3)、进行信号与槽的连接时必须采用异步连接的方式
(4)、界面组件对象必须依附于主线程