3. QT中的信号和槽 --- 信号连接方式、自定义信号和槽、信号槽重载、断连

1. 说明

实际是观察者模式的一种简易方式,使用connect函数可以为信号以及建立好连接,当信号广播(触发)时做出相应的处理。其中,信号来源于被观察者,槽来源于观察者
**信号:**函数声明,无需实现
**槽:**本质是函数,一般是类的成员函数,有声明且有实现

2. 信号连接方式

第一种:
使用SIGNAL和SLOT关键字,这样可以在信号和槽中进行参数传递

//创建按钮
QPushButton* btn = new QPushButton();
//设置位置
btn->move(150,200);
//设置大小
btn->resize(100,30);
btn->setText("窗口最大");
//设置字体
QFont font("楷体",15,1);
btn->setFont(font);
btn->setParent(this);
//设置样式
btn->setStyleSheet("QPushButton{background-color:lightblue;}\
                    QPushButton:hover{background-color:lightgreen;}\
                    QPushButton:pressed{background-color:rgba(170,155,221,1);}");
btn->show();

//创建信号连接(第一中方式:使用SIGNAL和SLOT关键字,可传递参数)
connect(btn,SIGNAL(clicked(bool)),this,SLOT(showMaximized()));

第二种:
使用地址作用域的方式,此种方式针对有多个信号和槽函数的时候不太友好

auto btnMin = new QPushButton("窗口正常",this);
btnMin->move(100,100);
//设置大小
btnMin->resize(100,30);
//设置字体
QFont font2("楷体",15,1);
btnMin->setFont(font2);
btnMin->setParent(this);
//设置样式
btnMin->setStyleSheet("QPushButton{background-color:lightblue;}\
                    QPushButton:hover{background-color:lightgreen;}\
                    QPushButton:pressed{background-color:rgba(170,155,221,1);}");
//创建信号连接(第二种连接方式,不可传递参数)
connect(btnMin,&QPushButton::clicked,this,&QWidget::showNormal);

第三种:
使用C++11中的Lambda新特性
语法:

[可访问外部变量](参数表)->返回值{
    
     函数体 }    **返回值为空时可省略**
1[变量1,变量2,...](){
    
    } 指定部分变量可访问
2[=](){
    
    } 值传递方式捕获所有外部变量(内部无法改变实际变量)
3[&](){
    
    } 引用方式捕获所有外部变量(内部可以改变实际变量)

示例:

auto btnTest = new QPushButton("测试按钮",this);
btnTest->move(100,100);
//设置大小
btnTest->resize(100,30);
//设置字体
QFont font3("楷体",15,1);
btnTest->setFont(font3);
btnTest->setParent(this);
//设置样式
btnTest->setStyleSheet("QPushButton{background-color:lightblue;}\
                    QPushButton:hover{background-color:lightgreen;}\
                    QPushButton:pressed{background-color:rgba(170,155,221,1);}");
//创建信号连接(第二种连接方式,Lambda表达式)
connect(btnTest,&QPushButton::pressed,[]()->void{
    
    
    qDebug()<<"按钮被按下....";
});
connect(btnTest,&QPushButton::released,[](){
    
    
    qDebug()<<"按钮被抬起....";
}); 

3. 自定义信号和槽

信号自定义时,使用关键字signals,只需要定义,不用实现
槽函数自定义时,使用public slots,需要实现
举例:
首先在头文件中定义信号和槽函数:

signals:
    void printInfo();

public slots:
    void onPrintInfo();

然后在界面中添加一个按钮,点击按钮后,发射自定义的信号,同时将自定义的信号和自定义的槽函数进行绑定:

auto selfBtn = new QPushButton("测试");
selfBtn->move(100,100);
//设置大小
selfBtn->resize(100,30);
//设置字体
QFont font4("楷体",15,1);
selfBtn->setFont(font4);
selfBtn->setParent(this);
//设置样式
selfBtn->setStyleSheet("QPushButton{background-color:lightblue;}\
                    QPushButton:hover{background-color:lightgreen;}\
                    QPushButton:pressed{background-color:rgba(170,155,221,1);}");
//点击按钮后,发射自定义信号
connect(selfBtn,&QPushButton::clicked,this,[=](){
    
    
    emit printInfo();
});
//将自定义的信号和自定义的槽绑定
connect(this,&Widget::printInfo,this,&Widget::onPrintInfo);

//槽函数的简单实现
void Widget::onPrintInfo()
{
    
    
    qDebug()<<"输出一些打印信息...";
}

4. 信号槽重载

关于信号和槽若有重载,则在连接信号和槽时,可以借助函数指针进行连接,使用SIGNAL和SLOT关键字的形式进行连接也是可以的。
首先,定义两个重载的信号和槽:

signals:
    void printInfo();
    void printInfo(QString mStr);

public slots:
    void onPrintInfo();
    void onPrintInfo(QString str);

然后在源文件中对两个重载的槽函数进行实现:

void Widget::onPrintInfo()
{
    
    
    qDebug()<<"输出一些打印信息...";
}

void Widget::onPrintInfo(QString str)
{
    
    
    qDebug()<<str;
}

最后进行连接时需要使用函数指针找到指定的信号和槽:

auto selfBtn = new QPushButton("测试");
selfBtn->move(btnTest->x(),btnTest->y()+50);
//设置大小
selfBtn->resize(100,30);
//设置字体
QFont font4("楷体",15,1);
selfBtn->setFont(font4);
selfBtn->setParent(this);
//设置样式
selfBtn->setStyleSheet("QPushButton{background-color:lightblue;}\
                    QPushButton:hover{background-color:lightgreen;}\
                    QPushButton:pressed{background-color:rgba(170,155,221,1);}");
connect(selfBtn,&QPushButton::clicked,this,[=](){
    
    
    emit printInfo();
    emit printInfo("带参数的信号...");
});

//定义函数指针,指向对应的信号和槽函数
void(Widget::*printSignal)() = &Widget::printInfo;
void(Widget::*printSlot)() = &Widget::onPrintInfo;
void(Widget::*printSignalStr)(QString) = &Widget::printInfo;
void(Widget::*printSlotStr)(QString) = &Widget::onPrintInfo;
//信号槽连接
connect(this,printSignal,this,printSlot);
connect(this,printSignalStr,this,printSlotStr);

5. 断连

在一个信号连接了多个槽函数后,如果想让其中一对信号槽不在产生作用,可以将其断开连接,使用函数disconnect,用法和connect一样。

disconnect(this,&Widget::printInfo,this,&Widget::onPrintInfo);

猜你喜欢

转载自blog.csdn.net/FY_13781298928/article/details/130742130