QThread创建多线程程序
Posted samp000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QThread创建多线程程序相关的知识,希望对你有一定的参考价值。
最近在阅读Qt 5.9 C++开发指南,为了加深对书本上内容的理解,参照书上的讲解尝试写了一些demo,用于以后工作中查阅,如果涉及侵权请告知,实例程序samp13_1
mythread.h
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QThread> class MyThread : public QThread { Q_OBJECT private: int _times; int _value; protected: void run(); public: MyThread(); ~MyThread(); signals: void timesValueChanged(int times, int value); }; #endif // MYTHREAD_H
mythread.cpp
#include "mythread.h" #include <QRandomGenerator> MyThread::MyThread() { _times = 0; _value = 0; } MyThread::~MyThread() { } // 这个是通过信号与槽与主窗口进行交互的,还有一种方法是通过函数 void MyThread::run() { while(1) { _value = QRandomGenerator::global()->generate(); // 用这个类生成随机数 _value = (_value % 6) + 1; // 这个类生成的数可能是负数,如果是负数就从新生成 if(_value <= 0) { continue; } _times = _times + 1; emit timesValueChanged(_times, _value); // 发信号给主窗口,叫他显示 msleep(500); // 先睡一会儿在生成数字 } }
mydialog.h
#ifndef MYDIALOG_H #define MYDIALOG_H #include <mythread.h> #include <QDialog> #include <QPushButton> #include <QPlainTextEdit> #include <QLabel> class MyDialog : public QDialog { Q_OBJECT private: QPushButton *_btnStart; QPushButton *_btnFinish; QPushButton *_btnClearInfo; QPlainTextEdit *_plainTextEdit; QLabel *_labStatus; QLabel *_labPicture; MyThread *_thread; protected: void closeEvent(QCloseEvent *event); public: MyDialog(QWidget *parent = nullptr); ~MyDialog(); void iniUI(); void iniSignalSlots(); private slots: void btnStartClicked(); void btnFinishClicked(); void btnClearInfoClicked(); void timesValueChanged(int times, int value); }; #endif // MYDIALOG_H
mydialog.cpp
#include "mydialog.h" #include <QHBoxLayout> #include <QVBoxLayout> #include <QGroupBox> #include <QPixmap> #include <QString> MyDialog::MyDialog(QWidget *parent) : QDialog(parent) { iniUI(); //创建线程 _thread = new MyThread(); iniSignalSlots(); } MyDialog::~MyDialog() { } // 初始化界面 void MyDialog::iniUI() { // 创建按钮 _btnStart = new QPushButton("启动游戏"); _btnFinish = new QPushButton("结束游戏"); _btnFinish->setEnabled(false); _btnClearInfo = new QPushButton("清空文本"); // 布局按钮 QHBoxLayout *layout1 = new QHBoxLayout(); layout1->addWidget(_btnStart); layout1->addWidget(_btnFinish); layout1->addWidget(_btnClearInfo); // 创建文本框和图片显示框 _plainTextEdit = new QPlainTextEdit(); _labPicture = new QLabel(); QPixmap pixmap; pixmap.load(":/images/d0.jpg"); _labPicture->setPixmap(pixmap); // 布局文本框和图片显示框 QHBoxLayout *layout2 = new QHBoxLayout(); layout2->addWidget(_plainTextEdit); layout2->addWidget(_labPicture); // 创建状态栏 _labStatus = new QLabel("游戏状态:未开始"); // 布局状态栏 QHBoxLayout *layout3 = new QHBoxLayout(); layout3->addWidget(_labStatus); // 创建分组框的布局 QVBoxLayout *layout4 = new QVBoxLayout(); layout4->addLayout(layout1); layout4->addLayout(layout2); layout4->addLayout(layout3); // 创建一个分组框 QGroupBox *groupBox = new QGroupBox("掷骰子"); groupBox->setLayout(layout4); // 创建整体布局 QHBoxLayout *layout5 = new QHBoxLayout(); layout5->addWidget(groupBox); // 设置整体布局 setLayout(layout5); resize(800, 600); } // 连接信号与槽 void MyDialog::iniSignalSlots() { connect(_btnStart, SIGNAL(clicked()), this, SLOT(btnStartClicked())); connect(_btnFinish, SIGNAL(clicked()), this, SLOT(btnFinishClicked())); connect(_btnClearInfo, SIGNAL(clicked()), this, SLOT(btnClearInfoClicked())); connect(_thread, SIGNAL(timesValueChanged(int, int)), this, SLOT(timesValueChanged(int, int))); } void MyDialog::btnStartClicked() { _labStatus->setText("游戏状态:进行中"); _thread->start(); _btnStart->setEnabled(false); _btnFinish->setEnabled(true); } void MyDialog::btnFinishClicked() { _labStatus->setText("游戏状态:未开始"); _thread->terminate(); _thread->wait(); _btnStart->setEnabled(true); _btnFinish->setEnabled(false); } void MyDialog::btnClearInfoClicked() { _plainTextEdit->clear(); } // 当用户点击开始游戏后,线程就启动了,当线程生成一个数字时,会发一个信号过来,这个槽函数接受信号做出响应 void MyDialog::timesValueChanged(int times, int value) { QString text = QString::asprintf("第%d次掷骰子,点数为:%d", times, value); _plainTextEdit->appendPlainText(text); QString filename = QString::asprintf(":/images/d%d.jpg", value); QPixmap pixmap; pixmap.load(filename); _labPicture->setPixmap(pixmap); // 给一个label设置图片 } void MyDialog::closeEvent(QCloseEvent *event) { if(_thread->isRunning()) // 如果线程还在继续执行,那么强行终止 { _thread->terminate(); _thread->wait(); } event->accept(); }
main.cpp
#include "mydialog.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MyDialog w; w.show(); return a.exec(); }
效果展示
以上是关于QThread创建多线程程序的主要内容,如果未能解决你的问题,请参考以下文章
Python Qt GUI设计:多线程中信号与槽的使用(基础篇—9)
QtConcurrent 与多线程 QThread 的多线程性能