Qt 多线程中使用信号槽的示例
之前对线程理解得不深入,所以对Qt的线程机制没有搞清楚,今天写一篇文章总结一下,如有错误,欢迎指出。
首先需要理解线程是什么,线程在代码中的表现其实就是一个函数,只不过这个函数和主线程的函数同时运行,写C语言的都知道,一般代码是从main()函数开始运行的,每个线程都有一个入口函数,main()函数可以看做是主线程的入口函数,从main函数开始执行,主线程就开始了,写过一点代码的都知道,程序是从main()函数开始一条一条地往下执行的,但是有的时候我们需要同时执行A,B两个函数。初学代码时,都是先调用A函数,再调用B函数,这时是A函数执行完毕后再执行B函数,没有达到我们想要同时执行的目的。这时如果把A函数放入另一个线程中执行,那么不需要等到A函数执行完毕,B函数就可以开始执行。C++11中已经有了多线程库,简单示例如下
1 std::thread t(A); 2 B();你可以随便写两个函数,函数名为A,B。函数内容可以写成输出10000次A(B函数可以输出10000次B,输出次数少了可能会观察不到),你可能会发现A和B会交替出现,这就是A和B在同时执行的证明。多线程在图形界面程序中几乎是必须的,图形界面程序的主线程一般是界面线程,用于响应用户的操作,后台线程用于执行计算,通信等操作,如果不使用多线程,图形界面会因为等待计算数据(当然我说的是大量数据,少量数据你可能会感受不到)而卡住不响应用户的操作。讲到这里你也许对线程有了一个基本的印象。
Qt使用QThread类有两种方式,这个网上可以找到很多资料。
第一种:继承QThread类,自己写一个类(假设为MyThread),重写QThread的run()函数,新线程就会运行run()里面的代码,但是要注意的是只有run()函数里面的代码在新线程里运行,所以你自己的MyThread类里面的槽函数虽然和主线程的信号绑定了,但是只要没有放在run()里面运行,还是运行在主线程中的。
第二种:使用moveToThread(),我下面的示例代码就是使用的moveToThread()方法。QThrad中默认的run()函数启用了事件循环(exec()),所以你移动到线程中的那个对象的所有槽函数均在新线程中执行,不会阻塞主线程。看完示例就明白了。新建一个QApplication工程,把mainwindoh改成下面的代码
1 // mainwindoh#ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 #include <QApplication> 4 #include <QObject> 5 #include <QEvent> 6 #include <thread> 7 #include <iostream> 8 #include <QThread> 9 #include <QPushButton> 10 #include <QVBoxLayout> 11 #include <QMainWindow> 12 13 // network thread 14 class NetworkThread:public QObject 15 22 23 signals: 24 void datacing(int a); 25 26 private: 27 void memberFun(); 28 29 public slots: 30 void testSlot(); 31 void sleepSlot(); 32 }; 33 // network thread class 34 35 // GUI class,run in main thread 36 37 class MyWidget:public QMainWindow 38 ; 57 58 // GUI class 59 60 // csApplication class 61 62 class csApplication:public QApplication ; 77 78 // csApplication class 79 80 81 #endif // MAINWINDOW_H把mainpp改成下面的代码,并删去mainwindocpp
1 // mainpp 2 3 #include "mainwindoh" 4 5 6 7 // network thread 8 9 void NetworkThread::testSlot() 10 14 15 void NetworkThread::memberFun() 16 19 20 void NetworkThread::sleepSlot() 21 26 27 // network thread class 28 29 // GUI class,run in main thread 30 31 MyWidget::MyWidget(QWidget *parent=0) 32 49 MyWidget::~MyWidget() 50 57 58 void MyWidget::secondButtonClicked() 59 64 // GUI class 65 66 // csApplication class 67 68 csApplication::csApplication(int argc, char *argv[]):QApplication(argc,argv) 69 85 csApplication::~csApplication() 86 91 92 // csApplication class 93 94 95 int main(int argc, char *argv[]) 96点击运行就可以了。
下一篇:Windows11上启用远程桌面?4种方法看完你就会了!
Qt