Qt初識信號槽

在Qt框架下,使用信號槽機制來完成事件處理。

信號就是發生的事件,槽就是處理事件的函數。這兩者不在一起,不像MFC的消息循環機制。它們是鬆散的耦合。要想將它們連接起來,那麼必須使用connect函數來連接它們。例如,當我想實現,點擊關閉按鈕就會關閉當前窗口的操作。那麼我就需要使用connect函數來連接“點擊”這個信號函數和“關閉”這個槽函數。

下面是我的代碼:

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QPushButton>
#include<QString>

class MyPushButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyPushButton(const int& x,const int& y,const QString& str,QWidget *parent = nullptr);
signals:

};

MyPushButton::MyPushButton(const int& x, const int& y,const QString& str,QWidget *parent) :QPushButton(parent)
{
    this->setText(str);
    this->move(x,y);
    this->resize(100,50);
}

#endif // MYPUSHBUTTON_H
#include "widget.h"
#include"mypushbutton.h"
#include <QApplication>


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    
    QString str = "關閉";
    MyPushButton button(300,200,str);
    button.setParent(&w);
    
    //連接信號槽
    QObject::connect(&button,&MyPushButton::clicked,&QApplication::quit);
    
    button.show();
    w.show();
    return a.exec();
}

這段代碼的核心在於就在於QObject::connect()函數的使用。只有在Widget類中寫了QObject,我們才能使用信號槽機制。因此,connect理所當然的就是QObject的函數成員。我們可以在幫助文檔中看到connect函數有6個重載函數。其中5個都是靜態成員函數,剩下的一個是普通成員函數。下面是這個普通connect函數的原型:

QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type = Qt::AutoConnection) const

這個普通成員函數需要使用一個QObject才能調用,但是我們確實沒有必要創建一個QObject對象,所以一般都是使用重載的5個靜態成員函數。

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


static QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal, const QObject *receiver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection)


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


static QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)


static QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)

仔細觀察這些connect函數,可以看出,發送者和接收者都是QObject指針類型(也就是說它們可以是QObject對象或者是QObject的派生類對象)。連接類型有一個默認值Qt::AutoConnection。信號和槽可以是const char*類型的,也可以是const QMetaMethod &類型,還可以是成員函數指針(PointerToMemberFunction),還可以是Functor類型,這個類型可以是能連接到信號的任意函數或者仿函數,lambda表達式。

注意:Qt::UniqueConnections do not work for lambdas, non-member functions and functors; they only apply to connecting to member functions.

很明顯,我的代碼中使用的是靜態函數中的第四個。

 QObject::connect(&button,&MyPushButton::clicked,&QApplication::quit);

button是信號發送者,clicked是信號,quit是槽函數。

當我們點擊按鈕,發送信號,那麼槽函數quit就會被調用,從而程序退出。

lambda表達式請看這裏:https://blog.csdn.net/zy010101/article/details/73613664

信號槽要求信號和槽的參數一致。如果不一致,但是槽函數的參數可以比信號的少,即便如此,槽函數存在的那些參數的順序也必須和信號的前面幾個參數一致。因爲,你可以在槽函數中選擇忽略信號傳來的數據,但是不能說信號根本沒有這個參數,你就要在槽函數中使用。

我們一般使用的connect函數形式如下:

connect(sender, signal, receiver, slot);

sender是信號發送者,signal是信號,receiver是信號接收者,slot是槽函數。

當信號發送以後,槽函數就會被自動調用。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章