【Qt】bug排查筆記——QMetaObject::invokeMethod: No such method

問題如題目所示:QMetaObject::invokeMethod: No such method xxxx,在網上好一頓查,又將查到的資料喂給了 Ai,才最終將問題解決,特此記錄下。

一、問題背景

在做公司項目時,使用了插件的方式開發。主程序加載了一個叫CtmAboutAppPlugin的插件。該插件有個界面類CtmAboutUi,它有個槽函數:

public slot:void subAppInfo(const QVariant& msg);

主程序通過一個叫 CbbEventBus的事件總線機制,把消息發送給CtmAboutAppPlugin 這個插件。

此處我給出CbbEventBus的訂閱方法的源碼(問題出在了訂閱方法這里):

bool CbbEventBus::subscribe(const QString &topic, QObject *receiver, const char *method, Qt::ConnectionType type)
{if (!receiver || !method) return false;auto connection = QObject::connect(this,&CbbEventBus::signalUpdateMessage,receiver,[receiver, method, topic](const QString &receivedTopic, const QVariant &msg) {if (receivedTopic == topic) {// 問題出現在下面這里// QMetaObject::invokeMethod(receiver, method, Q_ARG(const QVariant&, msg)); // 最開始我是這么寫的QMetaObject::invokeMethod(receiver, method, Q_ARG(QVariant, msg)); 	// 后來改成了左邊這樣}},type);if (connection) {m_QIsSubscribeMap[topic][receiver].append(connection);return true;}return false;
}

上面兩種寫法,在程序運行時,控制臺分別輸出以下信息:

Q_ARG(QVariant, msg)對應控制臺輸出信息:QMetaObject::invokeMethod: No such method CtmAboutUi::1subAppInfo(QVariant)(const QVariant&)

Q_ARG(QVariant, msg)對應控制臺輸出信息:No such method CtmAboutUi::1subAppInfo(QVariant)(QVariant)

二、🔍 問題原因(一句話總結)

根本原因不是方法不存在,而是 invokeMethod 找方法時用的名字“對不上號”——我傳了個“帶參數的簽名”,它卻以為這是“方法名”,導致匹配失敗。


三、🕵??♂? 排查過程回顧

3.1 第一反應:是不是 MOC 沒生效?

○ 檢查了 CtmAboutUi 類,Q_OBJECT 有,public slots: 有,語法沒問題。
○ 打開 Qt 生成的 moc_CtmAboutUi.cpp一看,MOC 確實生成了,subAppInfo(QVariant) 也注冊進去了,說明元對象系統這塊是沒有問題的。
在這里插入圖片描述

3.2 第二反應:是不是 Q_ARG 寫錯了?

○ 一開始用了 Q_ARG(const QVariant&, msg),這是個經典坑。
○ Qt 的 Q_ARG 第一個參數是類型名,不能帶 const&(否則元對象系統會直接按照 const QVariant&去匹配字符串,實際上元對象系統中注冊的是QVariant 類型,并沒有const QVariant&),應該寫成 Q_ARG(QVariant, msg)
○ 改了之后,錯誤還在,但變成了 (QVariant)(QVariant),說明問題沒完。

3.3 第三反應:名字到底傳了啥?

eventBus.subscribe(topic, m_pAboutUi, SLOT(subAppInfo(QVariant)));

○ 這里 SLOT(...) 宏展開后是 "subAppInfo(QVariant)",是個帶參數列表的字符串。
○ 而 invokeMethod 拿到這個字符串后,會把它當“方法名”去查,再配上 Q_ARG(QVariant, msg),就變成了"subAppInfo(QVariant)" + “(QVariant)”,即下面這樣:

subAppInfo(QVariant)(QVariant)

這當然找不到,因為實際注冊的是 subAppInfo(QVariant)

四、? 最終解決辦法

把調用方式從:

eventBus.subscribe(this->topic(), m_pAboutUi, SLOT(subAppInfo(QVariant)));

改成:

eventBus.subscribe(this->topic(), m_pAboutUi, "subAppInfo");

只傳方法名,不帶參數列表。這樣 invokeMethod 就會用方法名 “subAppInfo” 去找,再根據 Q_ARG(QVariant, msg) 匹配參數類型,完美匹配成功。


4.1 其它疑問:

我也嘗試了如下方法:

雖然 "subAppInfo" 能解決問題,但更推薦用 函數指針 的方式,既安全又現代:


eventBus.subscribe(this->topic(), m_pAboutUi, &CtmAboutUi::subAppInfo);

這需要 CbbEventBus 支持模板,但好處是:
● 編譯時檢查,名字寫錯直接報錯
● 不用拼字符串,不怕類型不匹配
● IDE 能跳轉,維護方便

但是有錯誤,沒有成功…


五、📝 總結

QMetaObject::invokeMethod: No such method 不一定是方法不存在,很可能是 名字傳錯了。
SLOT() 宏返回的是帶參數的字符串,不適合直接傳給 invokeMethod 當方法名用。
Q_ARG 只寫類型名,別帶 const&
個人認為最穩妥的方式是用函數指針 &Class::method,但是該方法沒有成功,由于工作時間問題,目前還沒繼續深究…

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

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

相關文章

Spring Boot手寫10萬敏感詞檢查程序

使用Spring Boot手寫10萬敏感詞檢查程序 本文將介紹如何使用Spring Boot構建一個高效的敏感詞檢查系統,能夠處理多達10萬個敏感詞的檢測需求。我們將使用DFA(Deterministic Finite Automaton)算法來實現高效匹配,并提供RESTful API接口。 實現步驟 1. 創建Spring Boot項…

零構建的快感!dagger.js 與 React Hooks 實現對比,誰更優雅?

“Add Tags” 技術方案并行對比:React Hooks vs dagger.js(含核心 JS 代碼) 源碼: React Hooks:https://codepen.io/prvnbist/pen/jJzROe?editors1010dagger.js:https://codepen.io/dagger8224/pen/ZErjzw…

矩池云中LLaMA- Factory多機多卡訓練

LLaMA Factory 是一款開源低代碼大模型微調框架,集成了業界最廣泛使用的微調技術,支持通過 Web UI 界面零代碼微調大模型,目前已經成為開源社區內最受歡迎的微調框架之一。但是在矩池云上如何使用LLaMA-Factory多機多卡訓練模型呢&#xff1f…

Nginx的反向代理與正向代理及其location的配置說明

一、Nginx中location匹配優先級Nginx中location匹配優先級location支持各種匹配規則,在多個匹配規則下,Nginx對location的處理是有優先級的,優先級高的規則會優先進行處理;而優先級低的規則可能會最后處理或者不進行處理。注意&am…

神經網絡正則化三重奏:Weight Decay, Dropout, 和LayerNorm

正則化是機器學習中防止模型過擬合、提升泛化能力的核心技術。Weight Decay、Dropout和LayerNorm是三種最常用的方法,但它們的工作原理和首要目標截然不同。下面的流程圖揭示了它們的核心區別與聯系: #mermaid-svg-vymek6mFvvfxcWiM {font-family:"…

兩臺電腦通過網線直連共享數據,設置正確,卻互相ping不通的解決方法

因為某些原因,需要兩臺電腦互傳資源,但是某臺電腦可能無法連接外網。如果手頭有根網線,很容易想到通過一根網線連接兩臺電腦互傳數據。 這里先說一下基本的設置: 兩臺電腦最好都關閉防火墻;兩臺電腦都打開專用網絡和公…

面試新紀元:無聲勝有聲,讓AI成為你頸上的智慧伙伴

面試,無論是對于面試官還是求職者,都像一場無聲的戰爭。 一方要精準識人,一方要完美自薦;一方怕問不到點子上,一方怕答不到心坎里。 緊張、遺忘、表達失誤、準備不足……這些問題幾乎每個人都經歷過。 有沒有一種方…

qt-C++筆記之QtDesigner-Creator按鈕圖標與樣式

qt-C筆記之QtDesigner-Creator按鈕圖標與樣式 整理:如何用 .qrc 管理資源、在 Designer/Creator 中為 QPushButton 設置圖標(資源或系統主題),以及用樣式表調整文字樣式。涵蓋 C/Qt 與 PySide/PyQt;Linux 桌面優先&am…

maven 常用指令

Maven 是 Java 項目構建和依賴管理的得力助手。這里為你總結了一些常用指令,希望能幫你提升開發效率。下面這個表格匯總了 Maven 最核心和常用的一些命令:命令主要功能典型使用場景mvn clean清理項目,刪除 target 目錄及其所有編譯輸出文件。…

# pdf.js完全指南:構建現代Web PDF查看與解析解決方案

在當今Web開發中,實現高質量的PDF查看功能一直是前端開發者面臨的挑戰之一。作為最受歡迎的JavaScript PDF庫,pdf.js已經成為解決這一問題的行業標準。由Mozilla開發并維護的pdf.js項目,通過純JavaScript實現PDF解析與渲染,徹底改…

高效對象屬性復制工具

日常編程中,經常會碰到對象屬性復制的場景,比如 VO、DTO、PO、VO 等之間的轉換,關于什么是VO、DTO、PO、VO 等可以看上篇文章,VO、DTO、PO、VO 等對象具體有哪些方式可以使用呢? set/get 方式 性能最好的方式&#x…

大疆圖傳技術參數對比 你了解多少?

無人機是現代航空技術與智能控制技術結合的產物,已從軍事領域廣泛滲透至民用場景,成為推動各行業效率升級的關鍵工具。無人機的全稱為 “無人駕駛航空器(Unmanned Aerial Vehicle,簡稱 UAV)”,簡言之&#…

Redis 緩存熱身(Cache Warm-up):原理、方案與實踐

在 Redis 緩存架構中,“緩存熱身”是指在系統正式提供服務前(如重啟、擴容后),主動將熱點數據加載到 Redis 中的操作。其核心目標是避免**緩存穿透**(請求直達數據庫)和**緩存雪崩**(大量請求同…

基于SpringBoot的大學生就業招聘系統

1. 在線演示: 后臺:http://springbootiv1oo.xiaobias.com/springbootiv1oo/admin/dist/index.html 前臺:http://springbootiv1oo.xiaobias.com/springbootiv1oo/front/index.html 管理員:abo/abo 用戶:用戶1/123456、…

Java反序列化漏洞揭秘:從原理到攻擊實戰

一、背景 熟悉接口開發的同學一定知道,能將數據對象很輕松的實現多平臺之間的通信、對象持久化存儲,序列化和反序列化是一種非常有效的手段,例如如下應用場景,對象必須 100% 實現序列化。 DUBBO:對象傳輸必須要實現序…

Time-MOE 音頻序列分類任務

prompt 我準備做語音疾病分類任務。語音音頻是 WAV 格式的音頻,基本上分為兩類,分別是疾病類和非疾病類。也有少數數據集是多分類,現在我找到了26個數據集,我準備我已經在 MLP CNN 上面測試了它們的基準,下面我找到了一…

[嵌入式embed][Qt]Qt5.12+Opencv4.x+Cmake4.x_測試Qt編譯的opencv4.x的庫

[嵌入式embed][Qt]Qt5.12Opencv4.xCmake4.x_測試Qt編譯的opencv4.x的庫編譯Qt-Opencv庫測試流程-①創建一個簡單的qt-ui工程配置 & 測試配置庫編譯環境測試代碼百度云-工程(opencv4.xqt5.12的工程)參考文檔編譯Qt-Opencv庫 [嵌入式embed][Qt]Qt5.12Opencv4.xCmake4.x_用Qt…

相較于傳統AR礦物鑒定有哪些優勢?

與傳統的礦物鑒定方法相比,AR礦物鑒定就像是一位全面升級的“超級助手”,展現出了無可比擬的優勢。傳統的礦物鑒定方法,往往依賴于地質學家或專業鑒定人員的豐富經驗。他們需要通過肉眼觀察礦物的顏色、光澤、硬度等物理特征,再結…

第5節:分布式文件存儲

本節主要是講解的是分布式文件存儲,主要介紹了阿里云OSS云存儲和Minio文件存儲,本章重點主要是掌握怎么在SpringBoot項目里面接入文件存儲。 記錄、交流、實踐,讓每一份付出皆可看見,讓你我共同前行😁 1.分布式文件存…

當 GitHub 宕機時,我們如何協作?

一、引言1.1 GitHub 的重要性及宕機影響在當今軟件開發的生態系統中,GitHub 已然成為全球開發者不可或缺的核心平臺。它為無數開源項目與企業級開發團隊提供了高效的代碼托管、版本控制、協作開發以及項目管理等服務。然而,2025 年 8 月那場波及全球的 G…