建设网站推广文案,怎么制作网页快捷方式,wordpress主题制作价格,深圳高端网站制作价格目录 介绍 线程类 QThread 方式1
方式2
案例
线程资源释放 介绍
qt为多线程提供了完美的支持#xff0c;实现多线程一般是从从QTHread中继承定义自己的线程类#xff0c;QT也提供了QMutexLocker,QwaitCondition等类实现线程同步#xff0c;与Linux系统或C中的线程库类似…目录 介绍 线程类 QThread 方式1
方式2
案例
线程资源释放 介绍
qt为多线程提供了完美的支持实现多线程一般是从从QTHread中继承定义自己的线程类QT也提供了QMutexLocker,QwaitCondition等类实现线程同步与Linux系统或C中的线程库类似。这里简单介绍下多线程的创建。
默认的线程在Qt中称之为窗口线程也叫主线程负责窗口事件处理或者窗口控件数据的更新子线程负责后台的业务逻辑处理子线程中不能对窗口对象做任何操作这些事情需要交给窗口线程处理主线程和子线程之间如果要进行数据的传递需要使用Qt中的信号槽机制 线程类 QThread
常用API [virtual protected] void QThread::run();
run()是一个虚函数如果想让创建的子线程执行某个任务需要写一个子类让其继承QThread并且在子类中重写父类的run()方法函数体就是对应的任务处理流程当前线程对象调用槽函数start()启动子线程当子线程被启动这个run()函数也就在线程内部被调用了。
信号与槽函数 // 线程中执行的任务完成了, 发出该信号 [signal] void QThread::finished(); // 开始工作之前发出这个信号, 一般不使用 [signal] void QThread::started(); [slot] void QThread::quit(); // 启动子线程 [slot] void QThread::start(Priority priority InheritPriority); // 线程退出, 可能是会马上终止线程, 一般情况下不使用这个函数 [slot] void QThread::terminate(); 方式1
创建一个线程类的子类让其继承QT中的线程类 QThread重写父类的 run() 方法启动子线程, 调用 start() 方法。
举例
#ifndef MYTHREAD_H
#define MYTHREAD_H#include QObject
#includeQThreadclass MyThread : public QThread
{Q_OBJECT
public:explicit MyThread(QObject *parent nullptr);
protected:void run();
signals:void curNumber(int num);
};#endif // MYTHREAD_H#include mythread.h
#includeQDebug
MyThread::MyThread(QObject *parent)
{
}void MyThread::run()
{qDebug() 当前线程对象的地址: QThread::currentThread();int num 0;while(1){emit curNumber(num);//子线程每秒发出一次信号if(num 10000000){break;}QThread::usleep(1);}qDebug() run() 执行完毕, 子线程退出...;}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);qDebug() 主线程对象地址: QThread::currentThread();MyThread* mnew MyThread;connect(m, MyThread::curNumber, this, [](int num)//子线程每秒发出一次信号{ui-label-setNum(num);});connect(ui-pushButton, QPushButton::clicked, this, [](){// 启动子线程m -start();});
}MainWindow::~MainWindow()
{delete ui;
}方式2
创建一个新的类A让这个类从QObject派生,这个类中添加一个公共的成员函数来处理对应的任务在主线程中创建一个QThread对象在主线程中创建工作的类对象A不能指定父对象将对象A移动到创建的子线程对象中, 需要调用QObject类提供的moveToThread()方法启动子线程调用 start(), 这时候线程启动了, 但是移动到线程中的对象并没有工作调用MyWork类对象的工作函数让这个函数开始执行。
例如
#ifndef WORK_H
#define WORK_H
#include QObjectclass Work : public QObject
{Q_OBJECT
public:explicit Work(QObject *parent nullptr);void Working();
signals:void curNumber(int num);};
#endif // WORK_H#include work.h
#includeQDebug
#includeQThread
Work::Work(QObject *parent): QObject{parent}
{
}void Work::Working()
{qDebug() 当前线程对象的地址: QThread::currentThread();int num 0;while(1){emit curNumber(num);//子线程每秒发出一次信号if(num 10000000){break;}QThread::usleep(1);}qDebug() run() 执行完毕, 子线程退出...;
}MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);qDebug() 主线程对象地址: QThread::currentThread();QThread* sub new QThread;//创建线程对象Work* wnew Work; //创建工作对象该对象包含业务处理方法不要指定给创建的对象指定父对象w-moveToThread(sub); //将工作对象移动到子线程中sub-start();connect(ui-startBtn, QPushButton::clicked, w,Work::Working);// 显示数据connect(w, Work::curNumber, this, [](int num){ui-label-setNum(num);});
}
案例
在一个子线程程中随机生成1000个数将这些数据交给另一个子线程去排序后面将排序的结果返回给主线程主线程再将数据输出到窗口中。
这里采用方案1进行演示
生成随机数线程
class Genera : public QThread //该类来生成随机数
{Q_OBJECT
public:explicit Genera(QObject *parent nullptr);void getnum(int k);
protected:void run();//重写run方法生成随机数
private:int num_; //获取主线程传来的数据这里为生成随机数的个数signals:void sendnum(QVectorint v);//当随机数生成完后发射该信号将数据传给主线程和排序线程
};Genera::Genera(QObject *parent): QThread{parent}
{
}
void Genera::getnum(int k)
{num_k;
}
void Genera::run()
{qDebug()当前线程是 QThread::currentThread();QVectorint v;QElapsedTimer q;q.start();for(int i0;inum_;i){v.push_back(qrand()%10000);}int mq.elapsed();qDebug()生成随机的时间是 m;emit sendnum(v);}
排序线程
class BubbleSort : public QThread //该类来生成随机数
{Q_OBJECT
public:explicit BubbleSort(QObject *parent nullptr);void getnum(QVectorint);//获取生成随机数线程传来的数据
protected:void run();//进行排序
private:QVectorint v;signals:void Finish(QVectorint v);//排序完成后发射该信号将排序结果给主线程
};BubbleSort::BubbleSort(QObject *parent): QThread{parent}
{
}
void BubbleSort::getnum(QVectorint list)
{vlist;
}
void BubbleSort::run()
{qDebug()当前线程是 QThread::currentThread();QElapsedTimer q;q.start();for(int i0;iv.size();i){for(int j0;jv.size()-i-1;j){if(v[j]v[j1]){int tmpv[j1];v[j1]v[j];v[j]tmp;}}}int mq.elapsed();qDebug()排序的时间是 m;emit Finish(v);
}
主线程
class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent nullptr);~MainWindow();
signals:void starting(int num);//生成随机数的个数private:Ui::MainWindow *ui;
};
#endif // MAINWINDOW_HMainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui-setupUi(this);//创建子线程Genera * gnew Genera;//生成随机数BubbleSort* bnew BubbleSort;//排序connect(this,MainWindow::starting,g,Genera::getnum);//启动子线程connect(ui-pushButton,QPushButton::clicked,this,[](){emit starting(1000);//发射该信号,将生成随机数的个数传给子线程g-start();});connect(g,Genera::sendnum,b,BubbleSort::getnum);//排序线程接受生成随机数线程传来的数据//接受子线程传来的排序数connect(g,Genera::sendnum,this,[](QVectorint v){//说明随机生成数已生成好b-start();for(int i0;iv.size();i){ui-listWidget-addItem(QString::number(v.at(i)));}});connect(b,BubbleSort::Finish,this,[](QVectorint v){for(int i0;iv.size();i){ui-listWidget_2-addItem(QString::number(v.at(i)));}});
}MainWindow::~MainWindow()
{delete ui;
} 结果 线程资源释放
1.创建线程时给它指明父对象让其添加到对象树列表中。
2.手动释放调用quit,waitdelete:例如在上面的代码中new出来的时局部变量 connect(this,MainWindow::destroyed,this,[](){g-quit();g-wait();g-deleteLater();//类似与c中delete});