当前位置: 首页 > news >正文

Qt信号与槽

        在 GUI 用户界面里,当用户对某个窗口部件进行操作时,往往需要其他窗口部件作出响应。传统做法通常借助 callback(回调机制)达成这一目的。回调机制是指预先把函数指针当作参数传递给另一个函数,随后在函数处理流程的恰当位置调用该回调函数。不过,回调机制存在两大明显缺陷:其一,类型不安全,无法确保在调用函数期间使用正确的参数;其二,强耦合,处理函数必须明确知晓要调用哪个回调函数。

        与之相比,Qt 的信号与槽机制具备类型安全、松耦合的特点,使用起来更为灵活、便捷。信号与槽(Signal & Slot)不仅是 Qt 编程的基石,更是 Qt 的一项重大创新。得益于信号与槽这一编程机制,在 Qt 中处理界面各组件间的交互操作变得更加直观、简易。

1.信号

        信号(Signal)本质上是在特定情形下被触发的事件。以 PushButton 为例,其最常见的信号便是在鼠标单击时发射的 clicked() 信号。在 Qt 里,发射信号需使用 emit 关键字。而 signals 关键字则用于标识进入信号声明区域,此后便可以声明自定义的信号。 

        定义信号,信号无需实现

signals:void A(QString & str); //信号不能也不需要实现

        发射信号:

QString str = "迪迦好帅!"
emit A(str); //emit关键字发射信号

2.槽函数 

           槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的 C++函数是一样的,可以声明在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
        声明1个槽方法,如:

private slots:void printStr(QString & str);

        槽方法的实现:

void  MainWindow :: printStr(QString &str)
{qDebug()<<str;
}

3.信号与槽关联 

        GUI 程序设计的核心在于处理界面组件的信号响应,只要清楚何时发射何种信号,并合理地响应和处理这些信号就行。

        信号与槽的连接实现        

        信号与槽的关联通过 `QObject::connect()` 函数达成,其原型如下:

QMetaObject::Connection QObject::connect(const QObject *sender,  // 信号发送者const char *signal,     // 发送的信号const QObject *receiver, // 信号接收者const char *method,     // 与信号连接的方式,可为槽或信号Qt::ConnectionType type = Qt::AutoConnection // 连接方式,默认自动连接
);

        常用格式为:`connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));`。这里使用 `SIGNAL` 和 `SLOT` 两个宏来构造表示信号和槽的字符串,将函数原型用它们包裹起来。注意,使用这种方式时函数原型只能写类型,不能有参数名,否则连接会失败。

        信号与槽的连接方式

        1. Qt::AutoConnection:默认方式,由系统自动选择合适的连接方式。
        2. Qt::DirectConnection:直接方式,信号发射时马上调用槽函数。
        3. Qt::QueuedConnection:队列方式,信号发射后产生一个事件进入队列,事件被处理时才调用槽函数。
        4. Qt::BlockQueuedConnection:阻塞队列方式,信号发射产生事件进入队列,当前线程会阻塞,直到事件处理完。若接收方和发送方在同一线程,程序会出现死锁,所以该方式仅用于多线程。

        信号与槽的参数及其他注意事项

        信号:可看作特殊函数,要带括号,能有参数,无需也不能实现。
        槽函数:要带括号,有参数时需指明参数类型。
        参数匹配:在 `connect()` 函数里写明参数类型,信号参数要和槽参数列表一致,允许信号参数比槽参数多。若不匹配或参数过少,会导致编译或运行错误。
        Q_OBJECT宏:使用信号与槽的类,其定义中必须加入 `Q_OBJECT` 宏。
        执行顺序:信号发射时,关联的槽函数通常立即执行,如同正常调用函数。只有所有关联槽函数执行完,才会执行发射信号处后面的代码。 

        信号与槽关联特点

        

        

        1 一个信号连接一个槽:

                connect(sender, SIGNAL(single1()), receiver, SLOT(slotFun()));

        2 一个信号连接一个信号:

                connect(sender, SIGNAL(single1()), receiver, SIGNAL(single2()));

        3 一个信号连接多个槽,关联信号的槽函数按照建立连接时的顺序依次执行:

                connect(sender, SIGNAL(single1()), receiver1, SLOT(slotFun()));

                connect(sender, SIGNAL(single1()), receiver2, SLOT(slotFun()));

                connect(sender, SIGNAL(single1()), receiver3, SLOT(slotFun()));

        4 多个信号连接一个槽:

                connect(sender1, SIGNAL(single1()), receiver, SLOT(slotFun()));

                connect(sender2, SIGNAL(single2()), receiver, SLOT(slotFun()));

                connect(sender3, SIGNAL(single3()), receiver, SLOT(slotFun()));

        5 信号与槽的自动关联:

        ui_xxxx.h 文件中 connectSlotsByName()方法通过对象名支持信号与槽的自动关联。不采用 connect()函数而是采用 on_objectName_signal 命名方式命名槽达到自动关联的效果。


http://www.mrgr.cn/news/98875.html

相关文章:

  • golang处理时间的包time一次性全面了解
  • uniapp-商城-26-vuex 使用流程
  • 强化学习算法系列(五):最主流的算法框架——Actor-Critic算法框架
  • Ubuntu源码制作openssh 9.9p2 deb二进制包修复安全漏洞 —— 筑梦之路
  • Rust 中的Relaxed 内存指令重排演示:X=0 Y=0 是怎么出现的?
  • 抽象的https原理简介
  • SQL刷题记录贴
  • 机器学习 | 细说Deep Q-Network(DQN)
  • 【Python爬虫基础篇】--1.基础概念
  • git撤销提交
  • C++面试
  • 定制化 Docsify 文档框架实战分享
  • 常见的服务器硬盘接口
  • HTTP/1.1 队头堵塞问题
  • 消息中间件——RocketMQ(一)
  • nodejs使用pkg打包文件
  • 面试题之数据库-mysql高阶及业务场景设计
  • 论文阅读VACE: All-in-One Video Creation and Editing
  • 【Python】用Python写一个俄罗斯方块玩玩
  • ubuntu24.04离线安装deb格式的mysql-community-8.4.4