????????最近在寫一個軟件,這個軟件稍微復雜一些,界面大概需要十幾個,后端也是要開多線程讀各種傳感器數據。然后鼠鼠我呀就發現一個致命的問題,那就是前端要求的控件太多了,點一下就需要通知后端,即調用后端的函數,這是非常不友好的。因為耦合程度太高了,交互起來過于混亂嚴重影響開發進度。如果是一個人設計的可能稍微好一些(一個按鈕實現一個函數唄),但是如果是團隊分工的話就會很麻煩。后面問了大佬,大佬給我提供了一個思路,然后我會又去問了GPT。把相關的方法也寫進來了。準備寫個小合集,現在這里占個坑,后面在慢慢補齊。
? ? ? ? 大佬最后還給了一個建議:
????????要解耦,就不要想到什么功能立馬實現地態度創建文件寫實現,而是需要抱著寫庫的思路去寫功能,把庫(模塊)寫的差不多了再利用界面去調用接口
目錄
? 1. 信號與槽機制(Signals & Slots) ?【小工程推薦】
? 特點:
? 示例:
? 2. 事件總線 / 消息中心(Event Bus / Message Center) ?【適合全局廣播】
? 特點:
? 示例實現:
? 3. 觀察者模式(Observer Pattern) 🧩【設計模式基礎】
? 特點:
? 4. 發布-訂閱模式(Pub-Sub Pattern) 🗞?【帶中介的觀察者模式】
? 特點:
? 5. 自定義 QEvent + 事件投遞機制(高級/底層)
? 特點:
? 6. MVC/MVVM 架構分層
? 特點:
? 7. 前后端分離架構(Frontend-Backend Separation)
? 模型
? 可選實現方式(C++ 服務端):
? 總結對比表:
? Qt 中前后端通信與解耦方式對比(含跨進程/語言)
? 各方法適用范圍速覽:
? 推薦使用建議:
? Qt 多線程通信方法對比表
這里是邪惡的分界線
? 1. 信號與槽機制(Signals & Slots) ?【小工程推薦】
? 特點:
-
Qt 原生支持
-
松耦合、線程安全(帶
QueuedConnection
) -
誰關心誰連接,不需要直接引用對象
? 示例:
connect(controller, &Controller::dataUpdated, ui, &MainWindow::updateUI);
? ? ? ? 優點:前端 UI 和后端邏輯彼此獨立,只通過信號/槽通信。
????????缺點也很明顯,一次調用就需要寫對應的信號函數和槽函數。UI界面如果功能要求很多的情況下會與其他的模塊過于耦合。甚至改了一個點,代碼就立即崩潰。
? 拓展:配合定時器實現定時巡查:
connect(mTimer, &QTimer::timeout, this, &類::onTimerTimeout);
? 2. 事件總線 / 消息中心(Event Bus / Message Center) ?【適合全局廣播】
? 特點:
-
所有模塊注冊到一個全局消息中心
-
事件發布者和訂閱者互不依賴
-
支持“一次廣播,多方接收”
? 示例實現:
// 發出事件
MessageCenter::instance().postMessage({ MessageType::JoystickAngleChanged, QVariant::fromValue(angle) });// 監聽事件
connect(&MessageCenter::instance(), &MessageCenter::messagePosted, this, [](const Message& msg) {if (msg.type == MessageType::JoystickAngleChanged) {float angle = msg.data.toFloat();// 處理邏輯}
});
? 3. 觀察者模式(Observer Pattern) 🧩【設計模式基礎】
? 特點:
-
手動實現:主題維護一組觀察者列表
-
經典設計模式思想
-
不依賴 Qt,可用于非 QObject 類
Qt 的信號槽就是觀察者模式的升級版
? 4. 發布-訂閱模式(Pub-Sub Pattern) 🗞?【帶中介的觀察者模式】
? 特點:
-
和 Event Bus 類似,但更偏架構層
-
可用于模塊化插件系統或多線程模塊通信
-
可選中介:如 Qt 中心類、第三方消息庫(如
eventpp
)
? 5. 自定義 QEvent + 事件投遞機制(高級/底層)
? 特點:
-
適合底層系統級事件、跨線程通信
-
使用
QCoreApplication::postEvent()
發消息 -
接收類需重寫
QObject::event(QEvent* e)
QCoreApplication::postEvent(targetObject, new MyCustomEvent());
? 6. MVC/MVVM 架構分層
? 特點:
-
把邏輯層(Model/ViewModel)和界面層(View)徹底分離
-
使用信號/槽或綁定橋接
-
更適合大型項目
? 7. 前后端分離架構(Frontend-Backend Separation)
? 模型
客戶端-服務器通信模型 + RESTful API 或 WebSocket 通信協議
????????C++ 后端作為服務,JS 前端通過 HTTPS 調用
-
后端 C++:實現邏輯處理、設備管理、數據計算,暴露 API(通過 REST 或 WebSocket)
-
前端 JS(如 Vue/React):調用后端接口、獲取數據、展示 UI
-
通信方式:通過 HTTP(S) 請求(GET/POST/PUT/DELETE)廣義的發布-訂閱模式(或請求-響應模式)?
通信例子(REST):
POST https://localhost:8000/api/update-angle
Content-Type: application/json{"angleX": 10.5,"angleY": -2.1
}
? 可選實現方式(C++ 服務端):
技術 | 用途 |
---|---|
Cpp-REST SDK(Casablanca) | 微軟支持的 REST 服務框架 |
Crow / Drogon / Pistache | 高性能 C++ Web 框架 |
gRPC + Protobuf | 更高效的 RPC 通信,非 HTTP |
Boost.Beast / ASIO | 低層 HTTP/WebSocket 支持 |
? 總結對比表:
? Qt 中前后端通信與解耦方式對比(含跨進程/語言)
方法 | 解耦性 | 使用難度 | 推薦場景 |
---|---|---|---|
信號與槽 | ???? | ?? | 通用通信,Qt 內部模塊、UI ? 邏輯 |
事件總線(MessageCenter) | ????? | ??? | 全局通知、廣播事件,解耦多個模塊 |
觀察者模式 | ??? | ?? | 基礎設計模式,適合無 Qt 場景 |
發布-訂閱模式(帶中介) | ????? | ??? | 插件系統、熱插拔模塊、多生產者消費者場景 |
QEvent 自定義 | ??? | ???? | 底層事件處理、跨線程通信、自定義事件類型 |
MVC / MVVM 架構 | ????? | ???? | 中大型應用的分層架構設計,邏輯與表現分離 |
前后端分離(C++ + JS + HTTPS) | ????? | ???? | 跨語言/跨平臺開發,Web UI 與本地后端通信 |
? 各方法適用范圍速覽:
方法 | 是否跨模塊 | 是否跨語言 | 是否適合大型項目 | 是否線程安全 |
---|---|---|---|---|
信號與槽 | ? | ? | ?(中小) | ?(帶 QueuedConnection ) |
事件總線 | ? | ? | ? | ?(需注意線程) |
觀察者模式 | ? | ? | ?(基礎) | ?(需手動實現) |
發布-訂閱 | ? | ?(默認) | ? | ?(實現復雜) |
QEvent 自定義 | ? | ? | ?(系統級) | ? |
MVC/MVVM | ? | ?(默認) | ?? | ? |
前后端分離(HTTPS) | ?? | ?? | ??? | ?(通過 HTTP 協議) |
? 推薦使用建議:
-
🔧 輕量內部通信 → 用 Qt 自帶的 信號與槽
-
📢 多個模塊響應同一事件 → 用 事件總線 / 發布-訂閱
-
🔋 需要插件式或熱插拔功能 → 推薦 發布-訂閱模式
-
?? 跨線程通信 → 使用 QEvent 自定義 + postEvent
-
🧩 清晰結構、大型項目 → 使用 MVC/MVVM 架構
-
🌐 前后端用不同語言(如 JS + C++) → 使用 前后端分離 + HTTPS 或 WebSocket
? Qt 多線程通信方法對比表
在 多線程環境下,模塊通信和解耦機制就必須考慮以下幾個關鍵因素:
-
? 線程安全性(Thread Safety)
-
🔁 事件能否跨線程分發
-
🚧 使用復雜度 / 調試難度
-
🧵 是否自動切換線程上下文(如 UI 線程)
方法 | 跨線程能力 | 線程安全性 | 自動線程切換 | 使用難度 | 推薦場景(多線程) |
---|---|---|---|---|---|
信號與槽(QueuedConnection) | ? | ? | ?(切 UI 線程) | ?? | 后臺線程通知 UI,常用 |
事件總線(MessageCenter) | ??(需額外處理) | ?(默認) / ?(加鎖) | ? | ??? | 多模塊通信,需加鎖或用 queued signal |
觀察者模式 | ?? | ? | ? | ?? | 不推薦直接用于多線程 |
發布-訂閱模式(線程安全實現) | ? | ?(需封裝) | ?(或自處理) | ???? | 多線程模塊解耦(如后臺計算、日志分發) |
QEvent 自定義 + postEvent() | ?? | ? | ?(需手動處理) | ???? | 跨線程消息隊列,精準控制投遞目標 |
MVC / MVVM 架構 | ??(依賴實現) | ??(需要配合線程機制) | ? | ???? | 與線程模型組合使用,如后臺模型 + UI 表現 |
前后端分離(HTTPS/WebSocket) | ?(多進程) | ?(通過網絡協議) | ?(通過響應處理) | ???? | 前后端線程獨立,由服務控制線程調度 |