QT入门笔记(一)QT信号和槽

QT入门笔记

Qt事件

Qt 事件指的是应用程序和用户之间的交互过程,例如用户按下某个按钮,点击某个输入框等等。实际上除了用户会与应用程序进行交互外,操作系统也会与应用程序进行交互,例如当某个定时任务触发时,操作系统会关闭应用程序,这也是一个事件。

Qt 界面程序的 main() 主函数中首先要创建一个 QApplication 类的对象,函数执行结束前还要调用 QApplication 对象的 exec() 函数。一个 Qt 界面程序要想接收事件,main() 函数中就必须调用 exec() 函数,它的功能就是使程序能够持续不断地接收各种事件。

信号和槽介绍

信号(Signal):就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。GUI 程序设计的主要内容就是对界面上各组件的信号的响应,只需要知道什么情况下发射哪些信号,合理地去响应和处理这些信号就可以了。

槽(Slot):就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。

connect

[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection);

第一个参数发送者,第二个信号,第三个接收者,第四个接收者的响应函数,第五个信号与槽的连接方式

Q_OBJECT:本质是一个已定义好的宏,所有需要“信号和槽”功能的组件都必须将 Q_OBJECT 作为 private 属性成员引入到类中。

QT信号和槽

在 Qt 中,用户和控件的每次交互过程称为一个事件,比如“用户点击按钮”是一个事件,“用户关闭窗口”也是一个事件。每个事件都会发出一个信号,例如用户点击按钮会发出“按钮被点击”的信号,用户关闭窗口会发出“窗口被关闭”的信号。

Qt 中的所有控件都具有接收信号的能力,一个控件还可以接收多个不同的信号。对于接收到的每个信号,控件都会做出相应的响应动作。例如,按钮所在的窗口接收到“按钮被点击”的信号后,会做出“关闭自己”的响应动作;再比如输入框自己接收到“输入框被点击”的信号后,会做出“显示闪烁的光标,等待用户输入数据”的响应动作。在 Qt 中,对信号做出的响应动作就称为槽。

img

信号函数和槽函数通常位于某个类中,和普通的成员函数相比,它们的特别之处在于:

  • 信号函数用 signals 关键字修饰,槽函数用 public slots、protected slots 或者 private slots 修饰。signals 和 slots 是 Qt 在 C++ 的基础上扩展的关键字,专门用来指明信号函数和槽函数;
  • 信号函数只需要声明,不需要定义(实现),而槽函数需要定义(实现)。

新版 connect() 函数指定信号函数和槽函数的语法格式是&+函数所在类+函数名,一个 connect() 函数只能关联一个信号函数和一个槽函数

自定义信号和槽

自定义信号函数

信号函数指的是符合以下条件的函数:

  • 定义在某个类中,该类直接或间接继承自 QObject 类;
  • 用 signals 关键字修饰;
  • 函数只需要声明,不需要定义(实现);
  • 函数的返回值类型为 void,参数的类型和个数不限。
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include <QDebug>
#include <QLabel>
#include <QPushButton>
class MyWidget:public QWidget{
//Q_OBJECT 是一个宏,添加它才能正常使用 Qt 的信号和槽机制
    Q_OBJECT
    public:
    MyWidget(QWidget *parent = 0);
    ~MyWidget();
    //修饰信号函数的关键字
    signals:
        //自定义的信号函数
        void MySignal(QString message, QString mess2);

    public:
        void emitSignal(){
            qDebug() << "qDebug输出";
            emit MySignal(message1, message2);  //自定义语句就表示发射 MySignal 信号
        }
        //类的成员函数
        void recSlot1(QString mess){
            qDebug() << "执行 recSlot1() 成员函数,输出" << mess;
        }
        //指明定义的是槽函数
    public slots:
        void mySlot();
        void recSlot2(QString mess1,QString mess2){
            qDebug() << "执行 recSlot2() 槽函数,输出"<< mess1 << " " << mess2;
        }
    public:
        QString message1;
        QString message2;
        QPushButton b1;
        QPushButton *b2;
};
//全局函数
/*void recSlot3(){
    qDebug() << "执行 recSlot3() 全局函数";
}*/
#endif // MYWIDGET_H

自定义槽函数

Qt5 中,槽函数既可以是普通的全局函数、也可以是类的成员函数、静态成员函数、友元函数、虚函数,还可以用 lambda 表达式表示。

和信号函数不同,槽函数必须手动定义(实现)。槽函数可以在程序中直接调用,但主要用来响应某个信号。自定义一个槽函数时,需要注意以下几点:

  • 槽函数的返回值必须和信号函数相同,由于信号函数的返回值一定是 void,所以槽函数的返回值也必须为 void;
  • 对于带参的信号函数,槽函数可以选择接收所有参数,则参数的类型、顺序、个数都必须与信号函数相同;也可以选择接收前几个参数,这些参数的类型、顺序都必须与信号函数相同;还可以选择不接受任何参数。
  • 槽函数的参数个数只能比信号函数少,不能比信号函数多;
  • 槽函数的参数不能有默认值。
#include "MyWidget.h"

MyWidget::MyWidget(QWidget *parent) : QWidget(parent){
    b1.setParent(this);
    b1.setText("Close");
    b1.move(50, 50);


    b2 = new QPushButton(this);
    b2->setText("Button2");
    b2->move(150, 50);

    connect(&b1, &QPushButton::clicked, this, &MyWidget::close);

    connect(b2, &QPushButton::clicked, this, &MyWidget::mySlot); //关联自身的槽函数

}
void MyWidget::mySlot()
{
    b2->setText("^_^");
}

MyWidget::~MyWidget()
{

}

#include "mainwindow.h"
#include "MyWidget.h"
#include <QApplication>
#include <QLocale>
#include <QTranslator>
#include <QtCore>
#include <QPushButton>
#include <QWidget>

//全局函数
void recSlot3(){
    qDebug() << "执行 recSlot3() 全局函数";
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTranslator translator;
    const QStringList uiLanguages = QLocale::system().uiLanguages();
    for (const QString &locale : uiLanguages) {
        const QString baseName = "test1_" + QLocale(locale).name();
        if (translator.load(":/i18n/" + baseName)) {
            a.installTranslator(&translator);
            break;
        }
    }

    //创建主窗口
    MyWidget mywidget;
	
    //类的成员函数作为槽函数
    QObject::connect(&mywidget,&MyWidget::MySignal,&mywidget,&MyWidget::recSlot1);
    //信号函数和槽函数相连接
    QObject::connect(&mywidget,&MyWidget::MySignal,&mywidget,&MyWidget::recSlot2);
    //全局函数作为槽函数
    QObject::connect(&mywidget,&MyWidget::MySignal,&recSlot3);
    
    mywidget.show();
    //QThread::sleep(5000);
    //发射 Signal 信号
    //mywidget.emitSignal();

    return a.exec();
}


效果

在这里插入图片描述

在这里插入图片描述

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值