Qt信号槽相关语法

下面詳細解釋新的 Qt 連接語法,也就是 Qt5 引入的基於函式指標的連接方式。這種語法相較於 Qt4 的字串式連接,更安全、更易讀、且在編譯時期就能檢查錯誤。

Qt4 的字串式連接 (已不建議使用):

在 Qt4 中,連接信號與槽是使用字串來指定信號和槽的名稱:

connect(sender, SIGNAL(signalName(argumentTypes)), receiver, SLOT(slotName(argumentTypes)));
  • SIGNAL(signalName(argumentTypes)): 使用 SIGNAL 巨集將信號名稱轉換為字串。
  • SLOT(slotName(argumentTypes)): 使用 SLOT 巨集將槽名稱轉換為字串。

這種方式有以下缺點:

  • 型別不安全: 編譯器無法檢查信號和槽的參數型別是否匹配,錯誤只能在執行時期發現。
  • 重構困難: 如果修改了信號或槽的名稱,需要手動修改所有連接的程式碼,容易出錯。
  • 效能略差: 執行時期需要進行字串比較,效能略遜於新的語法。

Qt5 的基於函式指標的連接 (推薦使用):

Qt5 引入了新的連接語法,使用函式指標來指定信號和槽:

connect(sender, &Sender::signalName, receiver, &Receiver::slotName);
  • &Sender::signalName: 使用 & 運算子取得信號的函式指標。
  • &Receiver::slotName: 使用 & 運算子取得槽的函式指標。

這種方式有以下優點:

  • 型別安全: 編譯器會在編譯時期檢查信號和槽的參數型別是否匹配,及早發現錯誤。
  • 重構容易: 如果修改了信號或槽的名稱,編譯器會提示錯誤,方便修改所有相關的程式碼。
  • 效能較好: 直接使用函式指標,避免了執行時期的字串比較,效能略有提升。
  • 更易讀: 程式碼更清晰易懂,更容易維護。

處理重載信號/槽:

當信號或槽是重載函式時,需要使用 QOverload 來明確指定要連接的版本:

// 假設 GirlFriend 類別有兩個重載的 hungry 訊號
class GirlFriend : public QObject {
    Q_OBJECT
public:
    signals:
        void hungry();
        void hungry(const QString& food);
};

// 連接 hungry(const QString& food) 版本
connect(girlfriend, QOverload<const QString&>::of(&GirlFriend::hungry), me, &Me::eat);

// 如果要連接無參數的hungry()版本,則可以這樣寫:
connect(girlfriend, QOverload<>(&GirlFriend::hungry), me, &Me::eat);

QOverload 的用法:

  • QOverload<ArgumentTypes>::of(&Class::method): 用於指定具有特定參數型別的重載函式。
  • QOverload<>(&Class::method): 用於指定無參數的重載函式。

Lambda 表達式 (C++11 引入):

Qt5 還支援使用 Lambda 表達式來連接信號和槽,這使得程式碼更加簡潔靈活:

connect(button, &QPushButton::clicked, this, [this](){
    // 在 Lambda 表達式中執行的程式碼
    qDebug() << "Button clicked!";
    m_girlfriend->hungry("我想吃點心!");
});

Lambda 表達式非常適合用於簡單的槽函式,避免了定義單獨的槽函式。

範例比較:

假設有以下信號和槽:

class Sender : public QObject {
    Q_OBJECT
public:
    signals:
        void mySignal(int value, const QString& text);
};

class Receiver : public QObject {
    Q_OBJECT
public:
public slots:
    void mySlot(int value, const QString& text);
};

使用 Qt4 的連接方式:

connect(sender, SIGNAL(mySignal(int, QString)), receiver, SLOT(mySlot(int, QString)));

使用 Qt5 的連接方式:

connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot);

使用 Qt5 和 Lambda 表達式:

connect(sender, &Sender::mySignal, this, [this](int value, const QString& text){
    qDebug() << "Value:" << value << "Text:" << text;
});

總結:

新的 Qt 連接語法使用函式指標,提供了型別安全、編譯時期檢查、更佳的效能和更易讀的程式碼。在現代 Qt 開發中,強烈建議使用這種新的連接方式。Lambda 表達式則提供了更靈活的選擇,適用於簡單的槽函式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值