Qt多个信号连接同一个槽的方法

    Qt的信号/槽机制给我们编程带来了很大的便利。在多数的情况下,我们只需要一个信号对应一个槽就可以了。但有时候我们也会遇到多个信号对应一个槽的情况。比如说做一个计算器的小程序,界面上有10个按钮分别对应0 - 9这几个数字。按下这几个按钮处理的逻辑是类似的,所以我们完全没有必要为每一个按钮都写一个槽来对应按钮按下的信号。但是假如我们把10个按钮的按下信号都连接到一个槽函数中,那么槽函数又要怎么区分此时按下的是哪个按钮呢?要知道按钮的按下信号是不带参数的。

    这时候QSignalMapper就能派生用场了。它可以将对象的信号转发一个槽函数中。那么具体该怎么使用呢?举个例子吧:

首先用QtCreator创建一个基于QWidget的程序,使用UI设计师在界面上拖6个按钮。

blob.png

接下来我们将使用QSignalMapper将这6个按钮的信号都连接到一个槽函数中。

  1. 创建QSignalMapper对象,并将它的mapped信号连接到一个槽函数中,这个槽就是我们用来处理6个按钮的地方。

blob.png  

mapped信号有4个不同参数的版本,根据需求自行选择。

blob.png

 2. 将QSignalMapper与按钮关联起来,使用QSignalMapper的setMapping函数。

blob.png

setMapping有4个重载函数,参数类型与mapped信号的参数一一对应。

blob.png

3. 将按钮的按下信号与QSignalMapper关联起来。前面做了那么多不就是为了信号连在一起吗。

blob.png

这一步将各个按钮的信号都连接到QSignalMapper的map()槽函数中。然后发射到第1步的slotSignalMap槽中。


4.在slotSignalMap处理

blob.png


由于我们在关联按钮和QSignalMapper时(setMapping)将按钮对象传入,在mapped信号触发时传给槽函数slotSignal。我们只需要把这个参数QWiget转换为QPushButton对象就自然知道此时按下的是哪个按钮了。效果如图:

blob.png


使用QSignalMapper可以帮我们解决信号转发的问题,不过感觉还是有点局限性,我们可以看到信号最终是通过QSignalMapper的mapped()转发出去的,如果我的QPushButton的两个不同的信号都用QSignalMapper转发会怎样呢?

blob.png


我们将第一个按钮的clicked和pressed两个信号都通过mSignalMapper转发出去,点击按钮打印出了两个"click:1"。

blob.png

说明两个信号都在同一个槽函数中处理了,这肯定不是我们想要的。我们既想要不同对象的同一个信号在同一个槽函数中处理,又不希望一个对象的不同信号在同一个槽函数中处理。怎么办?

    看来还需要sender()函数来帮忙了。通过在槽函数中调用sender()来获取信号的发送者。将上面的例子改一改,先定义一个slotClicked槽函数

blob.png

在槽函数中使用sender()获取此时槽函数对应的信号发送者,返回类型是QObject。  这样我们可以直接将不同对象的信号连接到同一个槽上,还能分清楚是谁触发的。

blob.png


看看运行效果:

blob.png

最后我们再添加一个slotPressed()槽函数,并让第一个按钮的pressed()信号连接该槽函数。

blob.png


    点击第一个按钮看看效果如何?

blob.png

可以看到pressed和clicked信号都触发了,而且两个信号在不同的槽函数中处理。 



测试环境:Qt5.9.4

演示站
上一篇:QGraphicsScene绘制背景图片引起的问题
下一篇:Qt封装的websocket了解一下

发表评论