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月前
|
安全 编译器 开发者
【Qt 学习笔记】Qt信号和槽的其他说明及Lambda表达式
【Qt 学习笔记】Qt信号和槽的其他说明及Lambda表达式
74 0
|
1月前
|
安全 C++ Windows
Qt信号与槽机制
Qt信号与槽机制
20 1
|
2月前
|
安全
【进程通信】信号的捕捉原理&&用户态与内核态的区别
【进程通信】信号的捕捉原理&&用户态与内核态的区别
|
2月前
|
存储
【进程信号】信号阻塞的原理
【进程信号】信号阻塞的原理
|
11天前
|
C++
Qt信号和槽
Qt信号和槽
14 2
|
4天前
|
C++
Qt中的信号与槽如何学习?(包括自定义信号)这篇文章告诉你
以现实中的事件来举例的话,例如有两把不同颜色的信号枪,分别是红色,绿色,打响不通颜色的信号枪会触发不同的槽发生,比如说打响红色这个人就跑步,绿色就走步,但是还有一个很重要的机制,那就是连接,我们需要把信号枪去跟这个人的动作连接起来。 如果上面理解没问题的话我们可以把信号和槽看成两个工具,我们最重要的是如何去把这两个工具连接起来。 它的作用可以让我们更加灵活的去使用不同窗口间的切换以及某些事件的连接。
|
1月前
|
Linux Shell
蓝易云 - 【Linux-Day8- 进程替换和信号】
这两个概念在Linux系统编程和shell脚本编写中都非常重要,理解它们可以帮助你更好地理解和控制Linux系统的行为。
28 9
|
2月前
|
图形学 C++ 容器
QT信号与槽机制 和 常用控件介绍
QT信号与槽机制 和 常用控件介绍
QT信号与槽机制 和 常用控件介绍
|
11天前
|
Linux
【Linux】进程信号_1
【Linux】进程信号_1
7 0