自定義Qt元件 通訊模組 P2

2022-02-28 12:39:06 字數 2678 閱讀 6293

抽象協議abstractprotocol定義commmanager與協議之間的介面。abstractprotocol中的一些屬性(如enabled)用於設定是否能夠處理資料。

processdata是abstractprotocol中定義的**函式,當裝置中有資料返回時,資料將會被交給該方法進行處理。

若該方法返回true,則表明當前處理資料的協議已經找到相應的資料並且不需要將資料再交給其它協議處理,commmanager便會停止向其它協議傳送這些資料;

若該方法返回為false,表明當前處理資料的協議並未找到相應的資料,並且希望交由其它協議進行處理,此時com會繼續**這些資料。

lastqueryfailed 是在查詢失敗時由協議實現類進行處理的**函式。

abstractprotocol(生產者)例項將會維護各自的命令佇列,commmanager(消費者)在完成一次查詢後拉取abstractprotocol(生產者)生成的指令。因此commmanager會根據指令消耗的速度決定是否應該進行下一次查詢。有關生產者和消費者的更多資訊,可以檢視

commfactory是通訊器的構造工廠類,要例項化某個abstractcomm的通訊器實現類,需要通過addcomm方法將通訊器註冊到commfactory中,工廠會儲存各個通訊器的實現類物件,在構造之後進行切換會嘗試找出已經構造過的物件,避免重複構造通訊器物件。

commmanager中可用的串列埠實現類物件由commfactory進行例化,通過createcomm方法將引數傳遞給工廠類的例項化方法,獲取可用的實現類物件指標。

comm層作為庫,暴露給其它**使用的部分主要是commmanager,因此要在程式執行時改變串列埠工作模式或切換成網路介面,呼叫 commmanager::resetmode 方法即可。

若該模組內部已經有實現好的通訊器,則可以呼叫 commmanager::resetmode(const qstring &type, const bool halfduplex),根據型別和全/半雙工模式選擇特定的通訊器,若要使用擴充套件的自定義通訊器,可以使用 commmanager::resetmode(const qstring &classname) 傳入具體的類名選擇通訊器。

如果需要新增新的通訊器,建立乙個繼承於abstractcomm的子類(建構函式需要用q_invokable修飾),通過addcomm方法將元物件和描述資訊新增到工廠類中,之後可以傳遞類名來構造其它的通訊器。

構造工廠的使用使得commmanager只用傳遞類名或通訊器型別即可獲得通訊器物件,從而使commmanager的功能只需要對通訊器物件進行管理和收發資料,簡化commmanager 的實現。

虛擬串列埠virtualcom是為了方便上位機單獨進行除錯而編寫的abstractcom的子類。以虛擬串列埠為例,介紹如何繼承實現abstractcom的子類,以設計新模式的串列埠。

虛擬串列埠virtualcom的介面:

如圖所示,virtualcom的init(), close(), opencomm, writecmd, setcommproperty, query, onread等方法都是繼承自abstractcom的介面(在方法宣告後增加了 q_decl_override巨集,即override 關鍵字)。

init()方法中進行成員變數的初始化(多執行緒中的qiodevice只能在建立其實例的執行緒中進行操作,否則在執行時會警告/報錯),需要在該方法中可以例項化qtimer,qserialport或qtcpsocket等物件(這些物件不能在建構函式中例項化)。

虛擬串列埠中沒有使用到串列埠物件,因此不需要例項化串列埠/qiodevice物件,這裡的init方法中例項化timer物件並連線相應的訊號和槽。

opencomm方法用於開啟裝置(串列埠/socket),由於虛擬串列埠中沒有串列埠物件,這裡只修改裝置狀態即可。開啟虛擬串列埠後,timer開始計時。

開啟串列埠後即可呼叫write寫入命令:一般該方法只需要傳遞引數給query函式執行即可,但半雙工模式下,需要儲存指令,待線路空閒時傳送。

若接受到命令後可以立即查詢,那麼需要通過qmetaobject::invokemethod靜態方法在子執行緒中執行(以致訪問串列埠/socket物件時不會出現錯誤)。虛擬串列埠中的該方法就是將cmd引數傳遞給query方法通過子執行緒執行。

要使用虛擬串列埠傳送一些特定的資料,需要修改virtualcom的實現,在實際使用過程中比較麻煩。目前可用的解決方法有兩個:

把虛擬串列埠編譯成動態鏈結庫,在不同的程式中使用不同的動態庫檔案即可,但是這樣做實際上在開發過程中變得非常麻煩。

自定義xml檔案格式,從指定的xml檔案中讀取資訊,根據資訊來決定傳送的資料內容,這樣的話就能夠使virtualcom作為庫檔案與實際的資訊回覆實現分離。如果要這樣實現,首先要定義xml檔案的格式,然後編寫相應的解析器,並將解析器解析的結果傳遞給virtualcom物件,當接收到來自上層的指令後根據解析器的結果進行響應。這樣做實際上是在模擬下位機收發資料的行為,看上去工作量較大,但比較實際的下位機應用應該是簡單不少了。

自定義元件,元件通訊

在專案開發時,採用元件化得思想開發,搭建專案時,src下有views目錄,一般放頁面級元件,在建立乙個comment目錄來放公共元件,比如頭部元件和底部元件,然後在建立乙個feature目錄來放功能元件,比如輪播元件,上拉載入更多元件,搜尋元件,tabbar元件等,元件提公升專案得開發效率,解決了傳...

自定義元件 元件通訊及cli

案例 封裝乙個 loading 元件 loading是用來做什麼的?基於使用者體驗 loading使用方式很多 第三方的ui庫 元件庫 自定義封裝 過程 建立乙個目錄資料夾,稱之為loading 在loading中建立乙個叫做component目錄,用來放模板 在loading目錄下建立乙個inde...

qt自定義控制項 2

環境 qtcreator 4.0.2 qt5.7.0 msvc 2013,32bit 步驟 1 在上篇文章的基礎上,我們在demo1自定義控制項類中新增如下 q enums m id q property qstring m id read get id write set id private q...