(三)信号与槽
案列:
1.点击button1改变button2的内容
2.点击主窗口按钮,显示子窗口,再通过自定义信号与槽,点击子窗口,回到主窗口
3.重载的信号槽
4.拓展:
1.信号可以连接信号
2.一个信号可以连接多个槽函数
3.多个信号可以连接一个槽函数
4.槽函数可以使用lambda表达式
例子:
connect(operatorComboBox, QOverload<int>::of(&QComboBox::activated),
this, &ImageComposer::recalculateResult);
第二个参数需要一个信号(函数)的指针,但是QComboBox::activated实际上有两个重载函数
void activated(const QString &text)
void activated(int index)
而上面的这种形式没有带形参列表,不知道返回第一个信号的指针还是第二个信号的指针
这时候利用QOverLoad通过指定形参列表,来确定返回哪个信号的指针
QOverload<int>::of()会返回一个函数指针
所以其实QComBox::activated(int) 和 QOverload<int>::of(&QComboBox::activated)意思差不多
mianwidget.cpp
#include "mainwidget.h" #include <QDebug> MainWidget::MainWidget(QWidget *parent) : QWidget(parent) { // init b1 = new QPushButton("老大", this); b1->move(100, 100); b2 = new QPushButton; b2->setParent(this); b2->setText("老二"); b2->move(200, 200); // b1 close window // qt 信号和槽他们都是函数 // 1. 信号只有函数声明, 不需要函数定义 // 2. 槽函数据需要声明也需要定义, 回调函数 // connect(b1, &QPushButton::pressed, this, &MainWidget::close); // 自定义槽函数 /* * 1. 槽函数在Qt5 可以是任意类成员函数, 全局函数, 静态函数, lambda表达式(隐式函数) * 2. 槽函数需要与信号对相应(返回值, 参数) * 3. 信号没有返回值, 槽函数返回值: void * 4. void mysig(int, double, QString); * void myslot(int, double); * 5. 槽函数的参数是为了接受信号传过来的的数据 * 6. 槽函数的参数应该是不能够大于信号的参数个数, 可以少于信号的参数个数 * 7. 槽函数可以重载 */ connect(b1, &QPushButton::released, this, &MainWidget::slotForMianWidget); // b3 显示子窗口SubWidget -- subW b3 = new QPushButton("软件园", this); b3->resize(100, 50); b3->move(200, 200); connect(b3, &QPushButton::clicked, this, &MainWidget::slotHideMe); // Qt 5 信号槽的使用方法 void (SubWidget::*MySigSub)() = &SubWidget::sigSub;// 用函数指针来指定接收的信号是带参数还是不带参数 connect(&subW, MySigSub, this, &MainWidget::slotShowMe); void (SubWidget::*MysigPlus)(int, QString) = &SubWidget::sigSub;// 用于信号函数发生重载的时候,告诉编译器调用哪个函数 connect(&subW, MysigPlus, this, &MainWidget::slotSubMsg); // Q4 信号槽 // SIGNAL() SLOT() 宏 将函数转换为字符串 宏展开预处理的时候不会报错 // connect(&subW, SIGNAL(sigSub()), this, SLOT(slotShowMe())); // connect(&subW, SIGNAL(sigSub(int , QString)), this, SLOT(ABCDe(bb, aa))); // 使用lambda表达式作为槽函数 connect(b1, &QPushButton::clicked, this, [=]() { b2->setText("lambda表达式!!!"); b3->hide(); }); } MainWidget::~MainWidget() { } void MainWidget::slotForMianWidget() { b2->setText("我被老大改名了..."); } void MainWidget::slotHideMe() { // 隐藏自己 hide(); // 显示软件园窗口 subW.show(); } void MainWidget::slotShowMe() { // 显示自己 show(); // 隐藏软件园窗口 subW.hide(); } void MainWidget::slotSubMsg(int num, QString str) { // QString --> char* // string --> char* .data() qDebug() << num << str.toUtf8().data(); }
#ifndef MAINWIDGET_H #define MAINWIDGET_H #include <QWidget> #include <QPushButton> #include "subwidget.h" class MainWidget : public QWidget { Q_OBJECT public: MainWidget(QWidget *parent = 0); ~MainWidget(); // 自定义槽函数 void slotForMianWidget(); void slotHideMe(); void slotShowMe(); void slotSubMsg(int num, QString str); private: QPushButton* b1; QPushButton* b2; QPushButton* b3; // 显示子窗口 // 子窗口对象 SubWidget subW; }; #endif // MAINWIDGET_H
#include "subwidget.h" SubWidget::SubWidget(QWidget *parent) : QWidget(parent) { b1= new QPushButton("中腾", this); b1->resize(100, 100); setWindowTitle("软件园窗口"); resize(400, 600); connect(b1, &QPushButton::clicked, this, &SubWidget::myslot); } void SubWidget::myslot() { // 发送信号 emit sigSub(); emit sigSub(250, "你是二百五!!!"); }
subwidget.h
#ifndef SUBWIDGET_H #define SUBWIDGET_H #include <QWidget> #include <QPushButton> class SubWidget : public QWidget { Q_OBJECT public: explicit SubWidget(QWidget *parent = 0); signals: // 自定义信号, 必须使用signals 声明 void sigSub(); void sigSub(int , QString); /* * 1. 可以有参数 * 2. 可以重载 * 3. 返回值为void * 4. 发送信号: emit + 信号名; * emit sigsub(); */ public slots: void myslot(); private: QPushButton* b1; }; #endif // SUBWIDGET_H