按照往常先贴运行结果
点击open开关后可以对下方的label控件进行滚动显示,然后点击close后可以关闭线程运行。
直接上代码。
mythread.h
/*子线程程序*/
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QObject>
#include <qlabel.h>
class MyThread : public QObject
{
Q_OBJECT
public:
MyThread(QObject *parent=0);
~MyThread();
void change_label_text(QLabel &label_);//定义改变label控件函数
void change_label_text2(QLabel &label_);
void setFlag(bool flag = true);//定义flag为布尔变量(布尔变量只能显示true与false两个情况)
void change_label_text2();
void setFlag2(bool flag2 = true);
signals:
void mySignal();
void mySignal2();
private:
bool isStop;
bool isStop2;
bool k;
bool j;
public:
bool returnK(){ return this->k; };//执行识别转化
bool returnj(){ return this->j; };
};
#endif // MYTHREAD_H
reg.h
#ifndef REG_H
#define REG_H
#include <qgroupbox.h>
#include <QtWidgets/QWidget>
#include <QLabel>
#include "mythread.h"
#include <QThread>
class reg : public QWidget
{
Q_OBJECT
public:
explicit reg(QWidget *parent = 0);
~reg();
void dealDestroy1();
void dealDestroy2();//定义结束函数
private:
QGroupBox *GroupBox_1();
QGroupBox *GroupBox_2();
QLabel *label_1;
QLabel *label_2;
private:
//定义线程
MyThread *myT;
QThread *thread;
MyThread *myT2;
QThread *thread2;
private slots:
//定义链接函数
void change_text_start1();
void change_text_stop1();
void change_text_start2();
void change_text_stop2();
signals:
//定义信号函数
void startThread();
void startThread2();
};
#endif // REG_H
main.cpp
#include "reg.h"
#include <QtWidgets/QApplication>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
reg w;
w.show();
return a.exec();
}
mythread.cpp
#pragma execution_character_set("UTF-8")
#include <QThread>
#include <QDebug>
#include <QMessageBox>
#include "reg.h"
#include <QT>
MyThread::MyThread(QObject *parent)
: QObject(parent)
{
//初始化变量
isStop = false;
isStop2 = false;
}
MyThread::~MyThread()
{
}
void MyThread::change_label_text( QLabel &label_)
{
while (isStop == false)
{
QThread::sleep(1);//延迟1秒
k = !k;//布尔变量的转化
emit &MyThread::mySignal;//emit(发出传输信号)
qDebug() << "子程序信号:" << QThread::currentThread();
qDebug() << "k:" << k;//在输出是确认是否可以运行
if (k) {
label_.setText("sss");//对k进行判断改变label控件文字
}
else if (!k)
{
label_.setText("aaaaa");
}
if (isStop==true)//结束循环
break;
}
}
void MyThread::change_label_text2(QLabel &label_)
{
while (isStop2 == false)
{
QThread::sleep(1);
j = !j;
emit &MyThread::mySignal2;
qDebug() << "子程序信号:" << QThread::currentThread();
qDebug() << "j:" << j;
if (j) {
label_.setText("kkk");
}
else if (!j)
{
label_.setText("bbb");
}
if (isStop == true)
break;
}
}
//
void MyThread::setFlag(bool flag)
{
isStop = flag;
}
void MyThread::setFlag2(bool flag2)
{
isStop2 = flag2;
}
reg.cpp
#pragma execution_character_set("UTF-8")
#include "reg.h"
#include "mythread.h"
#include "QPushButton.h"
#include <QLabel>
#include <QGroupBox>
#include <QGridLayout>
#include <QLayout>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug>
reg::reg(QWidget *parent)
: QWidget(parent)
{
//ui界面
QVBoxLayout *vLayout_1 = new QVBoxLayout;
QGroupBox *GroupBox_1 = new QGroupBox(QStringLiteral("GroupBox1"));
QPushButton *button_1 = new QPushButton("open1");
QPushButton *button_3 = new QPushButton("close1");
vLayout_1->addWidget(button_1);
vLayout_1->addWidget(button_3);
label_1 = new QLabel("label10");
connect(button_1, SIGNAL(clicked()), this, SLOT(change_text_start1()));//点击按钮使他进入线程开启程序
connect(button_3, SIGNAL(clicked()), this, SLOT(change_text_stop1()));
vLayout_1->addWidget(label_1);
GroupBox_1->setLayout(vLayout_1);
QVBoxLayout *vLayout_2 = new QVBoxLayout;
QGroupBox *GroupBox_2 = new QGroupBox(QStringLiteral("GroupBox2"));
QPushButton *button_2 = new QPushButton("open2");
QPushButton *button_4 = new QPushButton("close2");
vLayout_2->addWidget(button_2);
vLayout_2->addWidget(button_4);
label_2 = new QLabel("label20");
connect(button_2, SIGNAL(clicked()), this, SLOT(change_text_start2()));
connect(button_4, SIGNAL(clicked()), this, SLOT(change_text_stop2()));
vLayout_2->addWidget(label_2);
GroupBox_2->setLayout(vLayout_2);
QHBoxLayout *hlayout_1 = new QHBoxLayout(this);
hlayout_1->addWidget(GroupBox_1);
hlayout_1->addWidget(GroupBox_2);
hlayout_1->addStretch();
//定义子线程
myT = new MyThread;//定义myt为mythread.cpp的一个对象
thread = new QThread;//定义thread为新线程并给与新的内存
myT->moveToThread(thread);//讲myt对象放入线程中
connect(this, ®::startThread, myT, [=]()//接受来自startThread的信号执行程序
{
myT->change_label_text(*label_1);//改变label控件,改变指定的label控件
});
connect(this, ®::destroyed, this, ®::dealDestroy1);
myT2 = new MyThread;
thread2 = new QThread;
myT2->moveToThread(thread2);
connect(this, ®::startThread2, myT2, [=]()
{
myT->change_label_text2(*label_2);
});
connect(this, ®::destroyed, this, ®::dealDestroy2);
///
}
reg::~reg()
{
}
void reg::dealDestroy1()
{
qDebug() << "在执行dealDestroy" << QThread::currentThread();
change_text_stop1();//关闭线程函数
delete myT;//删除退出子线程
}
void reg::change_text_start1()
{
if (thread->isRunning() == true) return;//如果子线程在开启状态则返回空值
qDebug() << "在执行change_text_start";
thread->start();//线程开启
myT->setFlag(false);
emit startThread();//发出信号
}
void reg::change_text_stop1()
{
if (thread->isRunning() == false)return;
myT->setFlag(true);
thread->quit();//线程关闭清空
thread->wait();//线程等待(2句话是共同实现的)
}
void reg::dealDestroy2()
{
qDebug() << "在执行dealDestroy" << QThread::currentThread();
change_text_stop2();
delete myT2;
}
void reg::change_text_start2()
{
if (thread2->isRunning() == true) return;
thread2->start();
myT2->setFlag2(false);
emit startThread2();
}
void reg::change_text_stop2()
{
if (thread2->isRunning() == false)return;
myT2->setFlag2(true);
thread2->quit();
thread2->wait();
}
应用的关键还是在于建立线程
myT2 = new MyThread;
thread2 = new QThread;
myT2->moveToThread(thread2);
其次是对线程运行的连接
connect(this, ®::startThread2, myT2, [=]()
{
myT->change_label_text2(*label_2);
});
当然这些地方不一定需要使用通过信号连接,可以直接通过按钮点击也是可以的,但是在项目中会出现许多奇奇怪怪的问题,所以一般情况下可以使用按钮直接连接,也可以使用信号连接。
这东西根据实际应用来决定吧。