Qt 信號槽的擴展知識

Qt 信號槽的擴展知識

  • 一、信號與槽的重載
    • Qt信號與槽的重載問題
    • 注意事項
    • 示例場景
  • 二、一個信號連接多個槽
    • 1、直接連接多個槽
    • 2、使用lambda表達式連接
    • 3、連接順序控制
    • 4、斷開特定連接
    • 5、自動連接方式
  • 三、 多個信號連接一個槽
    • 基本連接語法
    • 使用QSignalMapper區分信號源(Qt5以下版本)
    • Qt5推薦的Lambda方式
    • 槽函數中識別信號源
    • 自動連接方式(Qt Designer)
    • 注意事項
  • 四、 信號連接信號
    • 使用`QObject::connect`直接連接
    • 使用Lambda表達式中轉
    • 信號轉發在UI設計中的應用
    • 注意事項

在這里插入圖片描述

一、信號與槽的重載

Qt信號與槽的重載問題

Qt信號與槽機制支持重載,但需要注意連接時的類型匹配和語法細節。以下是處理信號與槽重載的幾種方法:

使用QOverload或qOverload(Qt 5.7及以上)
對于重載的信號或槽,可以使用模板函數QOverloadqOverload明確指定參數類型:

connect(sender, QOverload<int>::of(&SenderClass::signalName), receiver, &ReceiverClass::slotName);

使用舊式Qt4語法(不推薦)
Qt4的SIGNAL/SLOT宏通過字符串匹配,可以繞過類型檢查,但存在運行時風險:

connect(sender, SIGNAL(signalName(int)), receiver, SLOT(slotName(int)));

使用lambda表達式作為中間層
當槽函數參數少于信號時,可用lambda過濾參數:

connect(sender, &SenderClass::signalName, [receiver](int val){ receiver->slotName(val); 
});

靜態轉換解決歧義
對于成員函數指針的歧義,可用static_cast強制轉換:

connect(sender, static_cast<void (SenderClass::*)(int)>(&SenderClass::signalName), ...);

注意事項

  • Qt5的新語法在編譯時檢查類型匹配,比Qt4的字符串語法更安全
  • 重載信號的連接必須保證參數類型完全一致或兼容
  • 默認參數會導致簽名變化,可能影響連接
  • 多繼承情況下需注意this指針的正確性

示例場景

class Device : public QObject {Q_OBJECT
public:void send(int code);  // 重載函數void send(QString msg);
signals:void data(int val);void data(QString val);
};// 連接int版本的信號
connect(device, QOverload<int>::of(&Device::data), [](int v){ qDebug() << v; });// 連接QString版本的信號
connect(device, QOverload<QString>::of(&Device::data), [](QString s){ qDebug() << s; });

二、一個信號連接多個槽

在QT中,一個信號可以連接多個槽函數,當信號被觸發時,所有連接的槽函數會按照連接的順序依次執行。

1、直接連接多個槽

使用connect函數多次連接同一個信號到不同的槽函數:

connect(sender, &SenderClass::signalName, receiver1, &ReceiverClass1::slotName1);
connect(sender, &SenderClass::signalName, receiver2, &ReceiverClass2::slotName2);

2、使用lambda表達式連接

如果需要傳遞額外參數或進行簡單處理,可以使用lambda表達式:

connect(sender, &SenderClass::signalName, [=](){// 槽函數1邏輯
});
connect(sender, &SenderClass::signalName, [=](){// 槽函數2邏輯
});

3、連接順序控制

槽函數的執行順序與連接順序一致。如果需要改變執行順序,可以使用QObject::connect的第五個參數指定連接類型:

connect(sender, &SenderClass::signalName, receiver1, &ReceiverClass1::slotName1, Qt::DirectConnection);
connect(sender, &SenderClass::signalName, receiver2, &ReceiverClass2::slotName2, Qt::QueuedConnection);

4、斷開特定連接

如果需要斷開某個特定連接,可以使用disconnect函數:

disconnect(sender, &SenderClass::signalName, receiver1, &ReceiverClass1::slotName1);

5、自動連接方式

在QT Designer中創建的UI文件,可以通過命名約定自動連接信號和槽:

void on_<object name>_<signal name>(<parameters>);

這種方式也會支持一個信號連接多個符合命名約定的槽函數。

三、 多個信號連接一個槽

在Qt中,多個信號可以連接到同一個槽函數。這種設計模式常用于多個事件觸發相同處理邏輯的場景,例如多個按鈕點擊觸發同一操作或多個數據源更新時刷新界面。

基本連接語法

使用connect函數將多個信號連接到同一個槽:

connect(sender1, &SenderClass::signal1, receiver, &ReceiverClass::slot);
connect(sender2, &SenderClass::signal2, receiver, &ReceiverClass::slot);
connect(sender3, &SenderClass::signal3, receiver, &ReceiverClass::slot);

使用QSignalMapper區分信號源(Qt5以下版本)

對于需要區分信號來源的場景,Qt4時代常用QSignalMapper:

QSignalMapper *mapper = new QSignalMapper(this);
connect(button1, SIGNAL(clicked()), mapper, SLOT(map()));
connect(button2, SIGNAL(clicked()), mapper, SLOT(map()));
mapper->setMapping(button1, 1);
mapper->setMapping(button2, 2);
connect(mapper, SIGNAL(mapped(int)), this, SLOT(handleButton(int)));

Qt5推薦的Lambda方式

現代Qt版本推薦使用Lambda表達式處理多信號連接:

connect(button1, &QPushButton::clicked, [=](){ handleButton("Button1"); });
connect(button2, &QPushButton::clicked, [=](){ handleButton("Button2"); });

槽函數中識別信號源

槽函數可以通過以下方式識別信號來源:

void MyClass::handleSlot()
{QObject *sender = QObject::sender();if (sender == button1) {// 處理button1信號} else if (sender == button2) {// 處理button2信號}
}

自動連接方式(Qt Designer)

在UI設計中,可以命名對象為"on_對象名_信號名"的槽函數實現自動連接:

void on_button1_clicked();
void on_button2_clicked();
void on_button3_clicked();

注意事項

  • 確保信號和槽的參數類型兼容
  • 多線程環境下注意連接類型(自動選擇、直接連接、隊列連接)
  • 對象生命周期管理避免懸空連接
  • 大量連接時考慮性能影響,必要時使用事件過濾器替代### 多個信號連接一個槽的實現方法

在Qt中,多個信號可以連接到同一個槽函數。這種設計模式常用于多個事件觸發相同處理邏輯的場景,例如多個按鈕點擊觸發同一操作或多個數據源更新時刷新界面。

四、 信號連接信號

在Qt中,信號可以連接到另一個信號,這種機制稱為信號轉發或信號中繼。當第一個信號被發射時,會自動觸發第二個信號的發射。以下是實現信號連接信號的幾種方法。

使用QObject::connect直接連接

通過QObject::connect函數,可以直接將一個信號連接到另一個信號。語法與信號連接到槽類似。

QObject::connect(sender, &SenderClass::signal1, receiver, &ReceiverClass::signal2);

示例代碼:

// 定義兩個QObject的子類
class Sender : public QObject {Q_OBJECT
signals:void signal1();
};class Receiver : public QObject {Q_OBJECT
signals:void signal2();
};// 連接信號到信號
Sender sender;
Receiver receiver;
QObject::connect(&sender, &Sender::signal1, &receiver, &Receiver::signal2);

使用Lambda表達式中轉

如果需要在中轉信號時添加邏輯,可以使用Lambda表達式作為中間層。

QObject::connect(sender, &SenderClass::signal1, [&receiver]() {// 添加額外邏輯receiver->signal2();
});

示例代碼:

QObject::connect(&sender, &Sender::signal1, [&receiver]() {qDebug() << "Signal1 emitted, forwarding to Signal2";emit receiver->signal2();
});

信號轉發在UI設計中的應用

在Qt Designer或QML中,信號轉發常用于簡化UI組件之間的交互。例如,按鈕的點擊信號可以轉發到另一個自定義信號。

QML示例:

Button {onClicked: customSignal()
}

注意事項

  • 信號連接信號時,無需手動調用emit,Qt會自動處理信號的轉發。
  • 避免循環連接(如A信號連B信號,B信號又連A信號),否則會導致無限遞歸。
  • 信號參數的類型和數量必須匹配,否則編譯時會報錯。

在Qt中,信號可以連接到另一個信號,這種機制稱為信號轉發或信號中繼。當第一個信號被發射時,會自動觸發第二個信號的發射。以下是實現信號連接信號的幾種方法。
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90531.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90531.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90531.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鏈表算法之【合并兩個有序鏈表】

目錄 LeetCode-21題 LeetCode-21題 將兩個升序鏈表合并成一個新的升序鏈表并返回 class Solution {public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if (list1 null)return list2;if (list2 null)return list1;ListNode dummyHead new ListNode();ListN…

Linux - firewall 防火墻

&#x1f525; 什么是 firewalld&#xff1f;firewalld 是一個動態管理防火墻的守護進程&#xff08;daemon&#xff09;&#xff0c;它提供了一個 D-Bus 接口來管理系統或用戶的防火墻規則。與傳統的靜態 iptables 不同&#xff0c;firewalld 支持&#xff1a;區域&#xff08…

【GESP】C++二級真題 luogu-B4356 [GESP202506 二級] 數三角形

GESP C二級&#xff0c;2025年6月真題&#xff0c;多重循環&#xff0c;難度★?☆☆☆。 題目題解詳見&#xff1a;【GESP】C二級真題 luogu-B4356 [GESP202506 二級] 數三角形 | OneCoder 【GESP】C二級真題 luogu-B4356 [GESP202506 二級] 數三角形 | OneCoderGESP C二級&…

遙感影像巖性分類:基于CNN與CNN-EL集成學習的深度學習方法

遙感影像巖性分類&#xff1a;基于CNN與CNN-EL集成學習的深度學習方法 大家好&#xff0c;我是微學AI&#xff0c;今天給大家介紹一下遙感影像巖性分類&#xff1a;基于CNN與CNN-EL集成學習的深度學習方法。該方法充分利用了多源遙感數據的光譜和空間信息&#xff0c;同時結合…

【STM32 學習筆記】SPI通信協議

SPI通信協議 SPI協議是由摩托羅拉公司提出的通訊協議(Serial Peripheral Interface)&#xff0c;即串行外圍設備接口&#xff0c; 是一種高速全雙工的通信總線。它被廣泛地使用在ADC、LCD等設備與MCU間&#xff0c;要求通訊速率較高的場合。 ??學習本章時&#xff0c;可與I2C…

Kafka如何做到消息不丟失

一、三種消息傳遞語義(Message Delivery Semantics):核心是“消息被消費處理的次數” Kafka的三種傳遞語義本質上描述的是“一條消息從生產到最終被消費者處理完成,可能出現的次數”,這由生產者的消息寫入可靠性和消費者的offset提交策略共同決定。 1. At most once(最…

HEVC/H.265 碼流分析工具 HEVCESBrowser 使用教程

引言 研究視頻編解碼的都知道&#xff0c;少不了各類的分析工具助力標準研究和算法開發&#xff0c;目前最出名的流媒體分析工具就是elecard系列&#xff0c;但基于一些原因可能大家用的都比較少。因此&#xff0c;找到合適的碼流分析工具才是編解碼研究的便捷途徑&#xff0c…

量子計算+AI芯片:光子計算如何重構神經網絡硬件生態

前言 前些天發現了一個巨牛的人工智能免費學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站 量子計算AI芯片&#xff1a;光子計算如何重構神經網絡硬件生態 ——2025年超異構計算架構下的萬億參數模型訓練革命 產業拐點&a…

linux 4.14 kernel屏蔽arm arch timer的方法

在 ARMv7 架構的單核 CPU 系統中&#xff0c;完全禁用 coretime 時鐘中斷&#xff08;通常是 ARM 私有定時器中斷&#xff09;需要謹慎操作&#xff0c;因為這會導致調度器無法工作&#xff0c;系統可能失去響應。以下是實現方法及注意事項&#xff1a;方法 1&#xff1a;通過 …

[實戰]調頻(FM)和調幅(AM)信號生成(完整C語言實現)

調頻&#xff08;FM&#xff09;和調幅&#xff08;AM&#xff09;信號生成 文章目錄調頻&#xff08;FM&#xff09;和調幅&#xff08;AM&#xff09;信號生成1. 調頻&#xff08;FM&#xff09;和調幅&#xff08;AM&#xff09;信號原理與信號生成調幅&#xff08;AM&#…

【LeetCode 熱題 100】21. 合并兩個有序鏈表——(解法一)迭代法

Problem: 21. 合并兩個有序鏈表 題目&#xff1a;將兩個升序鏈表合并為一個新的 升序 鏈表并返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 文章目錄整體思路完整代碼時空復雜度時間復雜度&#xff1a;O(M N)空間復雜度&#xff1a;O(1)整體思路 這段代碼旨在解決…

力扣 hot100 Day40

23. 合并 K 個升序鏈表 給你一個鏈表數組&#xff0c;每個鏈表都已經按升序排列。 請你將所有鏈表合并到一個升序鏈表中&#xff0c;返回合并后的鏈表。 //自己寫的垃圾 class Solution { public:ListNode* mergeKLists(vector<ListNode*>& lists) {vector<int…

validate CRI v1 image API for endpoint “unix:///run/containerd/containerd.sock“

1.現象pull image failed: Failed to exec command: sudo -E /bin/bash -c "env PATH$PATH crictl pull 172.23.123.117:8443/kubesphereio/pause:3.9"FATA[0000] validate service connection: validate CRI v1 image API for endpoint "unix:///run/container…

【會員專享數據】2013-2024年我國省市縣三級逐月SO?數值數據(Shp/Excel格式)

之前我們分享過2013-2024年全國范圍逐月SO?柵格數據&#xff08;可查看之前的文章獲悉詳情&#xff09;!該數據來源于韋晶博士、李占清教授團隊發布在國家青藏高原科學數據中心網站上的中國高分辨率高質量近地表空氣污染物數據集。很多小伙伴拿到數據后反饋柵格數據不太方便使…

銳捷網絡重磅發布RG-UNC CS網絡數字化平臺:四大核心能力重塑企業網絡管理新范式

近期&#xff0c;銳捷重磅發布RG-UNC網絡數字化平臺CS系列產品&#xff0c;通過全網統一融合管理、組網編排及自動化部署、便捷準入與訪問控制、全鏈業務保障與可視四大核心能力&#xff0c;重新定義企業網絡管理標準。置身于數字化轉型的進程中&#xff0c;您的網絡是否還在面…

使用虛擬機遠程登陸ensp模擬器交換機

本文使用軟件&#xff1a;VMware&#xff0c;eNSP&#xff0c;mobaxterm要登陸ensp里面的設備&#xff0c;需要使用到cloud下面我們先搭建如下拓撲&#xff1a;首先點擊cloud&#xff0c;端口一綁定UDP信息&#xff0c;添加&#xff1b;端口2綁定VMnet8網卡&#xff08;注意網段…

顯卡GPU的架構和工作原理

顯卡GPU&#xff08;圖形處理單元&#xff09;是專為并行計算和圖形處理設計的芯片&#xff0c;廣泛應用于游戲、科學計算、人工智能和數據中心等領域。以下詳細介紹GPU的架構和工作原理&#xff0c;涵蓋核心組件、計算流程和關鍵技術&#xff0c;盡量簡潔清晰。 一、GPU架構概…

AndFix、Robust 與 Tinker 熱修復框架深度對比

AndFix、Robust 與 Tinker 熱修復框架深度對比 在 Android 熱修復領域&#xff0c;AndFix、Robust 和 Tinker 是三種主流的解決方案&#xff0c;它們在實現原理、使用場景和限制條件上有顯著差異。以下是三者的詳細對比分析&#xff1a; 一、核心原理對比特性AndFixRobustTinke…

FlashAttention 快速安裝指南(避免長時間編譯)

簡介&#xff1a;FlashAttention 編譯太慢&#xff1f;本篇提供無需編譯的預編譯 wheel 快速安裝方案&#xff0c;適配多版本 Python、PyTorch 和 CUDA&#xff0c;極大節省部署時間&#xff01; &#x1f4a1; 背景介紹 FlashAttention 是由 DAO Labs 提出的一種高性能 atten…

openresty增加tcp端口轉發

openresty增加tcp端口轉發 1.配置文件nginx.conf 增加stream模塊 stream {include /etc/nginx/conf.d/stream/*.conf; }2.在nginx/conf/目錄下創建個stream文件夾 新增個10000.conf配置文件server {listen 10000;proxy_pass data_tcp; upstream data_tcp {server 10.10.10.2:10…