1. 程式人生 > >QT 多執行緒 使用UI

QT 多執行緒 使用UI

直接上程式碼:

qt的ui操作必須在主執行緒做的,分支執行緒只能傳送訊息給主執行緒進行引導操作。

所以平常我們的程式碼都是直接使用一個執行緒來調動UI,但是不同的執行緒同時需要使用UI來顯示結果之類的就需要相互協調;

如果沒有invoke之類的方法,可以考慮直接使用qt 的Qthread;直接使用thread會衝突;

1    需要使用UI的執行緒所在的類必須是繼承自Qthread; 標頭檔案#include<qthread.h>

   定義 訊號函式

#include <QObject>
#include<qthread.h>
#include<thread>
using namespace std;
class QTgui :public QThread
{
	Q_OBJECT
signals :
	void sigCurrentImage2(int img);

2  連結類執行緒函式(訊號)和主介面顯示UI的函式(槽)

g1 = new QTgui(this);

connect(g1, SIGNAL(sigCurrentImage2(int)), this, SLOT(slot3(int)));

3 在類中重寫run函式

void QTgui::run()
{
	while (add == 0)
	{
		k += 3;
		this_thread::sleep_for(std::chrono::milliseconds(timee));
		emit sigCurrentImage2(k);
	}
}

4 啟動run執行緒

void QTgui::addd()
{
	add = 0;
	start();
	//std::thread thread1(std::bind(&QTgui::porcess, this));
	//tthread = &thread1;
	//tthread->detach();
	
}

5 全部程式碼  在這裡:

 

#pragma once

#include <QObject>
#include<qthread.h>
#include<thread>
using namespace std;
class QTgui :public QThread
{
	Q_OBJECT
signals :
	void sigCurrentImage2(int img);
public:
	QTgui(QObject *parent);
	~QTgui();
	int k;
	int add;
	int timee=3;
	std::thread * tthread;

	void run();
	void addd();
	void porcess();
};
#include "QTgui.h"

QTgui::QTgui(QObject *parent)
	: QThread(parent)
{
	k = 0;
	add = 0;
}

QTgui::~QTgui()
{
}

void QTgui::run()
{
	while (add == 0)
	{
		k += 2;
		this_thread::sleep_for(std::chrono::milliseconds(timee));
		emit sigCurrentImage2(k);
	}
}

void QTgui::addd()
{

	start();
	//std::thread thread1(std::bind(&QTgui::porcess, this));
	//tthread = &thread1;
	//tthread->detach();
	
}

void QTgui::porcess()
{
	while (add == 0)
	{
		k += 2;
		this_thread::sleep_for(std::chrono::milliseconds(timee));
		emit sigCurrentImage2(k);
	}
}



#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_threadGui.h"
#include"QTgui.h"
class threadGui : public QMainWindow
{
	Q_OBJECT

public:
	threadGui(QWidget *parent = Q_NULLPTR);

	QTgui* g1;
	QTgui* g2;
	
private:
	Ui::threadGuiClass ui;
	private slots:
	void slot2();
	void slot1();
	void slot3(int k);
};


#include "threadGui.h"

threadGui::threadGui(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	g1 = new QTgui(this);
	/*connect(g1, &QTgui::sigCurrentImage2, [=](int img) {
		slot3(img);
	});*/
	g2 = new QTgui(this);
	g2->k = 1;
	g2->timee = 50;
	//connect(g2, &QTgui::sigCurrentImage2, [=](int img) {
	//	slot3(img);
	//});  
	connect(g1, SIGNAL(sigCurrentImage2(int)), this, SLOT(slot3(int)));
	connect(g2, SIGNAL(sigCurrentImage2(int)), this, SLOT(slot3(int)));
}


void threadGui::slot3(int k)
{
	if (k %2 ==0 ||true)
	{
		ui.label->setText(QString::number(k));

	}
	else {
		ui.label_2->setText(QString::number(k));
	}
}

void threadGui::slot1()
{
	g1->addd();
	g2->addd();
}

void threadGui::slot2()
{
	g1->add = 1;
	g2->add = 1;
	ui.label_3->setText(QString::number(g1->k) + QString::number(g2->k));
}