基於任務 API 的 Web 自定義頁

應用可以新增瀏覽器頁面,而不需要匯入 FastAPI,也不能直接訪問 TaskExecutor。公開 API 將後端行為與介面後設資料分開:

  • WebCustomTab 是 Python 後端,使用正常的任務生命週期和任務 API。
  • WebTabConfig 描述導航位置和前端資源。
  • task_tab_querytask_tab_action 明確宣告瀏覽器可以呼叫的方法。

Qt 與 Web 使用獨立配置:custom_tabs 只屬於 Qt,web_tabs 只屬於 Web。

定義後端

from pathlib import Path

from ok import WebCustomTab, WebTabConfig, task_tab_action, task_tab_query


class ExampleWebTab(WebCustomTab):
    web_tab = WebTabConfig(
        id="example",
        name="Example",
        asset_dir=Path(__file__).with_name("example_web"),
        icon="code",
        task_controls=False,
    )

    @task_tab_query("state")
    def state(self):
        return {"message": "Hello"}

    @task_tab_action("save")
    def save(self, payload):
        value = str(payload.get("value", ""))
        self.emit_web_event("saved", {"value": value})
        return {"value": value}

公開的方法只能不接收引數,或接收一個字典引數。操作名必須以小寫字母 開頭,並且只能包含小寫字母、數字、_-。返回值和事件資料必須 可以序列化為 JSON。未新增裝飾器的方法無法從瀏覽器呼叫。

WebCustomTab 還可以使用 self.config、日誌、翻譯、get_tasks()emit_web_event() 等任務 API。它不會顯示在普通任務列表中,也不能被 計劃任務排程。

註冊頁面

config = {
    "web_tabs": [["src.ui.ExampleWebTab", "ExampleWebTab"]],
}

web_tabs 中的類必須繼承 WebCustomTab,並且只會在 Web UI 模式下 載入。同時支援 Qt 和 Web 時應分別配置:

config = {
    "custom_tabs": [["src.gui.ExampleTab", "ExampleTab"]],  # 仅 Qt
    "web_tabs": [["src.ui.ExampleWebTab", "ExampleWebTab"]],  # 仅 Web
}

WebTabConfig 欄位

欄位 作用
id 穩定的 URL 標識,只能使用小寫字母、數字和單個連字元。
name 左側導航名稱;翻譯目錄存在對應文本時由宿主翻譯。
asset_dir 瀏覽器模組及其私有靜態資源所在目錄。
entrypoint 宿主載入的 ES 模組,預設為 index.js
icon 宿主圖示名,例如 codesettingsimagecalendarplay
position scroll 表示主導航,bottom 表示固定在導航底部。
add_after_default_tabs 放在 Triggers/Tasks 之前或緊接其後,預設為 True
task_controls 頁面是否使用可執行任務控制;純管理頁面應設為 False

啟動時會驗證資源目錄和入口檔案,入口檔案不能跳出 asset_dir

定義瀏覽器模組

入口模組必須匯出 mount(container, context),並且可以返回清理函式:

export function mount(container, context) {
  container.textContent = context.t("Loading");

  context.query("state").then((state) => {
    container.textContent = state.message;
  });

  const unsubscribe = context.subscribe((event) => {
    if (event.name === "saved") console.log(event.payload);
  });

  return () => unsubscribe();
}

context 提供以下介面:

API 作用
tab 當前頁面的只讀清單。
query(name, payload?) 呼叫一個 task_tab_query
action(name, payload?) 呼叫一個 task_tab_action
task 啟動、暫停、繼續、停止、讀取或配置可執行任務;僅在 task_controls=True 時使用。
subscribe(handler) 接收當前頁面的事件,並返回取消訂閱函式。
notify(message, intent) 顯示 successinfoerror 通知。
t(message, params?) 翻譯宿主目錄中的文本。
locale / theme 當前語言和 light/dark 主題。
setDirty(boolean) 接入宿主的未儲存修改導航保護。
registerSave(callback) 註冊導航保護使用的非同步儲存函式。

頁面應使用 --accent--card-bg--card-hover--stroke--selected--text-muted 等宿主 CSS 變數適配主題。

普通的 BaseTask 如果已經通過 onetime_taskstrigger_tasks 註冊, 也可以宣告 web_tab = WebTabConfig(...),為可執行任務提供自定義控制頁。 這種任務不需要再次新增到 web_tabs

瀏覽器不會獲得 executor 或任意 Python 物件。只有顯式裝飾的方法和受限 任務控制介面可以通過 HTTP 呼叫。除非已經新增認證和可信反向代理,否則 Web 服務應只監聽本機地址。

在 GitHub 查看來源 ↗ · 頁面產生時間: 2026年8月15日