前言
之前讲过继承QThread,在虚函数run()中实现线程里的工作。这是qt4.6之前的方法,目前官方推荐的方法,是继承QObject类,再用方法moveToThread来将QObject派生类移动到新线程中去,这样QObject派生类定义的信号和槽的事件响应行为,都会发生在新的线程中。
这个方法非常简单。下面还是以串口通讯作为例子,这次不用窗口,用控制台的方式。
新建工程
打开QTcreator,新建一个Qt Console Application工程,起好工程名,选用qmake作为编译工具,选择Desktop MinGW 64-bit作为编译器。
ps:选择编译器时,会看到各种各样的编译器,如MSVC,MinGW等,这取决于在安装Qt时你的选择。在选择编译器时还会看到,Desktop和UWP两种平台的选择,Desktop很好解释,就是桌面程序,UWP全称是Universal Windows Platform,即Windows通用应用平台,只支持Window10以上系统,如Windows应用商店上的应用都是UWP平台的。
建立完成以后,我们可以看到工程目录只有pro文件,和main.cpp。因为是控制台程序,要比窗口程序要简化很多,很适合做后台程序。
源码
使用QSerialPort首先得在pro文件中,增加serialport模块
QT +=serialport
在serialobject头文件中,我们定义了serialobject类,继承QObject类,这个serialobject类后面我们要通过moveToThread方法放进线程里,在QObject类new的对象和定义的信号和槽都将运行在新的线程中。
在使用moveToThread方法后,所有与信号关联的槽的运行都在新的线程中,但没有通过信号与槽方式的函数,都属于调用他的线程,比如构造函数。
我们的QserialPort对象是我们用来实际操作和设置串口的对象,设置为private类型,这样将所有的串口操作都放在了serialobject类里,多个串口就new多个serialobject类,可以方便创建多个线程操作。
serialobject.h
#ifndef SERIALOBJECT_H
#define SERIALOBJECT_H
#include <QObject>
#include <QSerialPort>
#include <QTimer>
class serialobject : public QObject
{
Q_OBJECT
public:
explicit serialobject(QObject *parent = nullptr);
~serialobject();
public:
void senddata(QByteArray &msg);
private:
QSerialPort *myQSerialPort=nullptr;
QTimer *timer=nullptr;//定时器
public slots:
void receivedata();
void cyclesend();
void init();
signals:
void datareceived();