实际开发中,如果仅使用Qt提供的信号函数和槽函数,会经常遇到信号函数的参数类型和个数无法满足实际需求、信号函数和槽函数的参数类型不匹配等问题。解决此类问题,最简单有效的方式就是:自定义场景需要的信号函数和槽函数。
1.自定义信号
条件
定义在某个类中,
该类直接或间接继承自QObject类;
用signals 关键字修饰;
函数只需要函数的返回值类型为void,参数的类型和个数不限。
- #ifndef MYPUSHBUTTON_H
- #define MYPUSHBUTTON_H
- #include
- #include
- class MyPushButton:public QPushButton
-
- {
- Q_OBJECT
- public:
- MyPushButton();
-
- void MySetText();
- signals:
- void MyClecked(QString &qstr);
-
- };
-
- #endif // MYPUSHBUTTON_H
- #include "mypushbutton.h"
-
- MyPushButton::MyPushButton()
- {
-
- }
- void MyPushButton::MySetText()
-
- {
- QString qstr="Hello";
- emit MyClecked(qstr);
- }
2.自定义槽函数
条件
和信号函数不同,槽函数必须手动定义(实现)。槽函数可以在程序中直接调用,但主要用来响应某个信号。自定义一个槽函数时,需要注意以下几点:
槽函数的返回值必须和信号函数相同,由于信号函数的返回值一定是void,所以槽函数的返回值也必须为void;
对于带参的信号函数,槽函数可以选择接收所有参数,则参数的类型、顺序、个数都必须与信号函数相同;也可以选择接收前几个参数,这些参数的类型、顺序都必须与信号函数相同;还可以选择不接受任何参数。
槽函数的参数个数只能比信号函数少,不能比信号函数多;
槽函数的参数不能有默认值。
slots 关键字可以和public、protected、private搭配使用,它们的区别是:
public slots:该关键字修饰的槽函数,既可以在当前类及其子类的成员函数中调用,也可以在类外部的其它函数(比如main()函数)中调用;
protected slots:该关键字修饰的槽函数,仅允许在当前类及其子类的成员函数内调用,不能在类外部的其它函数内调用;
private slots:该关键字修饰的槽函数,只允许在当前类的成员函数内调用,不能在子类中调用,也不能在类外部的其它函数内调用。
通常情况下,槽函数使用public slots 修饰。
- #ifndef MYLABEL_H
- #define MYLABEL_H
-
- #include
- class MyLabel:public QLabel
- {
- Q_OBJECT
- public:
- MyLabel();
- void MySetText();
- };
-
- #endif // MYLABEL_H
- #include "mylabel.h"
-
- MyLabel::MyLabel()
- {
-
- }
- void MyLabel::MySetText()
- {
- setText("Hellow");
- }
想实现通过按钮 显示标签 但是信号和槽函数参数不匹配 一个有参数 一个没参数 我们这里可以通过自定义槽和信号来实现
//改信号
//QObject::connect(&but,&QPushButton::clicked,&but,&MyPushButton::MySetText);
//QObject::connect(&but,&MyPushButton::MyClecked,&lab,&QLabel::setText);
//改槽
//QObject::connect(&but,&QPushButton::clicked,&lab,&MyLabel::MySetText);
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- Widget w;
-
- // //QPushButton but(&w);
- // MyPushButton but;
- // but.setParent(&w);
- // MyLabel lab;
- // lab.setParent(&w);
- // lab.move(200,100);
- // but.move(200,200);
- // but.setText("按一下显示文字");
- // lab.resize(200,100);
-
-
- //想实现通过按钮 显示标签 但是信号和槽函数参数不匹配 一个有参数 一个没参数
- //我们这里可以通过自定义槽和信号来实现
- //QObject::connect(&but,&QPushButton::clicked,&lab,&QLabel::setText);
-
- //改信号
- //QObject::connect(&but,&QPushButton::clicked,&but,&MyPushButton::MySetText);
- //QObject::connect(&but,&MyPushButton::MyClecked,&lab,&QLabel::setText);
-
- //改槽
- //QObject::connect(&but,&QPushButton::clicked,&lab,&MyLabel::MySetText);
-
-
- w.show();
除了上述两种方法 我们也可以通过widget来修改
对按钮 的clicked信号添加一个槽
widget中 多了一个
public slots:
void on_pushButton_clicked();槽函数
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include
-
- QT_BEGIN_NAMESPACE
- namespace Ui { class Widget; }
- QT_END_NAMESPACE
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- Widget(QWidget *parent = nullptr);
- ~Widget();
-
- public slots:
- void on_pushButton_clicked();
-
- private:
- Ui::Widget *ui;
- };
- #endif // WIDGET_H
- #include "widget.h"
- #include "ui_widget.h"
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::Widget)
- {
- ui->setupUi(this);
- }
-
- Widget::~Widget()
- {
- delete ui;
- }
-
-
- void Widget::on_pushButton_clicked()
- {
- ui->label->setText("hello");
- }
对void Widget::on_pushButton_clicked()进行实现 让他改变标签的文字
结果如下
点击按钮