pyloid 0.20.2.dev2__py3-none-any.whl → 0.22.0.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pyloid/browser_window.py CHANGED
@@ -8,13 +8,11 @@ from PySide6.QtWebChannel import QWebChannel
8
8
  from PySide6.QtGui import (
9
9
  QKeySequence,
10
10
  QShortcut,
11
- QCursor,
12
11
  )
13
- from PySide6.QtCore import Qt, QPoint, QUrl, QEvent, QFile
12
+ from PySide6.QtCore import Qt, QPoint, QUrl, QEvent, QFile, QEventLoop, QTimer, QObject, Signal, Slot
14
13
  from PySide6.QtWebEngineCore import (
15
14
  QWebEnginePage,
16
15
  QWebEngineSettings,
17
- QWebEngineUrlRequestInterceptor,
18
16
  )
19
17
  from .api import PyloidAPI
20
18
  import uuid
@@ -25,18 +23,16 @@ from PySide6.QtWidgets import (
25
23
  QVBoxLayout,
26
24
  )
27
25
  from .custom.titlebar import CustomTitleBar
28
- from .js_api.window_api import WindowAPI
26
+ from .js_api.base import BaseAPI
29
27
  from PySide6.QtGui import QPixmap, QMovie
30
28
  from PySide6.QtWidgets import QSplashScreen, QLabel
31
- from PySide6.QtCore import QSize
32
- from typing import TYPE_CHECKING
33
- from PySide6.QtWebEngineCore import QWebEngineSettings
29
+ from typing import TYPE_CHECKING, Any
30
+ from PySide6.QtWebEngineCore import QWebEngineSettings, QWebEngineDesktopMediaRequest
34
31
 
35
32
  if TYPE_CHECKING:
36
- from ..pyloid import Pyloid
33
+ from .pyloid import _Pyloid
37
34
 
38
35
 
39
- # 어차피 load 부분에만 쓰이니까 나중에 분리해서 load 위에서 선언하자.
40
36
  class CustomWebPage(QWebEnginePage):
41
37
  def __init__(self, profile=None):
42
38
  super().__init__(profile)
@@ -47,11 +43,11 @@ class CustomWebPage(QWebEnginePage):
47
43
  self._url_handlers = {} # URL 핸들러 저장을 위한 딕셔너리 추가
48
44
 
49
45
  # interceptor ( all url request )
50
- self.interceptor = CustomUrlInterceptor()
51
- self.profile().setUrlRequestInterceptor(self.interceptor)
46
+ # self.interceptor = CustomUrlInterceptor()
47
+ # self.profile().setUrlRequestInterceptor(self.interceptor)
52
48
 
53
49
  def _handlePermissionRequest(self, origin: QUrl, feature: QWebEnginePage.Feature):
54
- print(origin, feature)
50
+ # print(origin, feature)
55
51
 
56
52
  """Default permission request handler"""
57
53
  if feature in self._permission_handlers:
@@ -68,44 +64,86 @@ class CustomWebPage(QWebEnginePage):
68
64
  """Register a handler for a specific permission"""
69
65
  self._permission_handlers[feature] = handler
70
66
 
71
- def _handleDesktopMediaRequest(self, *args, **kwargs):
72
- print("Desktop media request received:", args, kwargs)
73
-
74
- # interceptor ( navigation request )
75
- def acceptNavigationRequest(self, url, navigation_type, is_main_frame):
76
- """네비게이션 요청을 처리하는 메서드"""
77
- print(f"Navigation Request - URL: {url.toString()}")
78
- print(f"Navigation Type: {navigation_type}")
79
- print(f"Is Main Frame: {is_main_frame}")
80
-
81
- # # URL이 구글이 아닐 경우에만 구글로 리다이렉트
82
- # if "example.com" not in url.toString():
83
- # self.setUrl(QUrl("https://www.example.com"))
84
- # return False
85
-
86
- return True
87
-
88
- def add_url_handler(self, pattern: str, handler):
89
- """URL 패턴에 대한 핸들러 등록
90
-
91
- Parameters:
92
- -----------
93
- pattern : str
94
- 정규표현식 패턴
95
- handler : callable
96
- URL을 인자로 받고 bool을 반환해야 함
97
- True를 반환하면 네비게이션을 허용, False를 반환하면 차단
98
- """
99
- import re
100
-
101
- self._url_handlers[re.compile(pattern)] = handler
67
+ def _handleDesktopMediaRequest(self, request: QWebEngineDesktopMediaRequest):
68
+ return
69
+ print("Desktop media request received:", request)
70
+
71
+ # 사용 가능한 화면 목록 확인
72
+ screens_model = request.screensModel()
73
+ print("\n=== Available Screens ===")
74
+ for i in range(screens_model.rowCount()):
75
+ screen_index = screens_model.index(i)
76
+ screen_name = screens_model.data(screen_index)
77
+ print(f"Screen {i}: {screen_name}")
78
+
79
+ # 사용 가능한 창 목록 확인
80
+ windows_model = request.windowsModel()
81
+ print("\n=== Available Windows ===")
82
+ for i in range(windows_model.rowCount()):
83
+ window_index = windows_model.index(i)
84
+ window_name = windows_model.data(window_index)
85
+ print(f"Window {i}: {window_name}")
86
+
87
+ request.selectWindow(windows_model.index(3))
88
+
89
+ # # interceptor ( navigation request )
90
+ # def acceptNavigationRequest(self, url, navigation_type, is_main_frame):
91
+ # """네비게이션 요청을 처리하는 메서드"""
92
+ # print(f"Navigation Request - URL: {url.toString()}")
93
+ # print(f"Navigation Type: {navigation_type}")
94
+ # print(f"Is Main Frame: {is_main_frame}")
95
+
96
+ # return True
102
97
 
103
98
 
104
99
  # interceptor ( all url request )
105
- class CustomUrlInterceptor(QWebEngineUrlRequestInterceptor):
106
- def interceptRequest(self, info):
107
- url = info.requestUrl().toString()
108
- print(url)
100
+ # class CustomUrlInterceptor(QWebEngineUrlRequestInterceptor):
101
+ # def interceptRequest(self, info):
102
+ # url = info.requestUrl().toString()
103
+ # print(url)
104
+
105
+ # class CustomInterceptor(QWebEngineUrlRequestInterceptor):
106
+ # def __init__(self, index_path=None):
107
+ # super().__init__()
108
+ # self.index_path = get_production_path()
109
+ # self.last_path = "/"
110
+
111
+ # def interceptRequest(self, info):
112
+ # url = info.requestUrl()
113
+ # navigation_type = info.navigationType()
114
+
115
+ # print("--------------------------------")
116
+
117
+ # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeTyped:
118
+ # print("NavigationTypeTyped")
119
+
120
+ # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeReload:
121
+ # print("NavigationTypeReload")
122
+
123
+ # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeBackForward:
124
+ # print("NavigationTypeBackForward")
125
+
126
+ # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeLinkClicked:
127
+ # print("NavigationTypeLinkClicked")
128
+
129
+ # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeFormSubmitted:
130
+ # print("NavigationTypeFormSubmitted")
131
+
132
+ # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeTyped:
133
+ # print("NavigationTypeTyped")
134
+
135
+ # if navigation_type == QWebEnginePage.NavigationType.NavigationTypeOther:
136
+ # print("NavigationTypeOther")
137
+
138
+ # print(navigation_type.value)
139
+
140
+ # print(url)
141
+ # print(url.scheme())
142
+ # print(url.host())
143
+ # print(url.url())
144
+ # print(self.last_path)
145
+
146
+ # self.last_path = url.path()
109
147
 
110
148
 
111
149
  class CustomWebEngineView(QWebEngineView):
@@ -250,10 +288,10 @@ class CustomWebEngineView(QWebEngineView):
250
288
  self.resize_start_pos = global_pos
251
289
 
252
290
 
253
- class BrowserWindow:
291
+ class _BrowserWindow:
254
292
  def __init__(
255
293
  self,
256
- app: "Pyloid",
294
+ app: "_Pyloid",
257
295
  title: str = "pyloid app",
258
296
  width: int = 800,
259
297
  height: int = 600,
@@ -280,7 +318,7 @@ class BrowserWindow:
280
318
  self.frame = frame
281
319
  self.context_menu = context_menu
282
320
  self.dev_tools = dev_tools
283
- self.js_apis = [WindowAPI()]
321
+ self.js_apis = [BaseAPI(self.id, self.app.data)]
284
322
  for js_api in js_apis:
285
323
  self.js_apis.append(js_api)
286
324
  self.shortcuts = {}
@@ -432,6 +470,13 @@ class BrowserWindow:
432
470
 
433
471
  # Set F12 shortcut
434
472
  self.set_dev_tools(self.dev_tools)
473
+
474
+ # 프로필 가져오기 및 인터셉터 설정
475
+ profile = self.web_view.page().profile()
476
+
477
+ # # 기존 인터셉터가 있다면 제거
478
+ # if self.interceptor:
479
+ # profile.setUrlRequestInterceptor(None)
435
480
 
436
481
  def _on_load_finished(self, ok):
437
482
  """Handles the event when the web page finishes loading."""
@@ -821,9 +866,9 @@ class BrowserWindow:
821
866
 
822
867
  def _remove_from_app_windows(self):
823
868
  """Removes the window from the app's window list."""
824
- if self in self.app.windows:
825
- self.app.windows.remove(self)
826
- if not self.app.windows:
869
+ if self in self.app.windows_dict:
870
+ self.app.windows_dict.pop(self.id)
871
+ if not self.app.windows_dict:
827
872
  self.app.quit() # Quit the app if all windows are closed
828
873
 
829
874
  ###########################################################################################
@@ -863,11 +908,14 @@ class BrowserWindow:
863
908
  >>> window = app.create_window("pyloid-window")
864
909
  >>> window.focus()
865
910
  """
911
+ was_on_top = bool(self._window.windowFlags() & Qt.WindowStaysOnTopHint)
912
+ if not was_on_top:
913
+ self._window.setWindowFlag(Qt.WindowStaysOnTopHint, True)
914
+ self._window.show()
866
915
  self._window.activateWindow()
867
- self._window.raise_()
868
- self._window.setWindowState(
869
- self._window.windowState() & ~Qt.WindowMinimized | Qt.WindowActive
870
- )
916
+ if not was_on_top:
917
+ self._window.setWindowFlag(Qt.WindowStaysOnTopHint, False)
918
+ self._window.show()
871
919
 
872
920
  def show_and_focus(self):
873
921
  """
@@ -879,12 +927,14 @@ class BrowserWindow:
879
927
  >>> window = app.create_window("pyloid-window")
880
928
  >>> window.show_and_focus()
881
929
  """
882
- self._window.show()
930
+ was_on_top = bool(self._window.windowFlags() & Qt.WindowStaysOnTopHint)
931
+ if not was_on_top:
932
+ self._window.setWindowFlag(Qt.WindowStaysOnTopHint, True)
933
+ self._window.show()
883
934
  self._window.activateWindow()
884
- self._window.raise_()
885
- self._window.setWindowState(
886
- self._window.windowState() & ~Qt.WindowMinimized | Qt.WindowActive
887
- )
935
+ if not was_on_top:
936
+ self._window.setWindowFlag(Qt.WindowStaysOnTopHint, False)
937
+ self._window.show()
888
938
 
889
939
  def close(self):
890
940
  """
@@ -1126,9 +1176,9 @@ class BrowserWindow:
1126
1176
  ###########################################################################################
1127
1177
  # Event (Calling the JS from Python)
1128
1178
  ###########################################################################################
1129
- def emit(self, event_name, data: Optional[Dict] = None):
1179
+ def invoke(self, event_name, data: Optional[Dict] = None):
1130
1180
  """
1131
- Emits an event to the JavaScript side.
1181
+ Invokes an event to the JavaScript side.
1132
1182
 
1133
1183
  Parameters
1134
1184
  ----------
@@ -1144,7 +1194,7 @@ class BrowserWindow:
1144
1194
  app = Pyloid(app_name="Pyloid-App")
1145
1195
 
1146
1196
  window = app.create_window("pyloid-window")
1147
- window.emit("customEvent", {"message": "Hello, Pyloid!"})
1197
+ window.invoke("customEvent", {"message": "Hello, Pyloid!"})
1148
1198
 
1149
1199
  app.run()
1150
1200
  ```
@@ -1526,52 +1576,52 @@ class BrowserWindow:
1526
1576
  ###########################################################################################
1527
1577
  # For Custom Pyside6 Features
1528
1578
  ###########################################################################################
1529
- def get_QMainWindow(self) -> QMainWindow:
1530
- """
1531
- Returns the QMainWindow object of the window.
1579
+ # def get_QMainWindow(self) -> QMainWindow:
1580
+ # """
1581
+ # Returns the QMainWindow object of the window.
1532
1582
 
1533
- you can use all the features of QMainWindow for customizing the window.
1583
+ # you can use all the features of QMainWindow for customizing the window.
1534
1584
 
1535
- Returns
1536
- -------
1537
- QMainWindow
1538
- QMainWindow object of the window
1585
+ # Returns
1586
+ # -------
1587
+ # QMainWindow
1588
+ # QMainWindow object of the window
1539
1589
 
1540
- Examples
1541
- --------
1542
- ```python
1543
- from PySide6.QtCore import Qt
1544
- from pyloid import Pyloid
1590
+ # Examples
1591
+ # --------
1592
+ # ```python
1593
+ # from PySide6.QtCore import Qt
1594
+ # from pyloid import Pyloid
1545
1595
 
1546
- app = Pyloid(app_name="Pyloid-App")
1596
+ # app = Pyloid(app_name="Pyloid-App")
1547
1597
 
1548
- window = app.create_window("pyloid-window")
1549
- qmain = window.get_QMainWindow()
1598
+ # window = app.create_window("pyloid-window")
1599
+ # qmain = window.get_QMainWindow()
1550
1600
 
1551
- qmain.setWindowFlags(qmain.windowFlags() | Qt.WindowStaysOnTopHint) # window stays on top
1552
- ```
1553
- """
1554
- return self._window
1601
+ # qmain.setWindowFlags(qmain.windowFlags() | Qt.WindowStaysOnTopHint) # window stays on top
1602
+ # ```
1603
+ # """
1604
+ # return self._window
1555
1605
 
1556
- def get_QWebEngineView(self) -> CustomWebEngineView:
1557
- """
1558
- Returns the CustomWebEngineView object which inherits from QWebEngineView.
1606
+ # def get_QWebEngineView(self) -> CustomWebEngineView:
1607
+ # """
1608
+ # Returns the CustomWebEngineView object which inherits from QWebEngineView.
1559
1609
 
1560
- Returns
1561
- -------
1562
- CustomWebEngineView
1563
- CustomWebEngineView object of the window
1610
+ # Returns
1611
+ # -------
1612
+ # CustomWebEngineView
1613
+ # CustomWebEngineView object of the window
1564
1614
 
1565
- Examples
1566
- --------
1567
- ```python
1568
- window = app.create_window("pyloid-window")
1569
- web_view = window.get_QWebEngineView()
1615
+ # Examples
1616
+ # --------
1617
+ # ```python
1618
+ # window = app.create_window("pyloid-window")
1619
+ # web_view = window.get_QWebEngineView()
1570
1620
 
1571
- web_view.page().runJavaScript("console.log('Hello, Pyloid!')")
1572
- ```
1573
- """
1574
- return self.web_view
1621
+ # web_view.page().runJavaScript("console.log('Hello, Pyloid!')")
1622
+ # ```
1623
+ # """
1624
+ # return self.web_view
1575
1625
 
1576
1626
  ###########################################################################################
1577
1627
  # QMainWindow flags
@@ -1669,7 +1719,7 @@ class BrowserWindow:
1669
1719
  Examples
1670
1720
  --------
1671
1721
  ```python
1672
- window.set_image_splash_screen("./assets/loading.png", close_on_load=True, stay_on_top=True)
1722
+ window.set_static_image_splash_screen("./assets/loading.png", close_on_load=True, stay_on_top=True)
1673
1723
  ```
1674
1724
  """
1675
1725
  pixmap = QPixmap(image_path)
@@ -1807,150 +1857,1121 @@ class BrowserWindow:
1807
1857
  ###########################################################################################
1808
1858
  # WebEngineView Attribute setting
1809
1859
  ###########################################################################################
1810
- def set_web_engine_view_attribute(self, attribute: QWebEngineSettings, on: bool):
1860
+ # def set_web_engine_view_attribute(self, attribute: QWebEngineSettings, on: bool):
1861
+ # """
1862
+ # Sets the attribute of the WebEngineView.
1863
+
1864
+ # Parameters
1865
+ # ----------
1866
+ # attribute : QWebEngineSettings
1867
+ # Attribute to set
1868
+ # on : bool
1869
+ # True to enable the attribute, False to disable it
1870
+
1871
+ # Examples
1872
+ # --------
1873
+ # ```python
1874
+ # window.set_web_engine_view_attribute(QWebEngineSettings.WebAttribute.ScreenCaptureEnabled, False)
1875
+ # ```
1876
+ # """
1877
+ # settings = self.web_view.settings()
1878
+ # settings.setAttribute(attribute, on)
1879
+
1880
+ # def is_web_engine_view_attribute(self, attribute: QWebEngineSettings) -> bool:
1881
+ # """
1882
+ # Returns the attribute of the WebEngineView.
1883
+
1884
+ # Parameters
1885
+ # ----------
1886
+ # attribute : QWebEngineSettings
1887
+ # Attribute to get
1888
+
1889
+ # Returns
1890
+ # -------
1891
+ # bool
1892
+ # True if the attribute is enabled, False otherwise
1893
+
1894
+ # Examples
1895
+ # --------
1896
+ # ```python
1897
+ # window.is_web_engine_view_attribute(QWebEngineSettings.WebAttribute.ScreenCaptureEnabled)
1898
+ # ```
1899
+ # """
1900
+ # settings = self.web_view.settings()
1901
+ # return settings.testAttribute(attribute)
1902
+
1903
+ # def set_permission_handler(self, feature: QWebEnginePage.Feature, handler):
1904
+ # """
1905
+ # Sets a handler for a specific permission.
1906
+
1907
+ # Parameters
1908
+ # ----------
1909
+ # feature : QWebEnginePage.Feature
1910
+ # The type of permission to set
1911
+ # handler : callable
1912
+ # The handler function to process the permission request
1913
+
1914
+ # Examples
1915
+ # --------
1916
+ # ```python
1917
+ # def handle_camera(origin, feature):
1918
+ # window.web_view.page().setFeaturePermission(
1919
+ # origin,
1920
+ # feature,
1921
+ # QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
1922
+ # )
1923
+
1924
+ # window.set_permission_handler(
1925
+ # QWebEnginePage.Feature.MediaVideoCapture,
1926
+ # handle_camera
1927
+ # )
1928
+ # ```
1929
+ # """
1930
+ # self.web_view.custom_page.setPermissionHandler(feature, handler)
1931
+
1932
+ # def grant_permission(self, feature: QWebEnginePage.Feature):
1933
+ # """
1934
+ # Automatically grants a specific permission when a request is made.
1935
+
1936
+ # Parameters
1937
+ # ----------
1938
+ # feature : QWebEnginePage.Feature
1939
+ # The type of permission to automatically grant
1940
+
1941
+ # Examples
1942
+ # --------
1943
+ # ```python
1944
+ # window.grant_permission(QWebEnginePage.Feature.MediaVideoCapture)
1945
+ # ```
1946
+ # """
1947
+
1948
+ # def auto_grant(origin, feat):
1949
+ # self.web_view.page().setFeaturePermission(
1950
+ # origin, feat, QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
1951
+ # )
1952
+
1953
+ # self.set_permission_handler(feature, auto_grant)
1954
+
1955
+ # def deny_permission(self, feature: QWebEnginePage.Feature):
1956
+ # """
1957
+ # Automatically denies a specific permission when a request is made.
1958
+
1959
+ # Parameters
1960
+ # ----------
1961
+ # feature : QWebEnginePage.Feature
1962
+ # The type of permission to automatically deny
1963
+
1964
+ # Examples
1965
+ # --------
1966
+ # ```python
1967
+ # window.deny_permission(QWebEnginePage.Feature.Notifications)
1968
+ # ```
1969
+ # """
1970
+
1971
+ # def auto_deny(origin, feat):
1972
+ # self.web_view.page().setFeaturePermission(
1973
+ # origin, feat, QWebEnginePage.PermissionPolicy.PermissionDeniedByUser
1974
+ # )
1975
+
1976
+ # self.set_permission_handler(feature, auto_deny)
1977
+
1978
+ # def set_desktop_media_handler(self, handler):
1979
+ # """
1980
+ # 데스크톱 미디어(화면/윈도우) 선택 핸들러를 설정합니다.
1981
+
1982
+ # Parameters
1983
+ # ----------
1984
+ # handler : callable
1985
+ # 요청을 처리할 핸들러 함수. QWebEngineDesktopMediaRequest 인자로 받습니다.
1986
+
1987
+ # Examples
1988
+ # --------
1989
+ # ```python
1990
+ # def custom_media_handler(request):
1991
+ # # 사용 가능한 화면 목록 출력
1992
+ # for screen in request.screenList():
1993
+ # print(f"Screen: {screen.name}")
1994
+
1995
+ # # 사용 가능한 윈도우 목록 출력
1996
+ # for window in request.windowList():
1997
+ # print(f"Window: {window.name}")
1998
+
1999
+ # # 첫 번째 화면 선택
2000
+ # if request.screenList():
2001
+ # request.selectScreen(request.screenList()[0])
2002
+
2003
+ # window.set_desktop_media_handler(custom_media_handler)
2004
+ # ```
2005
+ # """
2006
+ # self.web_view.custom_page.setDesktopMediaHandler(handler)
2007
+
2008
+
2009
+ # This wrapper class work in other thread
2010
+ class BrowserWindow(QObject):
2011
+ command_signal = Signal(str, str, object)
2012
+ result_signal = Signal(str, object)
2013
+
2014
+ def __init__(self, app, title: str, width: int, height: int, x: int, y: int, frame: bool, context_menu: bool, dev_tools: bool, js_apis: List[PyloidAPI]):
2015
+ super().__init__()
2016
+ self.window = _BrowserWindow(app, title, width, height, x, y, frame, context_menu, dev_tools, js_apis)
2017
+ self.command_signal.connect(self._handle_command)
2018
+
2019
+ @Slot(str, str, object)
2020
+ def _handle_command(self, command_id: str, command_type: str, params: object) -> None:
2021
+ """
2022
+ Handles commands sent from multiple threads.
2023
+ Calls the corresponding method of _BrowserWindow based on the command type and returns the result.
2024
+
2025
+ :param command_id: Unique identifier for each command
2026
+ :param command_type: Type of command to execute (e.g., "load_file", "set_title", etc.)
2027
+ :param params: Object containing parameters needed for command execution
2028
+ """
2029
+ result = None
2030
+
2031
+ if command_type == "load_file":
2032
+ result = self.window.load_file(params["file_path"])
2033
+ elif command_type == "load_url":
2034
+ result = self.window.load_url(params["url"])
2035
+ elif command_type == "load_html":
2036
+ html_content = params.get("html_content", "")
2037
+ base_url = params.get("base_url", "")
2038
+ result = self.window.load_html(html_content, base_url)
2039
+ elif command_type == "set_title":
2040
+ result = self.window.set_title(params["title"])
2041
+ elif command_type == "set_size":
2042
+ result = self.window.set_size(params["width"], params["height"])
2043
+ elif command_type == "set_position":
2044
+ result = self.window.set_position(params["x"], params["y"])
2045
+ elif command_type == "set_position_by_anchor":
2046
+ result = self.window.set_position_by_anchor(params["anchor"])
2047
+ elif command_type == "set_frame":
2048
+ result = self.window.set_frame(params["frame"])
2049
+ elif command_type == "set_context_menu":
2050
+ result = self.window.set_context_menu(params["context_menu"])
2051
+ elif command_type == "set_dev_tools":
2052
+ result = self.window.set_dev_tools(params["enable"])
2053
+ elif command_type == "open_dev_tools":
2054
+ result = self.window.open_dev_tools()
2055
+ elif command_type == "hide":
2056
+ result = self.window.hide()
2057
+ elif command_type == "show":
2058
+ result = self.window.show()
2059
+ elif command_type == "focus":
2060
+ result = self.window.focus()
2061
+ elif command_type == "show_and_focus":
2062
+ result = self.window.show_and_focus()
2063
+ elif command_type == "close":
2064
+ result = self.window.close()
2065
+ elif command_type == "fullscreen":
2066
+ result = self.window.fullscreen()
2067
+ elif command_type == "toggle_fullscreen":
2068
+ result = self.window.toggle_fullscreen()
2069
+ elif command_type == "minimize":
2070
+ result = self.window.minimize()
2071
+ elif command_type == "maximize":
2072
+ result = self.window.maximize()
2073
+ elif command_type == "unmaximize":
2074
+ result = self.window.unmaximize()
2075
+ elif command_type == "toggle_maximize":
2076
+ result = self.window.toggle_maximize()
2077
+ elif command_type == "is_fullscreen":
2078
+ result = self.window.is_fullscreen()
2079
+ elif command_type == "is_maximized":
2080
+ result = self.window.is_maximized()
2081
+ elif command_type == "capture":
2082
+ result = self.window.capture(params["save_path"])
2083
+ elif command_type == "add_shortcut":
2084
+ result = self.window.add_shortcut(params["key_sequence"], params["callback"])
2085
+ elif command_type == "remove_shortcut":
2086
+ result = self.window.remove_shortcut(params["key_sequence"])
2087
+ elif command_type == "get_all_shortcuts":
2088
+ result = self.window.get_all_shortcuts()
2089
+ elif command_type == "emit":
2090
+ event_name = params["event_name"]
2091
+ data = params.get("data")
2092
+ result = self.window.invoke(event_name, data)
2093
+ elif command_type == "get_window_properties":
2094
+ result = self.window.get_window_properties()
2095
+ elif command_type == "get_id":
2096
+ result = self.window.get_id()
2097
+ elif command_type == "get_size":
2098
+ result = self.window.get_size()
2099
+ elif command_type == "get_position":
2100
+ result = self.window.get_position()
2101
+ elif command_type == "get_title":
2102
+ result = self.window.get_title()
2103
+ elif command_type == "get_url":
2104
+ result = self.window.get_url()
2105
+ elif command_type == "get_visible":
2106
+ result = self.window.get_visible()
2107
+ elif command_type == "get_frame":
2108
+ result = self.window.get_frame()
2109
+ elif command_type == "set_resizable":
2110
+ result = self.window.set_resizable(params["resizable"])
2111
+ elif command_type == "set_minimum_size":
2112
+ result = self.window.set_minimum_size(params["min_width"], params["min_height"])
2113
+ elif command_type == "set_maximum_size":
2114
+ result = self.window.set_maximum_size(params["max_width"], params["max_height"])
2115
+ elif command_type == "get_minimum_size":
2116
+ result = self.window.get_minimum_size()
2117
+ elif command_type == "get_maximum_size":
2118
+ result = self.window.get_maximum_size()
2119
+ elif command_type == "get_resizable":
2120
+ result = self.window.get_resizable()
2121
+ elif command_type == "set_static_image_splash_screen":
2122
+ result = self.window.set_static_image_splash_screen(
2123
+ params["image_path"],
2124
+ params.get("close_on_load", True),
2125
+ params.get("stay_on_top", True),
2126
+ params.get("clickable", True),
2127
+ params.get("position", "center")
2128
+ )
2129
+ elif command_type == "set_gif_splash_screen":
2130
+ result = self.window.set_gif_splash_screen(
2131
+ params["gif_path"],
2132
+ params.get("close_on_load", True),
2133
+ params.get("stay_on_top", True),
2134
+ params.get("clickable", True),
2135
+ params.get("position", "center")
2136
+ )
2137
+ elif command_type == "close_splash_screen":
2138
+ result = self.window.close_splash_screen()
2139
+ else:
2140
+ return None
2141
+
2142
+ self.result_signal.emit(command_id, result)
2143
+
2144
+ def execute_command(self, command_type: str, params: object, timeout: Optional[int] = None):
2145
+ command_id = str(uuid.uuid4())
2146
+
2147
+ result_data = [None]
2148
+ loop = QEventLoop()
2149
+
2150
+ if timeout:
2151
+ timer = QTimer()
2152
+ timer.setSingleShot(True)
2153
+ timer.timeout.connect(loop.quit)
2154
+ timer.start(timeout)
2155
+
2156
+ def on_result(received_id, result):
2157
+ if received_id == command_id:
2158
+ result_data[0] = result
2159
+ loop.quit()
2160
+
2161
+
2162
+ self.result_signal.connect(on_result, Qt.QueuedConnection)
2163
+
2164
+ self.command_signal.emit(command_id, command_type, params)
2165
+
2166
+ loop.exec()
2167
+
2168
+ self.result_signal.disconnect(on_result)
2169
+
2170
+ return result_data[0]
2171
+
2172
+ # -------------------------------------------------------------------
2173
+ # Execute_command wrapper functions
2174
+ # -------------------------------------------------------------------
2175
+ def load_file(self, file_path: str) -> None:
1811
2176
  """
1812
- Sets the attribute of the WebEngineView.
2177
+ Loads a local HTML file into the web view.
1813
2178
 
1814
2179
  Parameters
1815
2180
  ----------
1816
- attribute : QWebEngineSettings
1817
- Attribute to set
1818
- on : bool
1819
- True to enable the attribute, False to disable it
2181
+ file_path : str
2182
+ The path to the local HTML file to be loaded.
1820
2183
 
1821
2184
  Examples
1822
2185
  --------
1823
- ```python
1824
- window.set_web_engine_view_attribute(QWebEngineSettings.WebAttribute.ScreenCaptureEnabled, False)
1825
- ```
2186
+ >>> app = Pyloid(app_name="Pyloid-App")
2187
+ >>> window = app.create_window("pyloid-window")
2188
+ >>> window.load_file('/path/to/local/file.html')
2189
+ >>> window.show()
1826
2190
  """
1827
- settings = self.web_view.settings()
1828
- settings.setAttribute(attribute, on)
2191
+ return self.execute_command("load_file", {"file_path": file_path})
1829
2192
 
1830
- def is_web_engine_view_attribute(self, attribute: QWebEngineSettings) -> bool:
2193
+ def load_url(self, url: str) -> None:
1831
2194
  """
1832
- Returns the attribute of the WebEngineView.
2195
+ Sets the URL of the window.
1833
2196
 
1834
2197
  Parameters
1835
2198
  ----------
1836
- attribute : QWebEngineSettings
1837
- Attribute to get
2199
+ url : str
2200
+ The URL to be loaded in the web view.
1838
2201
 
1839
- Returns
1840
- -------
1841
- bool
1842
- True if the attribute is enabled, False otherwise
2202
+ Examples
2203
+ --------
2204
+ >>> app = Pyloid(app_name="Pyloid-App")
2205
+ >>> window = app.create_window("pyloid-window")
2206
+ >>> window.load_url('https://www.example.com')
2207
+ >>> window.show()
2208
+ """
2209
+ return self.execute_command("load_url", {"url": url})
2210
+
2211
+ def load_html(self, html_content: str, base_url: str = "") -> None:
2212
+ """
2213
+ Loads HTML content directly into the web view.
2214
+
2215
+ Parameters
2216
+ ----------
2217
+ html_content : str
2218
+ The HTML content to be loaded.
2219
+ base_url : str, optional
2220
+ The base URL to use for resolving relative URLs (default is "").
1843
2221
 
1844
2222
  Examples
1845
2223
  --------
1846
- ```python
1847
- window.is_web_engine_view_attribute(QWebEngineSettings.WebAttribute.ScreenCaptureEnabled)
1848
- ```
2224
+ >>> app = Pyloid(app_name="Pyloid-App")
2225
+ >>> window = app.create_window("pyloid-window")
2226
+ >>> html_content = "<html><body><h1>Hello, Pyloid!</h1></body></html>"
2227
+ >>> window.load_html(html_content)
2228
+ >>> window.show()
1849
2229
  """
1850
- settings = self.web_view.settings()
1851
- return settings.testAttribute(attribute)
2230
+ return self.execute_command("load_html", {"html_content": html_content, "base_url": base_url})
1852
2231
 
1853
- def set_permission_handler(self, feature: QWebEnginePage.Feature, handler):
2232
+ def set_title(self, title: str) -> None:
1854
2233
  """
1855
- Sets a handler for a specific permission.
2234
+ Sets the title of the window.
1856
2235
 
1857
2236
  Parameters
1858
2237
  ----------
1859
- feature : QWebEnginePage.Feature
1860
- The type of permission to set
1861
- handler : callable
1862
- The handler function to process the permission request
2238
+ title : str
2239
+ The title to be set for the window.
1863
2240
 
1864
2241
  Examples
1865
2242
  --------
1866
- ```python
1867
- def handle_camera(origin, feature):
1868
- window.web_view.page().setFeaturePermission(
1869
- origin,
1870
- feature,
1871
- QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
1872
- )
2243
+ >>> app = Pyloid(app_name="Pyloid-App")
2244
+ >>> window = app.create_window("pyloid-window")
2245
+ >>> window.set_title('My Window Title')
2246
+ """
2247
+ return self.execute_command("set_title", {"title": title})
1873
2248
 
1874
- window.set_permission_handler(
1875
- QWebEnginePage.Feature.MediaVideoCapture,
1876
- handle_camera
1877
- )
1878
- ```
2249
+ def set_size(self, width: int, height: int) -> None:
2250
+ """
2251
+ Sets the size of the window.
2252
+
2253
+ Parameters
2254
+ ----------
2255
+ width : int
2256
+ The width of the window.
2257
+ height : int
2258
+ The height of the window.
2259
+
2260
+ Examples
2261
+ --------
2262
+ >>> app = Pyloid(app_name="Pyloid-App")
2263
+ >>> window = app.create_window("pyloid-window")
2264
+ >>> window.set_size(800, 600)
1879
2265
  """
1880
- self.web_view.custom_page.setPermissionHandler(feature, handler)
2266
+ return self.execute_command("set_size", {"width": width, "height": height})
1881
2267
 
1882
- def grant_permission(self, feature: QWebEnginePage.Feature):
2268
+ def set_position(self, x: int, y: int) -> None:
1883
2269
  """
1884
- Automatically grants a specific permission when a request is made.
2270
+ Sets the position of the window.
1885
2271
 
1886
2272
  Parameters
1887
2273
  ----------
1888
- feature : QWebEnginePage.Feature
1889
- The type of permission to automatically grant
2274
+ x : int
2275
+ The x-coordinate of the window's position.
2276
+ y : int
2277
+ The y-coordinate of the window's position.
1890
2278
 
1891
2279
  Examples
1892
2280
  --------
1893
- ```python
1894
- window.grant_permission(QWebEnginePage.Feature.MediaVideoCapture)
1895
- ```
2281
+ >>> app = Pyloid(app_name="Pyloid-App")
2282
+ >>> window = app.create_window("pyloid-window")
2283
+ >>> window.set_position(100, 100)
1896
2284
  """
2285
+ return self.execute_command("set_position", {"x": x, "y": y})
1897
2286
 
1898
- def auto_grant(origin, feat):
1899
- self.web_view.page().setFeaturePermission(
1900
- origin, feat, QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
1901
- )
2287
+ def set_position_by_anchor(self, anchor: str) -> None:
2288
+ """
2289
+ Positions the window at a specific location on the screen.
2290
+
2291
+ Parameters
2292
+ ----------
2293
+ anchor : str
2294
+ The anchor point indicating where to position the window.
2295
+ Possible values: 'center', 'top', 'bottom', 'left', 'right',
2296
+ 'top-left', 'top-right', 'bottom-left', 'bottom-right'
1902
2297
 
1903
- self.set_permission_handler(feature, auto_grant)
2298
+ Examples
2299
+ --------
2300
+ >>> window.set_position_by_anchor('center')
2301
+ >>> window.set_position_by_anchor('top-right')
2302
+ """
2303
+ return self.execute_command("set_position_by_anchor", {"anchor": anchor})
1904
2304
 
1905
- def deny_permission(self, feature: QWebEnginePage.Feature):
2305
+ def set_frame(self, frame: bool) -> None:
1906
2306
  """
1907
- Automatically denies a specific permission when a request is made.
2307
+ Sets the frame of the window.
1908
2308
 
1909
2309
  Parameters
1910
2310
  ----------
1911
- feature : QWebEnginePage.Feature
1912
- The type of permission to automatically deny
2311
+ frame : bool
2312
+ If True, the window will have a frame. If False, the window will be frameless.
1913
2313
 
1914
2314
  Examples
1915
2315
  --------
1916
- ```python
1917
- window.deny_permission(QWebEnginePage.Feature.Notifications)
1918
- ```
2316
+ >>> app = Pyloid(app_name="Pyloid-App")
2317
+ >>> window = app.create_window("pyloid-window")
2318
+ >>> window.set_frame(True)
2319
+ >>> window.set_frame(False)
1919
2320
  """
2321
+ return self.execute_command("set_frame", {"frame": frame})
1920
2322
 
1921
- def auto_deny(origin, feat):
1922
- self.web_view.page().setFeaturePermission(
1923
- origin, feat, QWebEnginePage.PermissionPolicy.PermissionDeniedByUser
1924
- )
2323
+ def set_context_menu(self, context_menu: bool) -> None:
2324
+ """
2325
+ Sets the context menu of the window.
2326
+
2327
+ Parameters
2328
+ ----------
2329
+ context_menu : bool
2330
+ If True, the context menu will be disabled. If False, the default context menu will be enabled.
1925
2331
 
1926
- self.set_permission_handler(feature, auto_deny)
2332
+ Examples
2333
+ --------
2334
+ >>> app = Pyloid(app_name="Pyloid-App")
2335
+ >>> window = app.create_window("pyloid-window")
2336
+ >>> window.set_context_menu(True)
2337
+ >>> window.set_context_menu(False)
2338
+ """
2339
+ return self.execute_command("set_context_menu", {"context_menu": context_menu})
1927
2340
 
1928
- def set_desktop_media_handler(self, handler):
2341
+ def set_dev_tools(self, enable: bool) -> None:
1929
2342
  """
1930
- 데스크톱 미디어(화면/윈도우) 선택 핸들러를 설정합니다.
2343
+ Sets the developer tools of the window.
2344
+
2345
+ If enabled, the developer tools can be opened using the F12 key.
1931
2346
 
1932
2347
  Parameters
1933
2348
  ----------
1934
- handler : callable
1935
- 요청을 처리할 핸들러 함수. QWebEngineDesktopMediaRequest 인자로 받습니다.
2349
+ enable : bool
2350
+ If True, the developer tools will be enabled. If False, the developer tools will be disabled.
1936
2351
 
1937
2352
  Examples
1938
2353
  --------
1939
- ```python
1940
- def custom_media_handler(request):
1941
- # 사용 가능한 화면 목록 출력
1942
- for screen in request.screenList():
1943
- print(f"Screen: {screen.name}")
2354
+ >>> app = Pyloid(app_name="Pyloid-App")
2355
+ >>> window = app.create_window("pyloid-window")
2356
+ >>> window.set_dev_tools(True)
2357
+ >>> window.set_dev_tools(False)
2358
+ """
2359
+ return self.execute_command("set_dev_tools", {"enable": enable})
1944
2360
 
1945
- # 사용 가능한 윈도우 목록 출력
1946
- for window in request.windowList():
1947
- print(f"Window: {window.name}")
2361
+ def open_dev_tools(self) -> None:
2362
+ """
2363
+ Opens the developer tools window.
2364
+
2365
+ Examples
2366
+ --------
2367
+ >>> app = Pyloid(app_name="Pyloid-App")
2368
+ >>> window = app.create_window("pyloid-window")
2369
+ >>> window.open_dev_tools()
2370
+ """
2371
+ return self.execute_command("open_dev_tools", {})
1948
2372
 
1949
- # 번째 화면 선택
1950
- if request.screenList():
1951
- request.selectScreen(request.screenList()[0])
2373
+ def hide(self) -> None:
2374
+ """
2375
+ Hides the window.
1952
2376
 
1953
- window.set_desktop_media_handler(custom_media_handler)
1954
- ```
2377
+ Examples
2378
+ --------
2379
+ >>> app = Pyloid(app_name="Pyloid-App")
2380
+ >>> window = app.create_window("pyloid-window")
2381
+ >>> window.hide()
2382
+ """
2383
+ return self.execute_command("hide", {})
2384
+
2385
+ def show(self) -> None:
2386
+ """
2387
+ Shows the window.
2388
+
2389
+ Examples
2390
+ --------
2391
+ >>> app = Pyloid(app_name="Pyloid-App")
2392
+ >>> window = app.create_window("pyloid-window")
2393
+ >>> window.show()
2394
+ """
2395
+ return self.execute_command("show", {})
2396
+
2397
+ def focus(self) -> None:
2398
+ """
2399
+ Focuses the window.
2400
+
2401
+ Examples
2402
+ --------
2403
+ >>> app = Pyloid(app_name="Pyloid-App")
2404
+ >>> window = app.create_window("pyloid-window")
2405
+ >>> window.focus()
2406
+ """
2407
+ return self.execute_command("focus", {})
2408
+
2409
+ def show_and_focus(self) -> None:
2410
+ """
2411
+ Shows and focuses the window.
2412
+
2413
+ Examples
2414
+ --------
2415
+ >>> app = Pyloid(app_name="Pyloid-App")
2416
+ >>> window = app.create_window("pyloid-window")
2417
+ >>> window.show_and_focus()
2418
+ """
2419
+ return self.execute_command("show_and_focus", {})
2420
+
2421
+ def close(self) -> None:
2422
+ """
2423
+ Closes the window.
2424
+
2425
+ Examples
2426
+ --------
2427
+ >>> app = Pyloid(app_name="Pyloid-App")
2428
+ >>> window = app.create_window("pyloid-window")
2429
+ >>> window.close()
2430
+ """
2431
+ return self.execute_command("close", {})
2432
+
2433
+ def fullscreen(self) -> None:
2434
+ """
2435
+ Enters fullscreen mode.
2436
+
2437
+ Examples
2438
+ --------
2439
+ >>> app = Pyloid(app_name="Pyloid-App")
2440
+ >>> window = app.create_window("pyloid-window")
2441
+ >>> window.fullscreen()
2442
+ """
2443
+ return self.execute_command("fullscreen", {})
2444
+
2445
+ def toggle_fullscreen(self) -> None:
2446
+ """
2447
+ Toggles the fullscreen mode of the window.
2448
+
2449
+ Examples
2450
+ --------
2451
+ >>> app = Pyloid(app_name="Pyloid-App")
2452
+ >>> window = app.create_window("pyloid-window")
2453
+ >>> window.toggle_fullscreen()
2454
+ """
2455
+ return self.execute_command("toggle_fullscreen", {})
2456
+
2457
+ def minimize(self) -> None:
2458
+ """
2459
+ Minimizes the window.
2460
+
2461
+ Examples
2462
+ --------
2463
+ >>> app = Pyloid(app_name="Pyloid-App")
2464
+ >>> window = app.create_window("pyloid-window")
2465
+ >>> window.minimize()
2466
+ """
2467
+ return self.execute_command("minimize", {})
2468
+
2469
+ def maximize(self) -> None:
2470
+ """
2471
+ Maximizes the window.
2472
+
2473
+ Examples
2474
+ --------
2475
+ >>> app = Pyloid(app_name="Pyloid-App")
2476
+ >>> window = app.create_window("pyloid-window")
2477
+ >>> window.maximize()
2478
+ """
2479
+ return self.execute_command("maximize", {})
2480
+
2481
+ def unmaximize(self) -> None:
2482
+ """
2483
+ Restores the window from maximized state.
2484
+
2485
+ Examples
2486
+ --------
2487
+ >>> app = Pyloid(app_name="Pyloid-App")
2488
+ >>> window = app.create_window("pyloid-window")
2489
+ >>> window.unmaximize()
2490
+ """
2491
+ return self.execute_command("unmaximize", {})
2492
+
2493
+ def toggle_maximize(self) -> None:
2494
+ """
2495
+ Toggles the maximized state of the window.
2496
+
2497
+ Examples
2498
+ --------
2499
+ >>> app = Pyloid(app_name="Pyloid-App")
2500
+ >>> window = app.create_window("pyloid-window")
2501
+ >>> window.toggle_maximize()
2502
+ """
2503
+ return self.execute_command("toggle_maximize", {})
2504
+
2505
+ def is_fullscreen(self) -> bool:
2506
+ """
2507
+ Returns True if the window is fullscreen.
2508
+
2509
+ Examples
2510
+ --------
2511
+ >>> app = Pyloid(app_name="Pyloid-App")
2512
+ >>> window = app.create_window("pyloid-window")
2513
+ >>> window.is_fullscreen()
2514
+ """
2515
+ return self.execute_command("is_fullscreen", {})
2516
+
2517
+ def is_maximized(self) -> bool:
2518
+ """
2519
+ Returns True if the window is maximized.
2520
+
2521
+ Examples
2522
+ --------
2523
+ >>> app = Pyloid(app_name="Pyloid-App")
2524
+ >>> window = app.create_window("pyloid-window")
2525
+ >>> window.is_maximized()
2526
+ """
2527
+ return self.execute_command("is_maximized", {})
2528
+
2529
+ def capture(self, save_path: str) -> "Optional[str]":
2530
+ """
2531
+ Captures the current window.
2532
+
2533
+ Parameters
2534
+ ----------
2535
+ save_path : str
2536
+ Path to save the captured image. If not specified, it will be saved in the current directory.
2537
+
2538
+ Returns
2539
+ -------
2540
+ Optional[str]
2541
+ Returns the path of the saved image.
2542
+
2543
+ Examples
2544
+ --------
2545
+ >>> app = Pyloid(app_name="Pyloid-App")
2546
+ >>> window = app.create_window("pyloid-window")
2547
+ >>> save_path = window.capture("screenshot.png")
2548
+ >>> print(f"Image saved at: {save_path}")
2549
+ """
2550
+ return self.execute_command("capture", {"save_path": save_path})
2551
+
2552
+ def add_shortcut(self, key_sequence: str, callback: Callable) -> Any:
2553
+ """
2554
+ Adds a keyboard shortcut to the window if it does not already exist.
2555
+
2556
+ Parameters
2557
+ ----------
2558
+ key_sequence : str
2559
+ Shortcut sequence (e.g., "Ctrl+C")
2560
+ callback : Callable
2561
+ Function to be executed when the shortcut is pressed
2562
+
2563
+ Returns
2564
+ -------
2565
+ QShortcut or None
2566
+ Created QShortcut object or None if the shortcut already exists
2567
+
2568
+ Examples
2569
+ --------
2570
+ >>> app = Pyloid(app_name="Pyloid-App")
2571
+ >>> window = app.create_window("pyloid-window")
2572
+ >>> def on_shortcut():
2573
+ ... print("Shortcut activated!")
2574
+ >>> window.add_shortcut("Ctrl+C", on_shortcut)
2575
+ >>> app.run()
2576
+ """
2577
+ return self.execute_command("add_shortcut", {"key_sequence": key_sequence, "callback": callback})
2578
+
2579
+ def remove_shortcut(self, key_sequence: str) -> None:
2580
+ """
2581
+ Removes a keyboard shortcut from the window.
2582
+
2583
+ Parameters
2584
+ ----------
2585
+ key_sequence : str
2586
+ Shortcut sequence to be removed
2587
+
2588
+ Examples
2589
+ --------
2590
+ >>> app = Pyloid(app_name="Pyloid-App")
2591
+ >>> window = app.create_window("pyloid-window")
2592
+ >>> window.remove_shortcut("Ctrl+C")
2593
+ >>> app.run()
2594
+ """
2595
+ return self.execute_command("remove_shortcut", {"key_sequence": key_sequence})
2596
+
2597
+ def get_all_shortcuts(self) -> dict:
2598
+ """
2599
+ Returns all registered shortcuts in the window.
2600
+
2601
+ Returns
2602
+ -------
2603
+ dict
2604
+ Dictionary of shortcut sequences and QShortcut objects
2605
+
2606
+ Examples
2607
+ --------
2608
+ >>> app = Pyloid(app_name="Pyloid-App")
2609
+ >>> window = app.create_window("pyloid-window")
2610
+ >>> shortcuts = window.get_all_shortcuts()
2611
+ >>> print(shortcuts)
2612
+ >>> app.run()
2613
+ """
2614
+ return self.execute_command("get_all_shortcuts", {})
2615
+
2616
+ def invoke(self, event_name: str, data: "Optional[Dict]" = None) -> None:
2617
+ """
2618
+ Invokes an event to the JavaScript side.
2619
+
2620
+ Parameters
2621
+ ----------
2622
+ event_name : str
2623
+ Name of the event
2624
+ data : dict, optional
2625
+ Data to be sent with the event (default is None)
2626
+
2627
+ Examples
2628
+ --------
2629
+ (Python)
2630
+ >>> app = Pyloid(app_name="Pyloid-App")
2631
+ >>> window = app.create_window("pyloid-window")
2632
+ >>> window.invoke("customEvent", {"message": "Hello, Pyloid!"})
2633
+
2634
+ (JavaScript)
2635
+ >>> document.addEventListener('customEvent', (data) => {
2636
+ ... console.log(data.message);
2637
+ ... });
2638
+ """
2639
+ return self.execute_command("invoke", {"event_name": event_name, "data": data})
2640
+
2641
+ def get_window_properties(self) -> dict:
2642
+ """
2643
+ Returns the properties of the window.
2644
+
2645
+ Returns
2646
+ -------
2647
+ dict
2648
+ Dictionary containing the properties of the window
2649
+
2650
+ Examples
2651
+ --------
2652
+ >>> app = Pyloid(app_name="Pyloid-App")
2653
+ >>> window = app.create_window("pyloid-window")
2654
+ >>> properties = window.get_window_properties()
2655
+ >>> print(properties)
2656
+ >>> app.run()
2657
+ """
2658
+ return self.execute_command("get_window_properties", {})
2659
+
2660
+ def get_id(self) -> str:
2661
+ """
2662
+ Returns the ID of the window.
2663
+
2664
+ Returns
2665
+ -------
2666
+ str
2667
+ ID of the window
2668
+
2669
+ Examples
2670
+ --------
2671
+ >>> app = Pyloid(app_name="Pyloid-App")
2672
+ >>> window = app.create_window("pyloid-window")
2673
+ >>> window_id = window.get_id()
2674
+ >>> print(window_id)
2675
+ >>> app.run()
2676
+ """
2677
+ return self.execute_command("get_id", {})
2678
+
2679
+ def get_size(self) -> "Dict[str, int]":
2680
+ """
2681
+ Returns the size of the window.
2682
+
2683
+ Returns
2684
+ -------
2685
+ dict
2686
+ Dictionary containing the width and height of the window
2687
+
2688
+ Examples
2689
+ --------
2690
+ >>> app = Pyloid(app_name="Pyloid-App")
2691
+ >>> window = app.create_window("pyloid-window")
2692
+ >>> size = window.get_size()
2693
+ >>> print(size)
2694
+ >>> app.run()
2695
+ """
2696
+ return self.execute_command("get_size", {})
2697
+
2698
+ def get_position(self) -> "Dict[str, int]":
2699
+ """
2700
+ Returns the position of the window.
2701
+
2702
+ Returns
2703
+ -------
2704
+ dict
2705
+ Dictionary containing the x and y coordinates of the window
2706
+
2707
+ Examples
2708
+ --------
2709
+ >>> app = Pyloid(app_name="Pyloid-App")
2710
+ >>> window = app.create_window("pyloid-window")
2711
+ >>> position = window.get_position()
2712
+ >>> print(position)
2713
+ >>> app.run()
2714
+ """
2715
+ return self.execute_command("get_position", {})
2716
+
2717
+ def get_title(self) -> str:
2718
+ """
2719
+ Returns the title of the window.
2720
+
2721
+ Returns
2722
+ -------
2723
+ str
2724
+ Title of the window
2725
+
2726
+ Examples
2727
+ --------
2728
+ >>> app = Pyloid(app_name="Pyloid-App")
2729
+ >>> window = app.create_window("pyloid-window")
2730
+ >>> title = window.get_title()
2731
+ >>> print(title)
2732
+ >>> app.run()
2733
+ """
2734
+ return self.execute_command("get_title", {})
2735
+
2736
+ def get_url(self) -> str:
2737
+ """
2738
+ Returns the URL of the window.
2739
+
2740
+ Returns
2741
+ -------
2742
+ str
2743
+ URL of the window
2744
+
2745
+ Examples
2746
+ --------
2747
+ >>> app = Pyloid(app_name="Pyloid-App")
2748
+ >>> window = app.create_window("pyloid-window")
2749
+ >>> url = window.get_url()
2750
+ >>> print(url)
2751
+ >>> app.run()
2752
+ """
2753
+ return self.execute_command("get_url", {})
2754
+
2755
+ def get_visible(self) -> bool:
2756
+ """
2757
+ Returns the visibility of the window.
2758
+
2759
+ Returns
2760
+ -------
2761
+ bool
2762
+ True if the window is visible, False otherwise
2763
+
2764
+ Examples
2765
+ --------
2766
+ >>> app = Pyloid(app_name="Pyloid-App")
2767
+ >>> window = app.create_window("pyloid-window")
2768
+ >>> visible = window.get_visible()
2769
+ >>> print(visible)
2770
+ >>> app.run()
2771
+ """
2772
+ return self.execute_command("get_visible", {})
2773
+
2774
+ def get_frame(self) -> bool:
2775
+ """
2776
+ Returns the frame enabled state of the window.
2777
+
2778
+ Returns
2779
+ -------
2780
+ bool
2781
+ True if the frame is enabled, False otherwise
2782
+
2783
+ Examples
2784
+ --------
2785
+ >>> app = Pyloid(app_name="Pyloid-App")
2786
+ >>> window = app.create_window("pyloid-window")
2787
+ >>> frame = window.get_frame()
2788
+ >>> print(frame)
2789
+ >>> app.run()
2790
+ """
2791
+ return self.execute_command("get_frame", {})
2792
+
2793
+ def set_resizable(self, resizable: bool) -> None:
2794
+ """
2795
+ Sets the resizability of the window.
2796
+
2797
+ Parameters
2798
+ ----------
2799
+ resizable : bool
2800
+ True to make the window resizable, False to make it fixed size
2801
+
2802
+ Examples
2803
+ --------
2804
+ >>> app = Pyloid(app_name="Pyloid-App")
2805
+ >>> window = app.create_window("pyloid-window")
2806
+ >>> window.set_resizable(True)
2807
+ >>> app.run()
2808
+ """
2809
+ return self.execute_command("set_resizable", {"resizable": resizable})
2810
+
2811
+ def set_minimum_size(self, min_width: int, min_height: int) -> None:
2812
+ """
2813
+ Sets the minimum size of the window.
2814
+
2815
+ Parameters
2816
+ ----------
2817
+ min_width : int
2818
+ Minimum width of the window
2819
+ min_height : int
2820
+ Minimum height of the window
2821
+
2822
+ Examples
2823
+ --------
2824
+ >>> app = Pyloid(app_name="Pyloid-App")
2825
+ >>> window = app.create_window("pyloid-window")
2826
+ >>> window.set_minimum_size(400, 300)
2827
+ >>> app.run()
2828
+ """
2829
+ return self.execute_command("set_minimum_size", {"min_width": min_width, "min_height": min_height})
2830
+
2831
+ def set_maximum_size(self, max_width: int, max_height: int) -> None:
2832
+ """
2833
+ Sets the maximum size of the window.
2834
+
2835
+ Parameters
2836
+ ----------
2837
+ max_width : int
2838
+ Maximum width of the window
2839
+ max_height : int
2840
+ Maximum height of the window
2841
+
2842
+ Examples
2843
+ --------
2844
+ >>> app = Pyloid(app_name="Pyloid-App")
2845
+ >>> window = app.create_window("pyloid-window")
2846
+ >>> window.set_maximum_size(1024, 768)
2847
+ >>> app.run()
2848
+ """
2849
+ return self.execute_command("set_maximum_size", {"max_width": max_width, "max_height": max_height})
2850
+
2851
+ def get_minimum_size(self) -> "Dict[str, int]":
2852
+ """
2853
+ Returns the minimum size of the window.
2854
+
2855
+ Returns
2856
+ -------
2857
+ dict
2858
+ Dictionary containing the minimum width and height of the window
2859
+
2860
+ Examples
2861
+ --------
2862
+ >>> app = Pyloid(app_name="Pyloid-App")
2863
+ >>> window = app.create_window("pyloid-window")
2864
+ >>> min_size = window.get_minimum_size()
2865
+ >>> print(min_size)
2866
+ >>> app.run()
2867
+ """
2868
+ return self.execute_command("get_minimum_size", {})
2869
+
2870
+ def get_maximum_size(self) -> "Dict[str, int]":
2871
+ """
2872
+ Returns the maximum size of the window.
2873
+
2874
+ Returns
2875
+ -------
2876
+ dict
2877
+ Dictionary containing the maximum width and height of the window
2878
+
2879
+ Examples
2880
+ --------
2881
+ >>> app = Pyloid(app_name="Pyloid-App")
2882
+ >>> window = app.create_window("pyloid-window")
2883
+ >>> max_size = window.get_maximum_size()
2884
+ >>> print(max_size)
2885
+ >>> app.run()
2886
+ """
2887
+ return self.execute_command("get_maximum_size", {})
2888
+
2889
+ def get_resizable(self) -> bool:
2890
+ """
2891
+ Returns the resizability of the window.
2892
+
2893
+ Returns
2894
+ -------
2895
+ bool
2896
+ True if the window is resizable, False otherwise
2897
+
2898
+ Examples
2899
+ --------
2900
+ >>> app = Pyloid(app_name="Pyloid-App")
2901
+ >>> window = app.create_window("pyloid-window")
2902
+ >>> resizable = window.get_resizable()
2903
+ >>> print(resizable)
2904
+ >>> app.run()
2905
+ """
2906
+ return self.execute_command("get_resizable", {})
2907
+
2908
+ def set_static_image_splash_screen(self, image_path: str, close_on_load: bool = True, stay_on_top: bool = True, clickable: bool = True, position: str = "center") -> None:
2909
+ """
2910
+ Sets the static image splash screen of the window.
2911
+
2912
+ Parameters
2913
+ ----------
2914
+ image_path : str
2915
+ Path to the image file
2916
+ close_on_load : bool, optional
2917
+ True to close the splash screen when the page is loaded, False otherwise (default is True)
2918
+ stay_on_top : bool, optional
2919
+ True to keep the splash screen on top, False otherwise (default is True)
2920
+ clickable : bool, optional
2921
+ True to make the splash screen clickable, False otherwise (default is True)
2922
+ if clickable is True, you can click the splash screen to close it.
2923
+ position : str, optional
2924
+ Position of the splash screen. Options are 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right' (default is 'center')
2925
+
2926
+ Examples
2927
+ --------
2928
+ >>> window.set_static_image_splash_screen("./assets/loading.png", close_on_load=True, stay_on_top=True)
2929
+ """
2930
+ return self.execute_command("set_static_image_splash_screen", {
2931
+ "image_path": image_path,
2932
+ "close_on_load": close_on_load,
2933
+ "stay_on_top": stay_on_top,
2934
+ "clickable": clickable,
2935
+ "position": position
2936
+ })
2937
+
2938
+ def set_gif_splash_screen(self, gif_path: str, close_on_load: bool = True, stay_on_top: bool = True, clickable: bool = True, position: str = "center") -> None:
2939
+ """
2940
+ Sets the gif splash screen of the window.
2941
+
2942
+ Parameters
2943
+ ----------
2944
+ gif_path : str
2945
+ Path to the gif file
2946
+ close_on_load : bool, optional
2947
+ True to close the splash screen when the page is loaded, False otherwise (default is True)
2948
+ stay_on_top : bool, optional
2949
+ True to keep the splash screen on top, False otherwise (default is True)
2950
+ clickable : bool, optional
2951
+ True to make the splash screen clickable, False otherwise (default is True)
2952
+ if clickable is True, you can click the splash screen to close it.
2953
+ position : str, optional
2954
+ Position of the splash screen. Options are 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right' (default is 'center')
2955
+
2956
+ Examples
2957
+ --------
2958
+ >>> window.set_gif_splash_screen("./assets/loading.gif", close_on_load=True, stay_on_top=True)
2959
+ """
2960
+ return self.execute_command("set_gif_splash_screen", {
2961
+ "gif_path": gif_path,
2962
+ "close_on_load": close_on_load,
2963
+ "stay_on_top": stay_on_top,
2964
+ "clickable": clickable,
2965
+ "position": position
2966
+ })
2967
+
2968
+ def close_splash_screen(self) -> None:
2969
+ """
2970
+ Closes the splash screen if it exists.
2971
+
2972
+ Examples
2973
+ --------
2974
+ >>> window.close_splash_screen()
1955
2975
  """
1956
- self.web_view.custom_page.setDesktopMediaHandler(handler)
2976
+ return self.execute_command("close_splash_screen", {})
2977
+