在QT实现的应用程序界面中,QT的界面主线程必须保持畅通,才能刷新UI。在涉及到使用子线程更新UI上的控件时遇到了点儿麻烦。网上提供了很多同一线程不同类间采用信号槽通信的方式,但是并不完全适合线程间的信号槽通信.本文实现在主界面点击按钮开启子线程,子线程执行完毕,子线程发送一个信号,此信号触发主线程槽函数,实现多线程间的通信问题。
注意:
1.使用信号与槽机制,一定要是QObject类和QObject派生类才有效,否则该机制是无效的。
2.使用信号与槽机制时,需要在类的头文件的第一行加入Q_OBJECT宏,同时该类最好是QObject的派生类。
3.如果正确使用信号与槽机制,同时没有语法错误;但是编译时仍然报错,这时可以尝试把编译出的build*文件整个删除,然后再次编译。(有时是编译过的build文件对信号与槽机制有影响)。
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
class myThread: public QThread
{
Q_OBJECT
public:
explicit myThread(QObject *parent = 0);
public:
void run();
QString name; //添加一个 name 对象
signals:
void finish_save();//自定义信号
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
#include <QDebug>
extern unsigned char data_buf[1980];
//myThread::myThread()
myThread::myThread(QObject *parent):
QThread(parent)
{
}
void myThread::run()
{
qDebug() << this->name << "hello world!";
emit finish_save();//在子线程执行完发送此信号给主线程
}
dailog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QTime>
#include <QTimer>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QIODevice>
#include "mythread.h"
#include <QDebug>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private slots:
void on_pushButton_thread_clicked();
void slot_save_file();
private:
myThread *thread1;
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
dailog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include "mythread.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
setWindowTitle(tr("串口"));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_thread_clicked()//UI界面添加的按钮控件
{
thread1 = new myThread();//创建线程
connect(thread1, SIGNAL(finish_save()), this, SLOT(slot_save_file()));
thread1->name = tr("罗");
thread1->start();//开启线程
}
void Dialog::slot_save_file()
{
thread1->quit();
qDebug() << tr("退出了线程");//退出线程
}
原工程参见:https://download.youkuaiyun.com/download/luo_aiyang/10533175