這個應用程式的核心是 NodeGraphQt 函式庫,它讓使用者可以像在流程圖中一樣,拖拉節點並將它們連接起來,形成一個完整的處理流程。 以下將程式碼拆解成各個主要部分進行說明: 1. 總體結構與依賴 (Overall Structure & Dependencies) 程式碼的頂部引入了必要的函式庫: PyQt5: 用於建立整個桌面應用程式的圖形介面 (GUI),包括視窗、按鈕、輸入框等所有視覺元件。 NodeGraphQt: 這是核心,一個專為建立節點式圖形化介面而設計的函式庫。它提供了節點圖(Node Graph)、節點(Node)和屬性編輯器(Properties Bin)等基礎建設。 sys, json, os: Python 的標準函式庫,分別用於系統互動、處理 JSON 資料(用於儲存/載入管線)和作業系統相關功能(如處理檔案路徑)。 2. 外觀與風格 (Appearance & Styling) HARMONIOUS_THEME_STYLESHEET: 這是一個非常長的字串,包含了 QSS(Qt Style Sheets,類似於網頁的 CSS)。它定義了整個應用程式的外觀,包括顏色、字體、邊框、圓角等,創造了一個現代化且風格統一的深色主題(Dark Mode)。這使得所有 UI 元件看起來都非常和諧。 3. 自訂節點類別 (Custom Node Classes) 這是應用程式的核心業務邏輯。開發者繼承了 NodeGraphQt 的 BaseNode,定義了幾種代表 ML 管線中不同處理步驟的節點。 InputNode: 代表資料來源,例如攝影機、麥克風或檔案。 PreprocessNode: 代表前處理節點,負責在模型推論前處理資料,如調整圖片大小、正規化等。 ModelNode: 代表模型推論節點,是執行核心 AI 運算的地方。它有模型路徑、使用的硬體 (dongle) 數量等屬性。 PostprocessNode: 代表後處理節點,負責處理模型輸出,如過濾結果、轉換格式等。 OutputNode: 代表最終的輸出點,例如將結果存成檔案或傳送到某個 API。 在每個節點的 __init__ 方法中: add_input() 和 add_output(): 定義節點的輸入/輸出埠,用於連接其他節點。 set_color(): 設定節點在圖形介面中的顏色,以方便區分。 create_property(): 這是關鍵。這個方法為節點定義了「業務屬性」(Business Properties)。例如,ModelNode 有 model_path、num_dongles 等屬性。這些屬性可以在 UI 上被使用者編輯。 _property_options: 一個字典,用來定義屬性編輯器該如何呈現這些屬性(例如,提供一個下拉選單、設定數值的最大最小值、或提供檔案選擇按鈕)。 4. 核心 UI 元件 (Core UI Components) 這些是構成主視窗的各個面板和視窗。 DashboardLogin (啟動儀表板) 用途: 這是應用程式的進入點,一個歡迎畫面或啟動器。 功能: 提供 "Create New Pipeline"(建立新管線)和 "Edit Previous Pipeline"(編輯舊管線)的選項。 顯示最近開啟過的檔案列表 (.mflow 檔)。 當使用者選擇建立或開啟後,它會實例化並顯示 IntegratedPipelineDashboard 主視窗。 IntegratedPipelineDashboard (整合式主視窗) 用途: 這是應用程式最主要、功能最完整的操作介面。 佈局: 它採用一個三欄式佈局(使用 QSplitter): 左側面板 (Node Templates): 顯示所有可用的節點類型(Input, Model 等),使用者點擊按鈕即可在中間的編輯器中新增節點。 中間面板 (Pipeline Editor): 這是 NodeGraphQt 的主畫布,使用者可以在這裡拖動、連接節點,建立整個 ML 管線。 右側面板 (Configuration Tabs): 一個頁籤式視窗,包含了多個設定面板: Properties: 最重要的頁籤。當使用者在中間的畫布上選中一個節點時,這裡會動態顯示該節點的所有「業務屬性」並提供對應的編輯工具(輸入框、下拉選單、滑桿等)。這是由 update_node_properties_panel 方法動態生成的。 Stages: 設定管線的「階段」(Stage),可以將多個節點分配到不同階段。 Performance: 顯示模擬的效能指標,如 FPS、延遲等。 Dongles: 管理硬體加速器 (dongle) 的分配。 PipelineEditor (另一個主視窗版本) 用途: 這看起來是 IntegratedPipelineDashboard 的一個較早期或替代版本。它也提供了一個節點編輯器,但它的屬性編輯器 (CustomPropertiesWidget) 是一個可以停靠 (dockable) 的獨立視窗,而不是整合在右側的頁籤中。 CustomPropertiesWidget (自訂屬性編輯器) 用途: 這個類別被 PipelineEditor 使用,它取代了 NodeGraphQt 預設的屬性面板。 功能: 它監聽節點被選中的事件 (node_selection_changed)。 當節點被選中時,它會讀取節點的 custom 屬性和 _property_options 字典。 根據屬性的類型和選項,動態地建立對應的 UI 元件(如 QLineEdit, QComboBox, QSpinBox)。 提供 "Apply" 和 "Reset" 按鈕來儲存或重置屬性。 5. 對話方塊 (Dialogs) 這些是彈出式視窗,用於完成特定任務。 CreatePipelineDialog: 一個簡單的表單,讓使用者輸入新專案的名稱和描述。 StageConfigurationDialog: 一個更複雜的對話方塊,用於將管線劃分為多個「階段」,並為每個階段分配資源(如 dongle 數量)。 PerformanceEstimationPanel & SaveDeployDialog: 流程中的後續步驟,用於效能分析和最終部署配置的儲存。 6. 程式啟動點 (Execution Block) Python if __name__ == '__main__': # ... app.setFont(QFont("Arial", 9)) dashboard = DashboardLogin() dashboard.show() sys.exit(app.exec_()) if __name__ == '__main__':: 這是 Python 程式的標準入口。當這個 UI.py 檔案被直接執行時,這段程式碼會被觸發。 app = QApplication(sys.argv): 建立 PyQt 應用程式的實例,這是任何 PyQt UI 執行的第一步。 dashboard = DashboardLogin(): 建立我們設計的啟動器視窗。 dashboard.show(): 顯示這個視窗。 sys.exit(app.exec_()): 啟動應用程式的事件迴圈 (event loop)。程式會停在這裡,等待並處理使用者的操作(如點擊、輸入等),直到使用者關閉視窗,程式才會結束。