多线程与界面组件的通信_20191218

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)界面组件对象只能依附于主线程

发布了140 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_41211961/article/details/103604565
今日推荐