[C++Qt] 槽函數收不到信號問題(信號的注冊)

  • 📢博客主頁:https://loewen.blog.csdn.net
  • 📢歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正!
  • 📢本文由 丶布布原創,首發于 CSDN,轉載注明出處🙉
  • 📢現在的付出,都會是一種沉淀,只為讓你成為更好的人?

文章預覽:

      • 一. 需要注冊信號參數的情況
      • 二. 不注冊可能引發的問題
      • 三. 如何注冊自定義類型
      • 四. 示例:跨線程信號槽的正確用法
      • 五. 為什么“僅用 qRegisterMetaType 也能工作”?


一. 需要注冊信號參數的情況

1、跨線程的信號槽連接(使用 QueuedConnection)

當信號和槽位于不同線程,且連接方式為 Qt::QueuedConnectionQt::BlockingQueuedConnection 時,參數類型必須注冊

原因:跨線程通信時,Qt 需要將參數序列化到接收線程的事件隊列中,這要求類型必須能被 Qt 的元對象系統識別。

2、使用 QVariant 傳遞自定義類型

如果信號參數是自定義類型,且需要與 QVariant 結合使用,必須注冊類型。


二. 不注冊可能引發的問題

1、運行時警告或錯誤

如果未注冊自定義類型,Qt 會在運行時輸出類似以下警告:

QObject::connect: Cannot queue arguments of type 'MyCustomType'
(Make sure 'MyCustomType' is registered using qRegisterMetaType().)

后果:跨線程的信號槽調用會失敗,槽函數不會執行,程序可能無響應或崩潰。

2、參數無法正確傳遞

未注冊的類型無法被 Qt 序列化/反序列化,導致槽函數接收到的參數是無效或未初始化的值。

3、無法與 QVariant 交互

自定義類型無法通過 QVariant 存儲或傳遞,導致相關功能(如屬性系統、模型/視圖)失效。


三. 如何注冊自定義類型

1、使用 Q_DECLARE_METATYPE 宏

#include <QMetaType>// 自定義類型定義
struct MyCustomType {int id;QString name;
};// 聲明元類型支持(放在頭文件末尾)
Q_DECLARE_METATYPE(MyCustomType)

Q_DECLARE_METATYPE 的作用

1)編譯時元信息生成

Q_DECLARE_METATYPE 宏會為類型生成編譯時的元信息(如類型名稱、大小、對齊方式等),使得以下功能可用:

  • QVariant 的構造和類型轉換(例如 QVariant::fromValue 和 QVariant::value)。
  • 類型在模板和宏中的靜態識別(例如 QMetaType 的靜態接口)。

2)隱式要求

如果未使用 Q_DECLARE_METATYPE,即使通過 qRegisterMetaType 注冊了類型,以下操作可能失敗:

MyCustomType data;
QVariant variant = QVariant::fromValue(data); // 編譯錯誤!

2、使用 qRegisterMetaType 注冊類型

在程序啟動時(如 main 函數、構造函數等中)注冊類型:

#include <QMetaType>int main(int argc, char *argv[]) {QApplication app(argc, argv);// 注冊自定義類型qRegisterMetaType<MyCustomType>("MyCustomType");// 如果類型有默認構造函數,可以簡寫為:qRegisterMetaType<MyCustomType>();return app.exec();
}

四. 示例:跨線程信號槽的正確用法

// 自定義類型
struct MyCustomType {int id;QString name;
};
Q_DECLARE_METATYPE(MyCustomType)// 發送者類
class Sender : public QObject {Q_OBJECT
public:void sendData() {MyCustomType data{1, "Test"};emit signalData(data); // 發送信號}
signals:void signalData(const MyCustomType& data);
};// 接收者類
class Receiver : public QObject {Q_OBJECT
public slots:void onDataReceived(const MyCustomType& data) {qDebug() << "Received:" << data.id << data.name;}
};int main(int argc, char *argv[]) {QApplication app(argc, argv);qRegisterMetaType<MyCustomType>(); // 注冊類型Sender sender;Receiver receiver;QThread thread;// 跨線程連接QObject::connect(&sender, &Sender::signalData,&receiver, &Receiver::onDataReceived,Qt::QueuedConnection);//將接受者移至線程中,這樣與發送者即分屬于不同的線程中receiver.moveToThread(&thread);thread.start();sender.sendData();return app.exec();
}

五. 為什么“僅用 qRegisterMetaType 也能工作”?

場景 1:跨線程信號槽通信

  • 如果僅在跨線程信號槽中使用自定義類型,且未直接操作 QVariant,程序可能正常執行。
  • 原因
    qRegisterMetaType 在運行時注冊了類型,使得 Qt 能正確序列化參數。
    Q_DECLARE_METATYPE 的缺失在此場景下可能不會立即暴露問題。

場景 2:低版本 Qt 的寬松處理

  • 某些舊版 Qt(如 Qt4)對類型注冊的要求較為寬松,可能允許未聲明 Q_DECLARE_METATYPE。
  • 風險:
    這種行為是未定義的,可能因 Qt 版本或平臺不同而失效。

下雨天,最愜意的事莫過于躺在床上靜靜聽雨,雨中入眠,連夢里也長出青苔。

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

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

相關文章

從零開始用AI開發游戲(一)

1. 核心玩法設計 核心目標&#xff1a;玩家需在隨機生成的3D迷宮中尋找出口&#xff0c;躲避陷阱、收集道具、解開謎題。核心機制&#xff1a; 隨機生成迷宮&#xff1a;每次游戲生成不同結構的迷宮&#xff08;遞歸分割算法或深度優先搜索&#xff09;。第一人稱視角&#xf…

基于ssm的寵物醫院信息管理系統(全套)

一、系統架構 前端&#xff1a;html | layui | vue | element-ui 后端&#xff1a;spring | springmvc | mybatis 環境&#xff1a;jdk1.8 | mysql | maven | tomcat | idea | nodejs 二、代碼及數據庫 三、功能介紹 01. web端-首頁1 02. web端-首頁…

【CXX】6.7 SharedPtr<T> — std::shared_ptr<T>

std::shared_ptr 的 Rust 綁定稱為 SharedPtr。 限制&#xff1a; SharedPtr 不支持 T 為不透明的 Rust 類型。對于在語言邊界上傳遞不透明 Rust 類型的所有權&#xff0c;應改用 Box&#xff08;C 中的 rust::Box&#xff09;。 示例 // src/main.rsuse std::ops::Deref; …

利用python生成excel中模板范圍對應的shape文件

利用python生成excel中模板范圍對應的shape文件 # -*- coding: utf-8 -*- import os.pathimport pandas as pd from shapely.geometry import Polygon from shapely.wkt import dumps import argparse# 創建解析器 parser argparse.ArgumentParser(description"這是一個…

cursor使用

引入私有文檔 設置-> Features->下滑找到Docs url后邊多加一個 / 可以拉取url下所有的頁面(子頁面&#xff0c;子目錄)&#xff0c;不加只拉取url當前頁面 使用 選擇 Docs 回車 選擇 文檔 直接解析鏈接 鏈接 回車 搜索引擎 web 對比git版本差異 git 選擇其中一個 g…

達夢數據庫中插入導出圖片的方法與應用

達夢數據庫中插入導出圖片的方法與應用 在數據庫的實際應用場景中&#xff0c;圖片存儲是一項常見且重要的需求。以電商平臺為例&#xff0c;商品展示圖片是吸引消費者的關鍵元素&#xff1b;而在社交軟件里&#xff0c;用戶頭像更是個人形象的直觀體現。針對達夢數據庫&#…

【云原生】動態資源分配(DRA)深度洞察報告

1. DRA 的發展與設計靈感 Kubernetes 早期通過 Device Plugin&#xff08;設備插件&#xff09;機制支持 GPU、NIC 等特殊硬件&#xff0c;將節點上可用設備數量上報給 kubelet 和調度器。但設備插件模式存在局限&#xff1a;調度器只能根據節點標簽等屬性粗粒度篩選&#xff…

嵌入式八股ARM篇

前言 ARM篇主要介紹一下寄存器和中斷機制,至于匯編這一塊…還請大家感興趣自行學習 1.寄存器 R0 - R3 R4 - R11 寄存器 R0 - R3一般用作函數傳參 R4 - R11用來保存程序運算的中間結果或函數的局部變量 在函數調用過程中 注意在發生異常的時候 cortex-M0架構會自動將R0-R3壓入…

Python 實現的采集諸葛靈簽

Python 實現的采集諸葛靈簽 項目介紹 這是一個基于 Python 開發的諸葛靈簽數據采集和展示項目。通過爬蟲技術獲取諸葛神簽的簽文和解簽內容&#xff0c;并提供數據存儲和查詢功能。 項目結構 zhuge/├── zhuge_scraper.py # 爬蟲主程序├── zhuge_pages/ # 數據存儲目錄…

【C++項目實戰】校園公告搜索引擎:完整實現與優化指南

&#x1f3ac; 個人主頁&#xff1a;誰在夜里看海. &#x1f4d6; 個人專欄&#xff1a;《C系列》《Linux系列》《算法系列》 ?? 道阻且長&#xff0c;行則將至 目錄 &#x1f4da;一、項目概述 &#x1f4d6;1.項目背景 &#x1f4d6;2.主要功能 &#x1f4d6;3.界面展…

代理(Delegate)、閉包(Closure)、Notification(通知中心) 和 swift_event_bus適用場景和工作方式

在 Swift 開發中&#xff0c;在 Swift 開發中&#xff0c;代理&#xff08;Delegate&#xff09;、閉包&#xff08;Closure&#xff09;、Notification&#xff08;通知中心&#xff09; 和 swift_event_bus 主要用于 組件之間的通信&#xff0c;但它們的適用場景和工作方式有…

設計模式--單例模式(Singleton)【Go】

引言 在設計模式中&#xff0c;單例模式&#xff08;Singleton Pattern&#xff09;是一種非常常見且實用的模式。它的核心思想是確保一個類只有一個實例&#xff0c;并提供一個全局訪問點。這種模式在需要全局唯一對象的場景中非常有用&#xff0c;比如配置管理、日志記錄、數…

MySQL數據庫復制

文章目錄 MySQL數據庫復制一、復制的原理二、復制的搭建1.編輯配置文件2.在主庫上創建復制的用戶3.獲取主庫的備份4.基于從庫的恢復5.建立主從復制6.開啟主從復制7.查看主從復制狀態 MySQL數據庫復制 MySQL作為非常流行的數據庫&#xff0c;支撐它如此出彩的因素主要有兩個&am…

Sourcetree——使用.gitignore忽略文件或者文件夾

一、為何需要文件忽略機制&#xff1f; 1.1 為什么要會略&#xff1f; 對于開發者而言&#xff0c;明智地選擇忽略某些文件類型&#xff0c;能帶來三大核心優勢&#xff1a; 倉庫純凈性&#xff1a;避免二進制文件、編譯產物等污染代碼庫 安全防護&#xff1a;防止敏感信息&…

基于yolov8+streamlit實現目標檢測系統帶漂亮登錄界面

【項目介紹】 基于YOLOv8和Streamlit實現的目標檢測系統&#xff0c;結合了YOLOv8先進的目標檢測能力與Streamlit快速構建交互式Web應用的優勢&#xff0c;為用戶提供了一個功能強大且操作簡便的目標檢測平臺。該系統不僅具備高精度的目標檢測功能&#xff0c;還擁有一個漂亮且…

分享vue好用的pdf 工具實測

vue3-pdf-app&#xff1a; 帶大綱&#xff0c;帶分頁&#xff0c;帶縮放&#xff0c;帶全屏&#xff0c;帶打印&#xff0c;帶下載&#xff0c;帶旋轉 下載依賴&#xff1a; yarn add vue3-pdf-appornpm install vue3-pdf-app 配置類&#xff1a; 創建文件 pdfConfig.ts /…

基于微信小程序開發的寵物領養平臺——代碼解讀

項目前端 一、項目的技術架構概況 一句話概括&#xff1a;該項目是基于微信小程序開發的寵物領養平臺&#xff0c;采用原生小程序框架進行用戶界面的構建&#xff0c;使用 wx.request 進行 API 請求&#xff0c;并通過 getApp() 和本地存儲來管理全局狀態和用戶信息。 一&am…

最完美的WPF無邊框設計!

常規的無邊框方法設計 常規的WPF無邊框設計方法都是通過AllowsTransparency="True"和WindowStyle=“None”,并且使用WindowChrome樣式來實現,但是這樣會有問題就是,窗體最大化的時候將底部任務欄給擋住了,另外最大化的時候不能拖動窗體。參考這個大佬的設計@ 若…

【區塊鏈】btc

學習視頻源鏈接&#xff1a; https://www.bilibili.com/video/BV1Vt411X7JF/ 本文是根據肖老師的視頻進行的筆記記錄 一、 cryptographic hash function 1.1. collision resistance抗碰撞性 &#xff1a; collision 指的是hash碰撞 抗碰撞性 (Collision Resistance) 是密碼…

C語言【數據結構】:時間復雜度和空間復雜度.詳解

引言 詳細介紹什么是時間復雜度和空間復雜度。 前言&#xff1a;為什么要學習時間復雜度和空間復雜度 算法在編寫成可執行程序后&#xff0c;運行時需要耗費時間資源和空間(內存)資源。因此衡量一個算法的好壞&#xff0c;一般是從時間和空間兩個維度來衡量的&#xff0c;即時…