QT多线程专栏共有15篇文章,从初识线程到、QMutex锁、QSemaphore信号量、Emit、Sgnals、Slot主线程子线程互相传值同步变量、QWaitCondition、事件循环、QObjects、线程安全、线程同步、线程异步、QThreadPool线程池、ObjectThread多线程操作、 moveToThread等线程操作进行了全面!深入!的研究和详细的说明
本文实现了QObjectThread多线程的使用示例,新建了四个线程同时绑定了QTextEdit进行输出,moveToThread也有详细代码教程示例。
QT ObjectThread moveToThread多线程操作目录
1 新建界面
新建四个QTextEdit控件两个按钮
2 mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include <QThread>
#include <QCloseEvent>
#include "WorkObject.h"
#pragma execution_character_set("utf-8")
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void editInsertText1(QString strText);
void editInsertText2(QString strText);
void editInsertText3(QString strText);
void editInsertText4(QString strText);
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
WorkObject* m_workList[4];
QThread m_thread[4];
QString Title;
QString Version;
QString BlogText;
};
#endif // MAINWINDOW_H
3 mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
Title = "QT QObjectThread CSDN 双子座断点 ";
Version = "V 1.0 ";
BlogText = "https://blog.csdn.net/qq_37529913?type=lately/";
setWindowTitle(Title + Version + BlogText);
m_workList[0]=new WorkObject(ui->textEdit);
m_workList[1]=new WorkObject(ui->textEdit_2);
m_workList[2]=new WorkObject(ui->textEdit_3);
m_workList[3]=new WorkObject(ui->textEdit_4);
m_workList[0]->moveToThread(&m_thread[0]);
m_workList[1]->moveToThread(&m_thread[1]);
m_workList[2]->moveToThread(&m_thread[2]);
m_workList[3]->moveToThread(&m_thread[3]);
connect(&m_thread[0],SIGNAL(started()),m_workList[0],SLOT(starWork()));
connect(&m_thread[1],SIGNAL(started()),m_workList[1],SLOT(starWork()));
connect(&m_thread[2],SIGNAL(started()),m_workList[2],SLOT(starWork()));
connect(&m_thread[3],SIGNAL(started()),m_workList[3],SLOT(starWork()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
m_workList[0]->startThread();
m_workList[1]->startThread();
m_workList[2]->startThread();
m_workList[3]->startThread();
m_thread[0].start();
m_thread[1].start();
m_thread[2].start();
m_thread[3].start();
}
void MainWindow::on_pushButton_2_clicked()
{
m_workList[0]->stopThread();
m_workList[1]->stopThread();
m_workList[2]->stopThread();
m_workList[3]->stopThread();
QTimer::singleShot(1*1000,&m_thread[0],SLOT(terminate()));
QTimer::singleShot(1*1000,&m_thread[1],SLOT(terminate()));
QTimer::singleShot(1*1000,&m_thread[2],SLOT(terminate()));
QTimer::singleShot(1*1000,&m_thread[3],SLOT(terminate()));
}
4 WorkObject.h
#ifndef WORKOBJECT_H
#define WORKOBJECT_H
#include <QObject>
#include <QTime>
#include <QDebug>
#include <QThread>
#include <QTextEdit>
#pragma execution_character_set("utf-8")
QT_BEGIN_NAMESPACE
class QListWidget;
QT_END_NAMESPACE
class WorkObject : public QObject
{
Q_OBJECT
public:
WorkObject(QTextEdit *listEdit,QObject *parent = 0);
~WorkObject();
void stopThread();
void startThread();
private:
QTextEdit *m_listEdit;
bool m_runStatus;
public slots:
void starWork();//开始工作
};
#endif // WORKOBJECT_H
5 WorkObject.cpp
#include "WorkObject.h"
WorkObject::WorkObject(QTextEdit *listEdit, QObject *parent)
: QObject(parent)
{
m_listEdit=listEdit;
m_runStatus=true;
}
WorkObject::~WorkObject()
{
}
void WorkObject::starWork()
{
while (true)
{
if(!m_runStatus){
break;
}
QString msg="ThreadId:" + QString::number((unsigned int)QThread::currentThreadId()) + " " + " Time:"+QTime::currentTime().toString("HH:mm:ss");
m_listEdit->insertPlainText(msg + "\n");
QThread::sleep(1);
}
}
void WorkObject::stopThread()
{
m_runStatus=false;
}
void WorkObject::startThread()
{
m_runStatus=true;
}
//#include "WorkObject.h"
//WorkObject::WorkObject(QObject *parent)
// : QObject(parent)
//{
//}
//WorkObject::~WorkObject()
//{
// qDebug() << "WorkObject 销毁" << endl;
//}
//void WorkObject::objWork()
//{
// for (int i = 0; i < 1000; ++i)
// {
// qDebug() << i << endl;
// }
// emit workFinished();
//}
//void WorkObject::starWork()
//{
// emit workStart();
// objWork();
//}
6 moveToThread
以下附加核心代码、全部代码请参考最后。
6.1 效果
6.2 ObjectThread.h
#ifndef OBJECTTHREAD_H
#define OBJECTTHREAD_H
#include <QObject>
#include <QThread>
#include <QDebug>
#pragma execution_character_set("utf-8")
class ObjectThread : public QObject
{
Q_OBJECT
public:
ObjectThread(QObject *parent = nullptr);
~ObjectThread();
public:
void stopThread();
void startThread();
public slots:
void slotStart();
private:
bool m_runStatus;
};
#endif // OBJECTTHREAD_H
6.3 ObjectThread.cpp
#include "ObjectThread.h"
ObjectThread::ObjectThread(QObject *parent): QObject(parent)
{
m_runStatus = false;
}
ObjectThread::~ObjectThread()
{
}
void ObjectThread::stopThread()
{
m_runStatus=false;
}
void ObjectThread::startThread()
{
m_runStatus=true;
}
void ObjectThread::slotStart()
{
int i = 0;
qDebug()<<"子线程 id"<<QThread::currentThreadId();
while (true)
{
if(!m_runStatus){
break;
}
qDebug()<<"线程自增:" + QString::number(++i);
QThread::sleep(1);
}
}
7 mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include <QThread>
#include <QCloseEvent>
#include "WorkObject.h"
#include "ObjectThread.h"
#pragma execution_character_set("utf-8")
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void editInsertText1(QString strText);
void editInsertText2(QString strText);
void editInsertText3(QString strText);
void editInsertText4(QString strText);
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
QThread thread;
ObjectThread* object;
// WorkObject* m_workList[4];
// QThread m_thread[4];
QString Title;
QString Version;
QString BlogText;
};
#endif // MAINWINDOW_H
8 mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
Title = "QT QObjectThread CSDN 双子座断点 ";
Version = "V 1.0 ";
BlogText = "https://blog.csdn.net/qq_37529913?type=lately/";
setWindowTitle(Title + Version + BlogText);
object = new ObjectThread;
object->moveToThread(&thread);
connect(&thread,SIGNAL(started()),object,SLOT(slotStart()));
// m_workList[0]=new WorkObject(ui->textEdit);
// m_workList[1]=new WorkObject(ui->textEdit_2);
// m_workList[2]=new WorkObject(ui->textEdit_3);
// m_workList[3]=new WorkObject(ui->textEdit_4);
// m_workList[0]->moveToThread(&m_thread[0]);
// m_workList[1]->moveToThread(&m_thread[1]);
// m_workList[2]->moveToThread(&m_thread[2]);
// m_workList[3]->moveToThread(&m_thread[3]);
// connect(&m_thread[0],SIGNAL(started()),m_workList[0],SLOT(starWork()));
// connect(&m_thread[1],SIGNAL(started()),m_workList[1],SLOT(starWork()));
// connect(&m_thread[2],SIGNAL(started()),m_workList[2],SLOT(starWork()));
// connect(&m_thread[3],SIGNAL(started()),m_workList[3],SLOT(starWork()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
object->startThread();
//object->slotStart();
thread.start();
// m_workList[0]->startThread();
// m_workList[1]->startThread();
// m_workList[2]->startThread();
// m_workList[3]->startThread();
// m_thread[0].start();
// m_thread[1].start();
// m_thread[2].start();
// m_thread[3].start();
}
void MainWindow::on_pushButton_2_clicked()
{
object->stopThread();
thread.quit();
thread.wait();
// delete thread;
// thread = NULL;
// m_workList[0]->stopThread();
// m_workList[1]->stopThread();
// m_workList[2]->stopThread();
// m_workList[3]->stopThread();
// QTimer::singleShot(1*1000,&m_thread[0],SLOT(terminate()));
// QTimer::singleShot(1*1000,&m_thread[1],SLOT(terminate()));
// QTimer::singleShot(1*1000,&m_thread[2],SLOT(terminate()));
// QTimer::singleShot(1*1000,&m_thread[3],SLOT(terminate()));
}
9 多线程的各种操作
以下文章均为作者原创文章,看完记得收藏、关注加👍
线程、进程、多线程、线程池一文看懂从此秒变大佬!:深入理解线程、进程、多线程、线程池_双子座断点的博客-CSDN博客
QT 初识线程(简单实现):https://blog.csdn.net/qq_37529913/article/details/110127940
QT QMutex使用详解:https://blog.csdn.net/qq_37529913/article/details/110187452
QT 线程之QSemaphore(深入理解):https://blog.csdn.net/qq_37529913/article/details/110187121
QT线程 Emit、Sgnals、Slot详细解释:https://blog.csdn.net/qq_37529913/article/details/110211435
QT 线程之QWaitCondition(深入理解):https://blog.csdn.net/qq_37529913/article/details/110212704
Qt 多线程之线程事件循环(深入理解):https://blog.csdn.net/qq_37529913/article/details/110229382
QT线程之QObjects(深入理解):https://blog.csdn.net/qq_37529913/article/details/110228837
QT线程之可重入与线程安全(深入理解):https://blog.csdn.net/qq_37529913/article/details/110224166
QT 主线程子线程互相传值:QT 主线程子线程互相传值_双子座断点的博客-CSDN博客_qt主线程给子线程传数据
QT线程同步与异步处理:QT线程同步与异步处理_双子座断点的博客-CSDN博客_qt异步线程
QT 多线程之线程池QThreadPool(深入理解):QT 多线程之线程池QThreadPool(深入理解)_双子座断点的博客-CSDN博客_qthreadpool
QT之浅拷贝、深拷贝、隐式共享(深度理解必看文章):https://blog.csdn.net/qq_37529913/article/details/110235596QT 隐式共享机制对STL样式迭代器的影响:https://blog.csdn.net/qq_37529913/article/details/110252454