QT基础【7-跨进程发送信号】

简介: QT基础【7-跨进程发送信号】



1 跨进程发送信号

项目代码下载:提取码:ikun

其实与跨界面发送信号是一致的,只不过是发送信号的一方变成了进程

1.1 添加子进程类

  1. 选择C++ class

  1. 选择其父类为QThread(也可以自行在代码中继承QThread)

  1. 点击完成即可。

非基础类型数据的注册

此处我们要使用一个score结构体,要是没有注册,则会报错:

QObject::connect: Cannot queue arguments of type 'score'
(Make sure 'score' is registered using qRegisterMetaType().)

注册如下:

将score结构体注册,用score使用即可。注册的位置不固定,只需要在项目中即可。

qRegisterMetaType<score>("score");

TIP:string也属于非基础类型数据

string相关的问题

由于string是std中的,因此就算包含了#incude头文件,在使用时也要加上std,例如:

std::string
std::to_string(int index)

否则会报错:

代码

child_name.h

#include <QThread>]
#include<string>
struct score{
    int age;
    std::string name;
    int rate;
};
class child_name : public QThread
{
    Q_OBJECT //Q_OBJECT宏,使该类可以发送Qt信号
public:
    child_name();
signals:
    void send_index(score sc); //信号
protected:
    void run () override; //需要重写run方法
};

child_name.cpp

#include "child_name.h"
#include<stdlib.h>
#include<QDebug>
#include<string>
child_name::child_name() {}
void child_name::run(){
    while(1){
        //不间断的发送index,同时使index++
        score sc;
        sc.age = 13;
        sc.name="Tom";
        sc.rate = 100;
        emit this->send_index(sc);
        sleep(1); //每隔一秒发送
    }
}

Widget.h

#include <QWidget>
#include "child_name.h"
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void handle_send_index(score score); //处理信号的槽函数
    void connectFunc();//专门绑定各槽函数
    child_name *child; //让子进程成为自己的成员,便于操作
public slots:
    void on_start_btn_clicked(); //按钮按下的槽函数
private:
    Ui::Widget *ui;
};

Widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "child_name.h"
#include<QString>
#include<string>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    qRegisterMetaType<score>("score");
    ui->setupUi(this);
    connectFunc();
}
Widget::~Widget()
{
    delete ui;
}
void Widget::connectFunc(){
    //专门绑定各槽函数
    this->child = new child_name();
    connect(child,&child_name::send_index,this,&Widget::handle_send_index);
}
void Widget::handle_send_index(score sc){
    std::string str = "name: "+sc.name+"age: "+std::to_string(sc.age)+"rate: "+std::to_string(sc.rate);
    QString info = "index: "+QString::number(this->index++)+QString::fromStdString(str); //将int型转化为QString类型
    this->ui->dispInfo->clear(); //清除原有内容
    this->ui->dispInfo->setText(info);
}
void Widget::on_start_btn_clicked(){
    this->child->start(); //开始运行子进程
}

1.2 槽函数参数和信号参数的关系

Qt槽函数的参数需要和信号的参数保持一致,可以比信号的参数少,但是不能顺序不同,也不能比信号的参数多。

否则就会报错:

1.3 重名信号的处理

例如,QCOmboBox里面的currentIndexChanged有两个重载的版本,而我们在使用QT5的connect时是只写函数名的,因此此时编译器会报错。

若要处理,则使用Qt4的版本,因为它必须要指明参数的类型。例如

connect(this->ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(handle_index_change(int));

此外,还可以采用泛型编程的思想:

connect(ui->comboBox, Q0verload<int>::of(&0comboBox::currentIndexchanged),this,&Widget::onIndex);

此时,QOverload的数据类型为int,则此时currentIndexChanged函数中参数列表就是int型的。反之,为QOverload<const QString&>时则函数参数列表为const QString&类型

1.4 connect函数

connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender //发送者的指针
Func1 signal, //信号
const QObject *contexct  //接收者的指针
Func2 slot, //槽函数
Qt::ConnectionType type = Qt::AutoConnection) //连接的类型默认为AutoConection

连接方式是枚举型,有以下几种连接方式:

enum ConnectionType {
        AutoConnection,
        DirectConnection,
        QueuedConnection,
        BlockingQueuedConnection,
        UniqueConnection =  0x80
    };

AutoConnection:默认的连接方式,如果接收方在发出信号的线程中,使用Qt::DirectConnection;否则使用Qt::Queuedconnection。使用这种方式,Qt在发出信号时确定连接类型。在Qt中默认是用的AutoConnection,所以平时写信号槽时都是4个参数。

DirectConnection:当发出信号时,插槽立即被调果难槽在发送信易的线程中执行。

QueuedConnection:当控制返回到接收方线程的事件循环时调用槽,槽在接收方的线程中执行。

BlockingQueuedConnection:与Qt::QueuedConnection相同,只是发送信号的线程会阻,直到返回如果接收方存在于发送信号的线程中,则不能使用此连接,否则应用程序将死锁。

UniqueConnection:这是一个可以使用按位OR与上述任何一种连接类型组合的标志,当Qt::UniqueConnection被设置时,如果连接已经存在,QObject::connect()将失败(例如,如果相同的信号已经连接到相同的对象对的插槽)。

2 总结

在代码的舞台上翩翩起舞, Qt,如诗如画,编织梦的彩虹。

跨越平台的轻盈舞姿, 文档的琴音,灵感的涟漪。

模块的花瓣,细腻而丰满, 开发者的心灵,在那里盛开。

清新而深邃,如林中明月, Qt,用优雅的笔触,谱写未来的篇章。

渴望挑战Qt的学习路径和掌握进阶技术?不妨点击下方链接,一同探讨更多Qt的奇迹吧。我们推出了引领趋势的💻QT专栏:《QT从基础到进阶》 ,旨在深度探索Qt的实际应用和创新。🌐🔍

相关文章
|
2月前
|
编译器
(9)Qt中信号与槽重载的解决方案
本文介绍了在Qt中处理信号与槽重载问题的三种解决方案:使用函数指针、Qt提供的QOverload类和Qt4的宏方式。
161 3
|
2月前
(8)Qt中的自定义信号
本文介绍了如何在Qt框架中创建和使用自定义信号,并通过一个父子窗口切换的示例来展示自定义信号的实现和应用。
104 3
(8)Qt中的自定义信号
|
6天前
|
传感器 安全
第四问:QT中信号和槽原理
Qt的信号与槽机制是观察者模式的典型实现,允许对象间通信而不直接依赖。信号用于通知事件发生,槽是响应信号的函数,通过`QObject::connect()`连接。这种机制实现了松耦合、灵活扩展和自动通知,适用于UI更新和数据绑定等场景。
23 1
|
1月前
|
C++
003 Qt_信号和槽-上
本文介绍了Qt中的信号与槽机制,包括信号和槽的概念、本质及连接方法,并演示了如何自定义槽函数。信号是事件的体现,槽是对信号的响应函数。通过信号与槽,可以将独立的控件关联起来,实现复杂的交互逻辑。文中还详细展示了如何在Qt项目中定义和使用槽函数,通过实例代码和图形化界面操作,帮助读者更好地理解和应用这一机制。
55 1
003 Qt_信号和槽-上
|
3月前
|
Linux C语言
C语言 多进程编程(四)定时器信号和子进程退出信号
本文详细介绍了Linux系统中的定时器信号及其相关函数。首先,文章解释了`SIGALRM`信号的作用及应用场景,包括计时器、超时重试和定时任务等。接着介绍了`alarm()`函数,展示了如何设置定时器以及其局限性。随后探讨了`setitimer()`函数,比较了它与`alarm()`的不同之处,包括定时器类型、精度和支持的定时器数量等方面。最后,文章讲解了子进程退出时如何利用`SIGCHLD`信号,提供了示例代码展示如何处理子进程退出信号,避免僵尸进程问题。
|
3月前
|
NoSQL
gdb中获取进程收到的最近一个信号的信息
gdb中获取进程收到的最近一个信号的信息
|
4月前
|
程序员 C++
【Qt】信号与槽(下)
【Qt】信号与槽(下)
|
4月前
|
Linux C++
【Qt】信号与槽(上)
【Qt】信号与槽(上)
【Qt】信号与槽(上)
|
5月前
|
弹性计算 DataWorks 关系型数据库
DataWorks操作报错合集之DataX在执行过程中接收到了意外的信号15,导致进程被终止,该怎么处理
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
4月前
【qt】有点意思的信号与槽
【qt】有点意思的信号与槽
24 0