详解Qt中connect()函数

07-13 1797阅读

一、基本概念

        要想了解connect() 函数,要先知道在Qt中什么是什么是信号(SIGNAL)和槽(SLOT)。

        信号(SIGNAL):指在特定情况下发射的通知。比如当我们点击了用户界面的一个按钮之后就发射了一个信号。

        槽(SLOT):是指对信号进行响应的函数。也就是我们点击了一个按钮后我们要实现的功能。

        那么connect() 函数就是Qt 框架中用于将信号(SIGNAL)和槽(SLOT)关联起来的核心函数。

二、用法

1.旧版用法(Qt4和早期Qt5)

connect(sender, SIGNAL(signalName()), receiver, SLOT(slotName()));
  • sender:发射信号的对象名称
  • signalName():信号名称
  • receiver:接收信号的对象名称,一般情况下为槽函数所属对象,写this即可
  • slotName():槽函数名称

    示例: 

    connect(button, SIGNAL(clicked()), this, SLOT(handleButtonClicked()));
    

    注意: 如果信号与槽函数带参数还需要在函数括号内标出。

    2.新版用法(推荐)

    connect(sender, &SenderClass::signalName, receiver, &ReceiverClass::slotName);
    

             这里引入了基于函数指针的语法,使得编译器可以进行更好的类型检查。但是这里有一个问题:与旧版的写法不同的是,信号与槽函数的参数怎么办?

            首先我们知道,在 Qt 的信号与槽机制中,槽函数的参数不能多于信号的参数。也就是说,信号的参数可以多于槽的参数,且槽函数的参数必须是信号参数的一个子集。那么就可以分为如下三种情况:

            1.信号和槽函数具有相同数量和类型的参数。这时可以直接连接且无需出现函数参数:

    connect(lineEdit, &QLineEdit::textChanged, this, &Widget::do_textChanged);
    

    在上面示例中,信号textChanged(QString)和槽函数do_textChanged(QString)参数相同。

            2.信号的参数多于槽函数的参数。槽函数将忽略信号的多余参数,这个特性允许你在信号和槽参数不完全匹配的情况下,仍然能够正常工作。正常情况下,不推荐把槽函数设计为overload型。

            3.某些信号的参数有默认值。也就是说同一信号的参数分为有参数和无参数,如QCheckBox的clicked()信号和clicked(bool)信号。这时connect()函数有两种写法:

                    a.设置不同名字的槽函数: 

    //槽函数
    void do_checked(bool checked);
    void do_checked_NoParam();
    //connect()函数
    connect(checkBox, &QCheckBox::clicked, this, &Widget::do_checked);
    connect(checkBox, &QCheckBox::clicked, this, &Widget::do_checked_NoParam);

                    b.使用模板函数qOverload()来明确参数类型:

    connect(checkBox, &QCheckBox::clicked, this, qOverload(&Widget::do_checked));
    connect(checkBox, &QCheckBox::clicked, this, qOverload(&Widget::do_checked));

    3.自动连接(无需使用connect()函数)

            在构建项目时,若勾选了“Generate form”字段,则会生成一个后缀为“.ui”的文件。

    详解Qt中connect()函数

            那么在ui设计界面种可以选中一个对象,右键选择“Go to slot”或者“转到槽”,在弹出的对话框中再选择信号,那么就会自动生成一个槽函数。如果槽函数的名称符合相应的格式,Qt 会在运行时通过setupUi(this)自动生成connect()函数完成连接。

    详解Qt中connect()函数

    Dialog::Dialog(QWidget *parent)
        : QDialog(parent)
        , ui(new Ui::Dialog)
    {
        //由go to slot生成的槽函数可以自动关联
        ui->setupUi(this);  
        //自定义槽函数需要手动关联
        connect(ui->radioButtonBlack,SIGNAL(clicked()),this,SLOT(do_setFontColor()));
    }
    //自动生成的槽函数格式:void on__(){}
    void Widget::on_btnCal_clicked()
    {
        ...
    }
    //手动写的槽函数
    void Widget::do_setFontColor()
    {
        ...
    }

            当然在设计一些复杂功能时,自动连接方法就不太适用了。

    4.Lambda表达式(Qt5.4)

            lambda 表达式提供了一种非常灵活的方式来处理信号。有如下几个优点:

    1. 可以直接在连接语句中定义信号处理逻辑,无需在类中定义额外的槽函数。这在处理简单逻辑时尤其方便。
    2. 避免为每个信号处理逻辑定义新的槽函数,减少命名空间污染。
    3. 允许你在处理信号参数时,捕获外部变量或定义额外的处理逻辑。

    基本格式如下:

    connect(sender, &SenderClass::signalName, [lambda expression]);
    

             举个栗子对比理解一下:

    //方法一:使用槽函数指针连接
    void processData(int value, QString message) {
        if (value > 10) {
            qDebug() 
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]