首页 > 其他分享 >Qt 多线程中使用信号槽的示例

Qt 多线程中使用信号槽的示例

时间:2024-02-29 18:55:58浏览次数:30  
标签:csApplication 多线程 函数 示例 void 线程 include public 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工程,把mainwindow.h改成下面的代码

 1 // mainwindow.h#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 {
16     Q_OBJECT
17 public:
18     NetworkThread()
19     {
20         // do some initial works;
21     }
22 
23 signals:
24     void datacoming(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 {
39     Q_OBJECT
40 
41 public:
42     QPushButton *firstButton,*secondButton,*thirdButton;
43 
44     QVBoxLayout *layout;
45     QWidget *p;
46 
47 public:
48     explicit MyWidget(QWidget *parent);
49     ~MyWidget();
50 signals:
51     void signalTestStart(int a=0);
52     void startNetworkSleep();
53 
54 public slots:
55     void secondButtonClicked();
56 };
57 
58 // GUI class
59 
60 // csApplication class
61 
62 class csApplication:public QApplication
63 {
64     Q_OBJECT
65 
66 public:
67     csApplication(int argc,char *argv[]);
68 
69     MyWidget *mywindow;
70     NetworkThread *netthd;
71     QThread *t;
72 
73     ~csApplication();
74 
75 
76 };
77 
78 // csApplication class
79 
80 
81 #endif // MAINWINDOW_H

把main.cpp改成下面的代码,并删去mainwindow.cpp

  1 // main.cpp
  2 
  3 #include "mainwindow.h"
  4 
  5 
  6 
  7 // network thread
  8 
  9 void NetworkThread::testSlot()
 10 {
 11     std::cout<<"\nin testSlot()\n thread id:"<<std::this_thread::get_id()<<std::endl;
 12     memberFun();
 13 }
 14 
 15 void NetworkThread::memberFun()
 16 {
 17     std::cout<<"\nin NetworkThread::memberFun()\nthread id:"<<std::this_thread::get_id()<<"\n"<<std::endl;
 18 }
 19 
 20 void NetworkThread::sleepSlot()
 21 {
 22     std::cout<<"in NetworkThread::sleepSlot()\n thread id:"<<std::this_thread::get_id()<<"\nthen sleep 5 seconds\n";
 23     QThread::sleep(5);
 24     std::cout<<"sleepSlot() weak up\n"<<std::endl;
 25 }
 26 
 27 // network thread class
 28 
 29 // GUI class,run in main thread
 30 
 31 MyWidget::MyWidget(QWidget *parent=0)
 32 {
 33     firstButton = new QPushButton(tr("first"));
 34     secondButton = new QPushButton(tr("second"));
 35     thirdButton = new QPushButton(tr("third"));
 36 
 37     layout = new QVBoxLayout;
 38     layout->addWidget(firstButton);
 39     layout->addWidget(secondButton);
 40     layout->addWidget(thirdButton);
 41 
 42     p=new QWidget;
 43 
 44     p->setLayout(layout);
 45 
 46     setCentralWidget(p);
 47 
 48 }
 49 MyWidget::~MyWidget()
 50 {
 51     delete firstButton;
 52     delete secondButton;
 53     delete thirdButton;
 54     delete p;
 55     delete layout;
 56 }
 57 
 58 void MyWidget::secondButtonClicked()
 59 {
 60     emit startNetworkSleep();
 61     std::cout<<"in MyWidget::secondButtonClicked()\n thread id: "<<std::this_thread::get_id()<<"\n"<<std::endl;
 62 }
 63 
 64 // GUI class
 65 
 66 // csApplication class
 67 
 68 csApplication::csApplication(int argc, char *argv[]):QApplication(argc,argv)
 69 {
 70 
 71     std::cout<<"\nin csApplication()\nthread id:"<<std::this_thread::get_id()<<"\n"<<std::endl;
 72     mywindow = new MyWidget();
 73     netthd = new NetworkThread();
 74     t = new QThread();
 75 
 76     connect(mywindow->firstButton,SIGNAL(clicked()),netthd,SLOT(testSlot()),Qt::QueuedConnection);
 77     connect(mywindow->secondButton,SIGNAL(clicked()),mywindow,SLOT(secondButtonClicked()));
 78     connect(mywindow,SIGNAL(startNetworkSleep()),netthd,SLOT(sleepSlot()),Qt::QueuedConnection);
 79 
 80     netthd->moveToThread(t);
 81     t->start();
 82     mywindow->show();
 83 
 84 }
 85 csApplication::~csApplication()
 86 {
 87     delete mywindow;
 88     delete netthd;
 89     delete t;
 90 }
 91 
 92 // csApplication class
 93 
 94 
 95 int main(int argc, char *argv[])
 96 {
 97     csApplication a(argc, argv);
 98 
 99     return a.exec();
100 }

点击运行就可以了。

标签:csApplication,多线程,函数,示例,void,线程,include,public,Qt
From: https://www.cnblogs.com/ybqjymy/p/18045143

相关文章

  • C++ 多线程笔记1 线程的创建
    C++多线程笔记1线程的创建里面代码会用到的头文件#include<iostream>#include<string>#include<memory>#include<thread>#include<vector>#include<stdlib.h>#include<cmath>#include<chrono>#include<ctime>入门例子vo......
  • c++ queue在多线程中的使用
    queue队列,先进先出。多线程的一种使用案例:生产者每3spush一个元素消费者每5s才能pop一个元素(队首)那么,2个消费者就可以及时地消耗掉push的元素。#include<iostream>#include<thread>#include<mutex>#include<queue>std::queue<int>m_queue;std::mutexm_mutex;std:......
  • xss利用之盗取cookie示例
    实验环境目标网站:宿主机:192.168.10.1访问虚拟机win11:192.168.10.134伪造网站:192.168.10.12:100pikachu步骤一:受害者cookie:步骤二:输入xsspayload'"><script>document.location='http://192.168.10.12:100/pikachu/pkxss/xccokie/cookie.php?cookie='+doc......
  • VS Qt - cmake项目中添加运行时命令行参数
    1、VS在项目目录中找到.vs目录--->launch.vs.json{"version":"0.2.1","defaults":{},"configurations":[{"type":"default","project":"CMakeLists.txt",......
  • FastAPI系列 :安装启动及简单示例
    安装pip3installfastapipip3installuvicorn[standard]#是一个ASGI异步服务器网关接口服务器框架pip3installpython-multipart#处理表单参数的#完整安装pipinstallfastapi[all]启动程序#命令行启动uvicornmain:app--reload--host0.0.0.0--port8888......
  • OpenCV计数应用 c++(QT)
    一、前言为了挑战一下OpenCV的学习成果,最经一直在找各类项目进行实践。机缘巧合之下,得到了以下的需求:要求从以下图片中找出所有的近似矩形的点并计数,重叠点需要拆分单独计数。二、解题思路1.图片作二值化处理autoimage=cv::imread("points.jpg");cv::Matborder;//为......
  • c# winform 多线程
    ​  privateTaskSchedulermpr_ts_UIContext;    privatevoidbutton1_Click(objectsender,EventArgse)    {      progressBar1.Visible=true;      progressBar1.Value=0; //清空进度条      progress......
  • Qt 随机数生成器:QRandomGenerator
    一、描述QRandomGenerator可用于从高质量随机数生成器生成随机值。与C++随机引擎一样,QRandomGenerator可以通过构造函数使用用户提供的值作为种子。播种时,此类生成的数字序列是确定性的。也就是说,给定相同的种子数据,QRandomGenerator会生成相同的数字序列。给定不同的种......
  • Qt 生成随机数 qrand、QRandomGenerator
    //老方法//利用qrand和qsrand生成随机数//位于QtGlobal中//例,生成一个0和10之间的随机数1qsrand(QTime::currentTime().msec());//设置种子,该种子作为qrand生成随机数的起始值,RAND_MAX为32767,即随机数在种子值到32767之间2qrand()%10;//新方法//利用QRandomGenerator类......
  • Python scipy.ndimage.find_objects用法及代码示例
    用法scipy.ndimage.find_objects(input,max_label=0)在标记数组中查找对象。参数:input:整数数组包含由不同标签定义的对象的数组。值为0的标签将被忽略。max_label:整数,可选要在输入中搜索的最大标签。如果没有给出max_label,则返回所有对象的位置。object_slices:元组......