瀏覽代碼

experimenting with changeable native window
fails because queue is not passed to uvicorn subprocess when reload=True

Rodja Trappe 2 年之前
父節點
當前提交
07cf2e27ae
共有 2 個文件被更改,包括 73 次插入6 次删除
  1. 43 1
      nicegui/native.py
  2. 30 5
      nicegui/native_mode.py

+ 43 - 1
nicegui/native.py

@@ -1,10 +1,52 @@
+import inspect
+import types
 from dataclasses import dataclass, field
-from typing import Any, Dict
+from multiprocessing import Queue
+from typing import Any, Dict, Optional
+
+import webview
 
 from .helpers import KWONLY_SLOTS
 
+q_in = Queue()
+q_out = Queue()
+
+
+def create_proxy(cls):
+    class Proxy:
+        def __getattr__(self, name):
+            if name.startswith('__'):
+                return super().__getattr__(name)
+
+            print(f"Attribute get: {name}")
+
+        def __setattr__(self, name, value):
+            if name.startswith('__'):
+                super().__setattr__(name, value)
+                return
+
+            print(f"Attribute set: {name} = {value}")
+            q_in.put(('some_method', (42,), {}))
+            # result = q_out.get()
+
+    def mock_method(name):
+        def wrapper(*args, **kwargs):
+            print(f"Method called: {name}")
+        return wrapper
+
+    for name, attr in inspect.getmembers(cls):
+        if name.startswith('__'):
+            continue
+
+        if inspect.isfunction(attr) or inspect.ismethod(attr):
+            setattr(Proxy, name, mock_method(name))
+
+    return Proxy
+
 
 @dataclass(**KWONLY_SLOTS)
 class Native:
+
     start_args: Dict[str, Any] = field(default_factory=dict)
     window_args: Dict[str, Any] = field(default_factory=dict)
+    window: webview.Window = create_proxy(webview.Window)()

+ 30 - 5
nicegui/native_mode.py

@@ -1,5 +1,7 @@
 import _thread
+import logging
 import multiprocessing
+import queue
 import socket
 import sys
 import tempfile
@@ -7,7 +9,7 @@ import time
 import warnings
 from threading import Thread
 
-from . import globals, helpers
+from . import globals, helpers, native
 
 try:
     with warnings.catch_warnings():
@@ -18,7 +20,8 @@ except ModuleNotFoundError:
     pass
 
 
-def open_window(host: str, port: int, title: str, width: int, height: int, fullscreen: bool) -> None:
+def open_window(host: str, port: int, title: str, width: int, height: int, fullscreen: bool,
+                q_in: multiprocessing.Queue, q_out: multiprocessing.Queue) -> None:
     while not helpers.is_port_open(host, port):
         time.sleep(0.1)
 
@@ -26,7 +29,24 @@ def open_window(host: str, port: int, title: str, width: int, height: int, fulls
     window_kwargs.update(globals.app.native.window_args)
 
     try:
-        webview.create_window(**window_kwargs)
+        window = webview.create_window(**window_kwargs)
+        print('--------------------starting thread', flush=True)
+
+        def process_bridge():
+            time.sleep(1)
+            while True:
+                print('getting', flush=True)
+                try:
+                    result = q_in.get(block=False)
+                    print(result, flush=True)
+                except queue.Empty:
+                    print('empty', flush=True)
+                    time.sleep(1)
+                # result = getattr(window, method_name)(*args, **kwargs)
+                # q_out.put(result)
+        t = Thread(target=process_bridge)
+        t.start()
+
         webview.start(storage_path=tempfile.mkdtemp(), **globals.app.native.start_args)
     except NameError:
         print('Native mode is not supported in this configuration. Please install pywebview to use it.')
@@ -43,9 +63,14 @@ def activate(host: str, port: int, title: str, width: int, height: int, fullscre
         _thread.interrupt_main()
 
     multiprocessing.freeze_support()
-    process = multiprocessing.Process(target=open_window, args=(host, port, title, width, height, fullscreen),
-                                      daemon=False)
+    process = multiprocessing.Process(
+        target=open_window,
+        args=(host, port, title, width, height, fullscreen, native.q_in, native.q_out),
+        daemon=False
+    )
     process.start()
+    native.q_in.put(('some_method', (42,), {}))
+
     Thread(target=check_shutdown, daemon=True).start()