在遇到多信号问题的时候,你是否经常会连接多个槽函数呢?如果你的答案是绝对的,那么你已经Out很久了。多信号连接多个槽,实现不同的槽就在潜意识的加大程序的开销!那么为什么不去链接同一个槽呢?

    今天在次写下这篇文章,感觉有些唐突,但是又不得不写!因为信号与槽是Qt里面的最基础而且是最重要的部分,有很多人问过我关于信号与槽的问题,就总结一下。Qt主要包括:Qt基础部分(Qt入门、Qt对话框、Qt窗口、自定义窗口部件)、Qt中级(布局管理、事件处理、二维绘图、容器、数据库、多线程、网络等)、Qt高级(国际化、自定义样式、三维绘图、创建插件、嵌入式编程等)。

Qt5之前,信号与槽的连接方式看起来会是这样的:
connect(sender, SIGNAL(signal), receiver, SLOT(slot));
Qt5开始:
connect(sender, &Sender::signal, receiver, &Receiver::slot);

    前者:
    sender和receiver是指向QObject的指针,signal和slot是不带参数的函数名。SIGNAL()宏和SLOT()宏会把他们的参数转换成相应的字符串。
    后者:
    (1)编译器,检查信号与槽是否存在,参数类型检查,Q_OBJECT宏是否存在
    (2)信号可以和普通函数、类的普通成员函数、lambda函数连接(不在局限于信号和槽函数)
    (3)参数可以是typedef的或者使用不同的namespace specifier
    (4)可以允许一些自动类型的转换(即信号和槽函数类型不必完全匹配)
1、一个信号连接一个槽
    
connect(slider, &QSlider::valueChanged, spin_box, &QSpinBox::setValue);
2、一个信号连接多个槽
    connect(slider, &QSlider::valueChanged, spin_box, &QSpinBox::setValue);
    connect(slider, &QSlider::valueChanged, this, &QWidget::showValue);
3、多个信号连接同一个槽
    connect(push_button, &QPushButton::clicked, this, &QWidget::show);
    connect(tool_button, &QToolButton::clicked, this, &
QWidget
::
show
);
4、一个信号连接另一个信号
    
connect(push_button, &QPushlButton::clicked, this, &
QWidget
::
buttonClicked
);
5、连接被移除
    disconnect(
push_button
); //断开push_button的所有连接
    disconnect(
push_button, &QPushButton::clicked, this, &QWidget::show
); //断开此信号连接的槽

好了,这些都是最基本的应用。那么多个信号连接同一个槽的时候如何进行区分呢?
方法一:
typedef enum{
BUTTON_1,
BUTTON_2,
BUTTON_3,
BUTTON_4
}BUTTON;

 push_button_1->setObjectName(QString::number(
BUTTON_1, 10
));
 
push_button_2
->setObjectName(QString::number(
BUTTON_2
, 10
));
 
tool_button_1
->setObjectName(QString::number(
BUTTON_3
, 10
));
 
tool_button
_2
->setObjectName(QString::number(
BUTTON_4
, 10
));
 connect(push_button_1, &QPushButton::clicked, this, &MyWidget::changeButton);
 connect(push_button_2, &QPushButton::clicked, this, &
MyWidget
::
changeButton
);
 connect(tool_button_1, &QToolButton::clicked, this, &
MyWidget
::changeButton);
 connect(
tool_button
_2, &
QToolButton
::clicked, this, &
MyWidget
::
changeButton
);


void 
MyWidget::
changeButton()
{
    QObject *object = QObject::sender();
    QPushButton *push_button = qobject_cast(object);
    
QToolButton *tool_button = qobject_cast<</span>QToolButton  *>(object);
    
int index;
    if(
push_button
)
    {
        QString object_name = push_button->objectName();
        index = object_name.toInt();
    }
    else if(
tool_button
 
)
    {
        
 
QString object_name = 
tool_button
->objectName();
         index = object_name.toInt();
    }

    QString information = QString("");
    switch(index)
    {
    case 
BUTTON_1:
        
information = QString("clicked 1");
        break;

    case 
BUTTON_2:
       
 
information = QString("clicked 2");
        break;

    case 
BUTTON_3:
        
information = QString("clicked 3");
        break;

    case 
BUTTON_4:
        
information = QString("clicked 4");
        break;

    default:
        information = QString("which is clicked?");
        break;

    }
    QMessageBox::information(NULL, QString("Title"), 
information
);
}
    当然,
setObjectName不是专门用来干这事的,也可以使用text进行区分或者其它方法,这里介绍的只是一种思路而已!

方法二:
    
QSignalMapper
类可以简单的理解为
信号的翻译和转发器, 它可以把一个无参数的信号翻译成带
int
参数、
QString
参数、
QObject*
参数或者
QWidget*
参数的信号,并将之转发。 
QSignalMapper *signal_mapper = new QSignalMapper(this);
connect(
push_button_1, 
&QPushButton::clicked, signal_mapper, &
QSignalMapper::map);
connect(
push_button_2, 
&QPushButton::clicked, signal_mapper, 
&
QSignalMapper::
map);
connect(
tool_button_1, 
&QToolButton::clicked, signal_mapper, 
&
QSignalMapper::
map);
connect(
tool_button_2, 
&
QToolButton
::clicked, signal_mapper, 
&
QSignalMapper::
map);

signal_mapper->setMapping(
push_button_1, 
QString::number(
BUTTON_1, 10
));
signal_mapper->setMapping(
push_button_2, 
QString::number(
BUTTON_2, 10
));
signal_mapper->setMapping(
tool_button_1, 
QString::number(
BUTTON_3, 10
));
signal_mapper->setMapping(
tool_button_2, 
QString::number(
BUTTON_4, 10
));
connect(signal_mapper, 
&
QSignalMapper::mapped, this, 
&
MyWidget
::
changeButton);


void 
MyWidget::
changeButton(
QString text
)
{
    int index = 
text
.toInt();
    QString information = QString("");
    switch(index)
    {
    case 
BUTTON_1:
        
information = QString("clicked 1");
        break;

    case 
BUTTON_2:
       
 
information = QString("clicked 2");
        break;

    case 
BUTTON_3:
        
information = QString("clicked 3");
        break;

    case 
BUTTON_4:
        
information = QString("clicked 4");
        break;

    default:
        information = QString("which is clicked?");
        break;

    }
    QMessageBox::information(NULL, QString("Title"), 
information
);
}


    那么,同一信号连接多个槽呢,槽函数执行没有绝对的先后顺序。
如:
connect(slider, &QSlider::valueChanged, spin_box, &QSpinBox::setValue);
connect(slider, &QSlider::valueChanged, this, &QWidget::showValue);

valueChanged信号发送时,并不是说
setValue一定会比
showValue先执行。
    总结就到这里,很多东西书上说的都很明白,都是很常用,多注意细节部分,编程里就可以很轻松的实现write less,do more。。。

Qt之信号连接,你Out了吗?的更多相关文章

  1. PyQt(Python+Qt)学习随笔:调用disconnect进行信号连接断开时的信号签名与断开参数的匹配要求

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在使用信号调用disconnect()方法断开信号和槽的连接时,信号可以带签名也可不带签名,参数可以 ...

  2. qt中信号与槽机制

    一. 简介 就我个人来理解,信号槽机制与Windows下消息机制类似,消息机制是基于回调函数,Qt中用信号与槽来代替函数指针,使程序更安全简洁. 信号和槽机制是 Qt 的核心机制,可以让编程人员将互不 ...

  3. QT 的信号与槽

    转载: QT 的信号与槽机制介绍 QT 是一个跨平台的 C++ GUI 应用构架,它提供了丰富的窗口部件集,具有面向对象.易于扩展.真正的组件编程等特点,更为引人注目的是目前 Linux 上最为流行的 ...

  4. C++11实现Qt的信号槽机制

    概述 Qt的信号槽机制是Qt的核心机制,按钮点击的响应.线程间通信等都是通过信号槽来实现的,boost里也有信号槽,但和Qt提供的使用接口很不一样,本文主要是用C++11来实现一个简单的信号槽,该信号 ...

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

      信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工具以及在实际使用过程中应注意的一些问题. QT是一个跨平台的C++ GUI应用构架,它提供了丰富的窗 ...

  6. Qt 的信号与槽机制介绍(10个要注意的问题)

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

  7. C++框架_之Qt的信号和槽的详解

    C++_之Qt的信号和槽的详解 1.概述 信号槽是 Qt 框架引以为豪的机制之一.所谓信号槽,实际就是观察者模式.当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal ...

  8. Qt学习记录--02 Qt的信号槽机制介绍(含Qt5与Qt4的差异对比)

    一 闲谈: 熟悉Window下编程的小伙伴们,对其消息机制并不陌生, 话说:一切皆消息.它可以很方便实现不同窗体之间的通信,然而MFC库将很多底层的消息都屏蔽了,尽管使用户更加方便.简易地处理消息,但 ...

  9. qt多线程信号槽传输方式

    //简单介绍一下QT信号与槽的连接方式:    //Qt::AutoConnection表示系统自动选择相应的连接方式,如果信号与槽在同一线程,就采用Qt::DirectConnection, //如 ...

随机推荐

  1. centos 开启apache rewrite模式

    mod_rewrite能使网页伪静态,对于搜索引擎友好,下面就是开启这个功能的说明!启用mod_rewrite模块在conf目录的httpd.conf文件中找到 LoadModule rewrite_ ...

  2. iOS开发——C篇&预处理

    其实在C语言的远行过程中,有这样一个流程, 编译:C----〉可执行文件(可以运行的) 1:.C------.i 预处理(之前和之后还是C语法)2: .i-------.s 编译(之前是C语法,之后是 ...

  3. Iterator pattern(c++实现)

    概述: 在现在的电视机中,我们使用[后一个]和[前一个]按钮可以很方便的换台,当按下[后一个]按钮时,将切换到下一个预置的频道.想象一下在陌生的城市中的旅店中看电视.当改变频道时,重要的不是几频道,而 ...

  4. 交叉编译环境以及开发板上-/bin/sh: ./hello: not found(使用arm-linux-gcc -static -o 来进行静态编译)

    目标板是S3C2440.至于交叉编译环境的搭建就不多说了,网上很多教程. 搭建好了交叉编译环境后,第一件事就是传说中的”Hello,World!”. 一. 主机编译环节 我使用的系统是ubuntu10 ...

  5. 【转】android如何查看cpu的占用率和内存泄漏

    原文网址:http://www.cnblogs.com/yejiurui/p/3472765.html 在分析内存优化的过程中,其中一个最重要的是我们如何查看cpu的占用率和内存的占用率呢,这在一定程 ...

  6. linux下so动态库一些不为人知的秘密

    linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.    基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些 ...

  7. [Android开发常见问题-14] Unexpected namespace prefix "abc" found for tag SomeThing

    很多开发者朋友可能会自己定义一些控件,以此来扩展现有控件的功能,在扩展空间的时候通常会自己定义一些属性,例如: [html]  view plain copy   <android.alex.v ...

  8. Linux下查看显卡型号

    查看显卡使用 lspci |grep VGAemos@emos-desktop:~$ lspci -vnn | grep -i vga00:02.0 VGA compatible controller ...

  9. Java基础知识强化51:经典排序之桶排序(BucketSort)

    1. 首先说明三点: (1)桶排序是稳定的 (2)桶排序是常见排序里最快的一种,比快排还要快…大多数情况下 (3)桶排序非常快,但是同时也非常耗空间,基本上是最耗空间的一种排序算法 2. 桶排序的分析 ...

  10. yum安装于卸载软件常见命令

    1.使用yum安装和卸载软件,有个前提是yum安装的软件包都是rpm格式的. 安装的命令是,yuminstall ~,yum会查询数据库,有无这一软件包,如果有,则检查其依赖冲突关系,如果没有依赖冲突 ...