【为什么要用多线程?】
传统的图形用户界面应用程序都只有一个执行线程,并且一次只执行一个操作。如果用户从用户界面中调用一个比较耗时的操作,当该操作正在执行时,用户界面通常会冻结而不再响应。这个问题可以用事件处理和多线程来解决。
【使用多线程有什么好处?】
【Qt中创建线程的方法】
只需要子类化QThread并重新实现它的run()函数就可以了。run()是个纯虚函数,是线程执行的入口,在run()里出现的代码将会在另外线程中被执行。run()函数是通过start()函数来实现调用的。
【实例】
下面一个例子给出了在应用程序中除了主线程外,还提供了线程A和B。如果单击窗口中的按钮“Start A”,Qt的控制台就会连续输出字母“A”,此时按钮“Start A”被刷新为“Stop A”。再单击按钮“Start B”,控制台会交替输出字母“A”和“B”。如果再单击按钮“Stop A”,则控制台只输出字母“B”。如下图所示:
thread.h代码
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
#include <iostream>
class Thread : public QThread
{
Q_OBJECT
public:
Thread();
void setMessage(QString message);
void stop();
protected:
void run();
void printMessage();
private:
QString messageStr;
volatile bool stopped;
};
#endif // THREAD_H
注:
thread.cpp代码
#include "thread.h"
#include <QDebug>
Thread::Thread()
{
stopped = false;
}
void Thread::run()
{
while(!stopped)
{
printMessage();
}
stopped = false;
}
void Thread::stop()
{
stopped = true;
}
void Thread::setMessage(QString message)
{
messageStr = message;
}
void Thread::printMessage()
{
qDebug()<<messageStr;
sleep(1);
}
注:
threaddialog.h代码
#ifndef THREADDIALOG_H
#define THREADDIALOG_H
#include <QPushButton>
#include <QDialog>
#include <QCloseEvent>
#include "thread.h"
class ThreadDialog : public QDialog
{
Q_OBJECT
public:
ThreadDialog(QWidget *parent=0);
protected:
void closeEvent(QCloseEvent *event);
private slots:
void startOrStopThreadA();
void startOrStopThreadB();
void close();
private:
Thread threadA;
Thread threadB;
QPushButton *threadAButton;
QPushButton *threadBButton;
QPushButton *quitButton;
};
#endif // THREADDIALOG_H
threaddialog.cpp代码
#include "threaddialog.h"
ThreadDialog::ThreadDialog(QWidget *parent) : QDialog(parent)
{
threadA.setMessage("A");
threadB.setMessage("B");
threadAButton = new QPushButton(tr("Start A"), this);
threadAButton->setGeometry(10, 30, 80, 30);
threadBButton = new QPushButton(tr("Start B"),this);
threadBButton->setGeometry(110, 30, 80, 30);
quitButton = new QPushButton(tr("Quit"), this);
quitButton->setGeometry(210, 30, 80, 30);
quitButton->setDefault(true);
connect(threadAButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadA()));
connect(threadBButton, SIGNAL(clicked()), this, SLOT(startOrStopThreadB()));
connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
}
void ThreadDialog::startOrStopThreadA()
{
if(threadA.isRunning())
{
threadAButton->setText(tr("Stop A"));
threadA.stop();
threadAButton->setText(tr("Start A"));
}
else
{
threadAButton->setText(tr("Start A"));
threadA.start();
threadAButton->setText(tr("Stop A"));
}
}
void ThreadDialog::startOrStopThreadB()
{
if(threadB.isRunning())
{
threadBButton->setText(tr("Stop B"));
threadB.stop();
threadBButton->setText(tr("Strat B"));
}
else
{
threadBButton->setText(tr("Start B"));
threadB.start();
threadBButton->setText(tr("Stop B"));
}
}
void ThreadDialog::closeEvent(QCloseEvent *event)
{
threadA.stop();
threadB.stop();
threadA.wait();
threadB.wait();
event->accept();
}
void ThreadDialog::close()
{
exit(0);
}
注:
main.cpp代码
#include "threaddialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ThreadDialog *threaddialog = new ThreadDialog;
threaddialog->exec();
return app.exec();
}
注:
运行结果:
项目百度网盘瞎咋链接:
https://pan.baidu.com/s/1N-3NsA41R7Laq9cfSFc9Ew
提取码: 43rb