实际开发中,如果仅使用Qt提供的信号函数和槽函数,会经常遇到信号函数的参数类型和个数无法满足实际需求、信号函数和槽函数的参数类型不匹配等问题。解决此类问题,最简单有效的方式就是:自定义场景需要的信号函数和槽函数。
1.自定义信号
条件
定义在某个类中,
该类直接或间接继承自QObject类;
用signals 关键字修饰;
函数只需要函数的返回值类型为void,参数的类型和个数不限。
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H
#include<QPushButton>
#include<QString>
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<QLabel>
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 <QWidget>
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()进行实现 让他改变标签的文字
结果如下
点击按钮