Qt编程中的信号和槽机制

在使用自定义类创建一个按钮之后,只能看到一个按钮的图形,但是使用鼠标点击并无任何反应,下面想要实现一个“点击按钮可以关闭窗口”的功能。

关闭窗口的功能可以被抽象为以下对象和操作,即:按钮,点击按钮,窗口,关闭窗口。在qt中使用connect实现这个过程。
connet(信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽))
信号槽的一个优点:松散耦合,即信号的发送端和接收端本身是没有关联的,通过connect连接,将两端耦合在一起。

// myself button
MyPushButton *myBtn = new MyPushButton;
myBtn->setText("mybtn");
myBtn->setParent(this);
myBtn->move(10, 0);
myBtn->resize(200, 100);// close the window
connect(myBtn, &QPushButton::clicked, this, &myWidget::close);
// 通过帮助文档查找按钮对应的信号 signals & slots

以上即 信号和槽 的简单功能演示。其中用到的信号和槽是父类中已经定义好的用来实现特定的功能,下面来实现自定义的信号和槽功能。过程为:跑完步,张三口渴拿起杯子喝水。新建一个类,在自动生成的类声明位置,可以看到其中包含放置自定义信号的位置,信号只需要声明,不需要实现,可以包含参数但不需要返回值。如下,信号就定义好了。

class Person : public QObject
{Q_OBJECT
public:explicit Person(QObject *parent = nullptr);signals:void thirsty();
};

接下来是实现接收方的槽函数,早期版本槽函数必须写在类中的特定位置,5.4版本之后也可以将槽函数写在public中。槽函数既需要声明又需要实现,返回值为void,同样可以传入参数。

class Cup : public QObject
{Q_OBJECT
public:explicit Cup(QObject *parent = nullptr);signals:public slots:void drink();  // 还需到源文件中去定义
};

此时将信号和槽连接起来还不能看到效果,是因为信号未触发,只有信号触发后,与该信号连接的槽才能做出反应。

void Widget::overRun()
{emit zhangsan->thirsty();
}

信号发出后,与之相连的槽做出反应。

zhangsan = new Person(this);
beizi = new Cup(this);
connect(zhangsan, &Person::thirsty, beizi, &Cup::drink);
overRun();

信号和槽都可以传入参数,可以根据需要分别对其进行重载。注意,引用重载后需要利用函数指针明确指向具体函数。

// class Person
signals:void thirsty(QString WaterName);// class Cup
public slots:void drink(QString WaterName);// cup 定义
void Cup::drink(QString Watername)
{qDebug() << "drink water, " << Watername;
}// widget 定义
void Widget::overRun()
{emit zhangsan->thirsty("Nongfu Water");
}void (Person:: *zhangsanSignal)(QString) = &Person::thirsty;
void (Cup:: *beiziSlots)(QString) = &Cup::drink;
connect(zhangsan, zhangsanSignal, beizi, beiziSlots);
overRun();

输出结果为:drink water, "Nongfu Water",可以看到Nongfu Water被引号引起来了,想要去掉引号可以这样做:

qDebug() << "drink water, " << Watername.toUtf8().data();
// toUtf8()将QString转化为QByteArray,再使用data()将其转化为 char *

上面的实现中张三想要喝水的信号是调用函数触发的,下面想通过点击按钮的方式触发张三喝水的动作。

void (Person:: *zhangsanSignal)(QString) = &Person::thirsty;
void (Cup:: *beiziSlots)(QString) = &Cup::drink;
connect(zhangsan, zhangsanSignal, beizi, beiziSlots);QPushButton *btn = new QPushButton("跑步结束", this);
btn->move(50, 50);
resize(300, 200);
connect(btn, &QPushButton::clicked, this, &Widget::overRun);

上面的实现中,相当于点击按钮后将信号传递给了widget下的槽函数overRun,也可以通过信号传递给信号的方式,点击按钮直接触发张三口渴的信号,如下:

void (Person:: *zhangsanSignal)(void) = &Person::thirsty;
void (Cup:: *beiziSlots)(void) = &Cup::drink;
connect(zhangsan, zhangsanSignal, beizi, beiziSlots);
connect(btn, &QPushButton::clicked, zhangsan, zhangsanSignal);

信号连接之后,也可以通过disconnect()断开连接,其参数与想要断开的连接中的参数相同,例如断开张三拿起杯子喝水的连接:

disconnect(zhangsan, zhangsanSignal, beizi, beiziSlots);

信号和槽要注意的几个点:
1、信号可以连接信号;
2、一个信号可以连接多个槽函数;
3、多个信号可以连接同一个槽函数;
4、信号和槽函数的参数需要一一对应;
5、在参数对应的前提下,信号的参数可以多于槽函数的参数个数。

补充:Qt4信号槽连接方式connect(zhangsan, SIGNAL(thirsty()), beizi, SLOT(drink()));,相对于更高版本,QT4连接参数直观,但编辑器不进行参数类型检测。因为QT4底层实现时相当于将thirsty()转化成字符串然后去搜索该函数,没有对字符串进行比较。

Qt编程中的信号和槽机制相关推荐

  1. Qt中的信号与槽机制解析

    注:要想使用Qt的核心机制信号与槽,就必须在类的私有数据区声明Q_OBJECT宏,然后会有moc编译器负责读取这个宏进行代码转化,从而使Qt这个特有的机制得到使用. 所谓信号槽,简单来说,就像是插销一 ...

  2. Qt多线程中的信号与槽

    文章目录 1 多线程中的信号与槽 2 对象的依附性 2.1 对象的依附性 2.2 开启线程事件循环 2.3 线程事件循环的结束 2.4 设计实例 3 信号与槽的连接方式 3.1 Qt::DirectC ...

  3. Qt静态函数中的信号和槽问题

    目录 介绍 Qt中的信号和槽 一般形式 当发送信号的地方为静态函数时 存在问题 解决方案 介绍 信号和插槽用于对象之间的通信.信号和插槽机制是Qt的一个核心特性,可能是与其他框架提供的特性最为不同的部 ...

  4. QT对象树、信号和槽机制

    文章目录 一 .对象树是什么? 二.信号和槽的基本概念 2.1 信号 2.2 槽 2.3 松散耦合 2.4 特点 三.示例 总结 一 .对象树是什么? 对象树是由父类和若干子类对象组成,而子类也可以由 ...

  5. Qt图形界面编程入门(信号和槽通信机制)

    信号和槽机制是Qt的核心机制,可以让编程人员将互不相关的对象绑定在一起,实现对象之间的通信. 声明了信号的对象,当其状态改变时,信号就由该对象发送出去,而且该对象只负责发送信号,它不知道另一端是谁在接 ...

  6. QT 的信号与槽机制介绍

    QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT ...

  7. qt学习之路3 ---信号与槽机制

    信号和槽机制 1.概述 Qt采用了一种全新的对象和方法的关联与通信机制,称为信号和槽机制.信号和槽机制是独立于标准C++编译器的,在编译之前需要经过Qt的专门预处理工具MOC(Meta Object ...

  8. 【qt】QT 的信号与槽机制

    QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT ...

  9. 【转载】QT 的信号与槽机制介绍

    QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 KDE 桌面环境就是建立在 QT ...

最新文章

  1. 人类未来将毁于元宇宙?刘慈欣向往星辰大海,小扎却要深耕Meta
  2. BZOJ1061 [NOI2008]志愿者招募
  3. Delphi-TScreen表示应用程序运行时屏幕的状态
  4. iphone如何使用CoreNFC
  5. mysql binlog sql统计_mysql的binlog详解
  6. Java中遍历删除ArrayList中多个元素
  7. 去快捷方式小箭头_电脑桌面如何快速去掉快捷方式小箭头
  8. RSA加密、解密、签名、校验签名
  9. 购买女装摩托车(踏板车)
  10. django的模板系统过滤器笔记
  11. Linux学习之chage命令
  12. java jtable 单元格合并_java 表格JTable中怎么样合并单元格
  13. 酒精传感器实验-传感器原理及应用实验
  14. Truecrypt之死
  15. php环境配置PHPWAMP
  16. 连点脚本java,按键精灵如何设置自动连续点击 自动连点脚本设置教程
  17. 武汉大学计算机学院csc,2018年春武汉大学CSC公派出国留学录取名单
  18. 【剖析 | SOFARPC 框架】系列之SOFARPC序列化比较
  19. nodejs 中读取 package.json 文件内容
  20. linux 批量下载fnl,TMS370C356FNL

热门文章

  1. 计算机专业实训报告总结
  2. Nginx的介绍与使用
  3. 深度学习概念——Epoch, Batch, Iteration
  4. 【MFC学习笔记】常见问题解答
  5. execv 函数的应用
  6. Python简单处理excel数据(拆分合并单元格、根据表头合并sheet、添加列数、添加内容操作)
  7. Java面向对象之女朋友类
  8. 新媒体短视频运营哪些内容
  9. matlab不同版本之间编码出错问题20200825
  10. SSD测试专题(三)