pyloid 0.21.0.dev1__py3-none-any.whl → 0.22.0__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/__init__.py +2 -2
- pyloid/browser_window.py +1149 -208
- pyloid/js_api/base.py +29 -0
- pyloid/js_api/event_api.py +3 -3
- pyloid/js_api/window_api.py +254 -251
- pyloid/pyloid.py +901 -35
- pyloid/serve.py +56 -0
- pyloid/utils.py +36 -0
- {pyloid-0.21.0.dev1.dist-info → pyloid-0.22.0.dist-info}/LICENSE +1 -1
- {pyloid-0.21.0.dev1.dist-info → pyloid-0.22.0.dist-info}/METADATA +1 -2
- pyloid-0.22.0.dist-info/RECORD +20 -0
- pyloid/builder/__init__.py +0 -81
- pyloid/builder/build_config.schema.json +0 -73
- pyloid/builder/spec.py +0 -266
- pyloid-0.21.0.dev1.dist-info/RECORD +0 -21
- {pyloid-0.21.0.dev1.dist-info → pyloid-0.22.0.dist-info}/WHEEL +0 -0
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,19 +23,14 @@ from PySide6.QtWidgets import (
|
|
25
23
|
QVBoxLayout,
|
26
24
|
)
|
27
25
|
from .custom.titlebar import CustomTitleBar
|
28
|
-
from .js_api.
|
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 typing import TYPE_CHECKING
|
32
|
-
from PySide6.QtWebEngineCore import
|
33
|
-
QWebEngineSettings,
|
34
|
-
QWebEngineDesktopMediaRequest,
|
35
|
-
QWebEngineUrlRequestInterceptor,
|
36
|
-
)
|
37
|
-
from .utils import get_production_path, is_production
|
29
|
+
from typing import TYPE_CHECKING, Any
|
30
|
+
from PySide6.QtWebEngineCore import QWebEngineSettings, QWebEngineDesktopMediaRequest
|
38
31
|
|
39
32
|
if TYPE_CHECKING:
|
40
|
-
from
|
33
|
+
from .pyloid import _Pyloid
|
41
34
|
|
42
35
|
|
43
36
|
class CustomWebPage(QWebEnginePage):
|
@@ -72,6 +65,7 @@ class CustomWebPage(QWebEnginePage):
|
|
72
65
|
self._permission_handlers[feature] = handler
|
73
66
|
|
74
67
|
def _handleDesktopMediaRequest(self, request: QWebEngineDesktopMediaRequest):
|
68
|
+
return
|
75
69
|
print("Desktop media request received:", request)
|
76
70
|
|
77
71
|
# 사용 가능한 화면 목록 확인
|
@@ -89,79 +83,66 @@ class CustomWebPage(QWebEnginePage):
|
|
89
83
|
window_index = windows_model.index(i)
|
90
84
|
window_name = windows_model.data(window_index)
|
91
85
|
print(f"Window {i}: {window_name}")
|
92
|
-
|
86
|
+
|
93
87
|
request.selectWindow(windows_model.index(3))
|
94
88
|
|
95
|
-
# interceptor ( navigation request )
|
96
|
-
def acceptNavigationRequest(self, url, navigation_type, is_main_frame):
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
print(f"Is Main Frame: {is_main_frame}")
|
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}")
|
102
95
|
|
103
|
-
|
104
|
-
if url.scheme() == "file":
|
105
|
-
# 파일 경로에서 file:/// 제거
|
106
|
-
file_path = url_string.replace("file:///", "").rstrip("/")
|
107
|
-
|
108
|
-
# HTML 파일이 아닌 경우에만 index.html로 리다이렉트
|
109
|
-
if not file_path.endswith(".html"):
|
110
|
-
base_path = os.path.dirname(file_path)
|
111
|
-
self.setUrl(QUrl.fromLocalFile(os.path.join(base_path, "index.html")))
|
112
|
-
return False
|
113
|
-
|
114
|
-
return True
|
96
|
+
# return True
|
115
97
|
|
116
98
|
|
117
99
|
# interceptor ( all url request )
|
118
|
-
class CustomUrlInterceptor(QWebEngineUrlRequestInterceptor):
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
100
|
+
# class CustomUrlInterceptor(QWebEngineUrlRequestInterceptor):
|
101
|
+
# def interceptRequest(self, info):
|
102
|
+
# url = info.requestUrl().toString()
|
103
|
+
# print(url)
|
123
104
|
|
124
105
|
# class CustomInterceptor(QWebEngineUrlRequestInterceptor):
|
125
106
|
# def __init__(self, index_path=None):
|
126
107
|
# super().__init__()
|
127
108
|
# self.index_path = get_production_path()
|
128
109
|
# self.last_path = "/"
|
129
|
-
|
110
|
+
|
130
111
|
# def interceptRequest(self, info):
|
131
112
|
# url = info.requestUrl()
|
132
113
|
# navigation_type = info.navigationType()
|
133
114
|
|
134
115
|
# print("--------------------------------")
|
135
|
-
|
116
|
+
|
136
117
|
# if navigation_type == QWebEnginePage.NavigationType.NavigationTypeTyped:
|
137
118
|
# print("NavigationTypeTyped")
|
138
|
-
|
119
|
+
|
139
120
|
# if navigation_type == QWebEnginePage.NavigationType.NavigationTypeReload:
|
140
121
|
# print("NavigationTypeReload")
|
141
|
-
|
122
|
+
|
142
123
|
# if navigation_type == QWebEnginePage.NavigationType.NavigationTypeBackForward:
|
143
124
|
# print("NavigationTypeBackForward")
|
144
|
-
|
125
|
+
|
145
126
|
# if navigation_type == QWebEnginePage.NavigationType.NavigationTypeLinkClicked:
|
146
127
|
# print("NavigationTypeLinkClicked")
|
147
|
-
|
128
|
+
|
148
129
|
# if navigation_type == QWebEnginePage.NavigationType.NavigationTypeFormSubmitted:
|
149
130
|
# print("NavigationTypeFormSubmitted")
|
150
|
-
|
131
|
+
|
151
132
|
# if navigation_type == QWebEnginePage.NavigationType.NavigationTypeTyped:
|
152
133
|
# print("NavigationTypeTyped")
|
153
|
-
|
134
|
+
|
154
135
|
# if navigation_type == QWebEnginePage.NavigationType.NavigationTypeOther:
|
155
136
|
# print("NavigationTypeOther")
|
156
|
-
|
137
|
+
|
157
138
|
# print(navigation_type.value)
|
158
|
-
|
139
|
+
|
159
140
|
# print(url)
|
160
141
|
# print(url.scheme())
|
161
142
|
# print(url.host())
|
162
143
|
# print(url.url())
|
163
144
|
# print(self.last_path)
|
164
|
-
|
145
|
+
|
165
146
|
# self.last_path = url.path()
|
166
147
|
|
167
148
|
|
@@ -307,10 +288,10 @@ class CustomWebEngineView(QWebEngineView):
|
|
307
288
|
self.resize_start_pos = global_pos
|
308
289
|
|
309
290
|
|
310
|
-
class
|
291
|
+
class _BrowserWindow:
|
311
292
|
def __init__(
|
312
293
|
self,
|
313
|
-
app: "
|
294
|
+
app: "_Pyloid",
|
314
295
|
title: str = "pyloid app",
|
315
296
|
width: int = 800,
|
316
297
|
height: int = 600,
|
@@ -337,7 +318,7 @@ class BrowserWindow:
|
|
337
318
|
self.frame = frame
|
338
319
|
self.context_menu = context_menu
|
339
320
|
self.dev_tools = dev_tools
|
340
|
-
self.js_apis = [
|
321
|
+
self.js_apis = [BaseAPI(self.id, self.app.data)]
|
341
322
|
for js_api in js_apis:
|
342
323
|
self.js_apis.append(js_api)
|
343
324
|
self.shortcuts = {}
|
@@ -489,10 +470,10 @@ class BrowserWindow:
|
|
489
470
|
|
490
471
|
# Set F12 shortcut
|
491
472
|
self.set_dev_tools(self.dev_tools)
|
492
|
-
|
473
|
+
|
493
474
|
# 프로필 가져오기 및 인터셉터 설정
|
494
475
|
profile = self.web_view.page().profile()
|
495
|
-
|
476
|
+
|
496
477
|
# # 기존 인터셉터가 있다면 제거
|
497
478
|
# if self.interceptor:
|
498
479
|
# profile.setUrlRequestInterceptor(None)
|
@@ -552,26 +533,10 @@ class BrowserWindow:
|
|
552
533
|
|
553
534
|
document.addEventListener('mousedown', function (e) {
|
554
535
|
if (e.target.hasAttribute('data-pyloid-drag-region')) {
|
555
|
-
window.pyloid.
|
536
|
+
window.pyloid.BaseAPI.startSystemDrag();
|
556
537
|
}
|
557
538
|
});
|
558
539
|
|
559
|
-
function updateTheme(theme) {
|
560
|
-
document.documentElement.setAttribute(
|
561
|
-
'data-pyloid-theme',
|
562
|
-
theme
|
563
|
-
);
|
564
|
-
}
|
565
|
-
|
566
|
-
// 테마 변경 이벤트 리스너
|
567
|
-
document.addEventListener('themeChange', (e) => {
|
568
|
-
console.log('themeChange event received:', e);
|
569
|
-
updateTheme(e.detail.theme);
|
570
|
-
});
|
571
|
-
|
572
|
-
updateTheme('%s');
|
573
|
-
|
574
|
-
|
575
540
|
// Dispatch a custom event to signal that the initialization is ready
|
576
541
|
const event = new CustomEvent('pyloidReady');
|
577
542
|
document.dispatchEvent(event);
|
@@ -587,7 +552,7 @@ class BrowserWindow:
|
|
587
552
|
for js_api in self.js_apis
|
588
553
|
]
|
589
554
|
)
|
590
|
-
self.web_view.page().runJavaScript(js_code % (js_api_init
|
555
|
+
self.web_view.page().runJavaScript(js_code % (js_api_init))
|
591
556
|
|
592
557
|
# if splash screen is set, close it when the page is loaded
|
593
558
|
if self.close_on_load and self.splash_screen:
|
@@ -885,9 +850,9 @@ class BrowserWindow:
|
|
885
850
|
|
886
851
|
def _remove_from_app_windows(self):
|
887
852
|
"""Removes the window from the app's window list."""
|
888
|
-
if self in self.app.
|
889
|
-
self.app.
|
890
|
-
if not self.app.
|
853
|
+
if self in self.app.windows_dict:
|
854
|
+
self.app.windows_dict.pop(self.id)
|
855
|
+
if not self.app.windows_dict:
|
891
856
|
self.app.quit() # Quit the app if all windows are closed
|
892
857
|
|
893
858
|
###########################################################################################
|
@@ -927,11 +892,14 @@ class BrowserWindow:
|
|
927
892
|
>>> window = app.create_window("pyloid-window")
|
928
893
|
>>> window.focus()
|
929
894
|
"""
|
895
|
+
was_on_top = bool(self._window.windowFlags() & Qt.WindowStaysOnTopHint)
|
896
|
+
if not was_on_top:
|
897
|
+
self._window.setWindowFlag(Qt.WindowStaysOnTopHint, True)
|
898
|
+
self._window.show()
|
930
899
|
self._window.activateWindow()
|
931
|
-
|
932
|
-
|
933
|
-
self._window.
|
934
|
-
)
|
900
|
+
if not was_on_top:
|
901
|
+
self._window.setWindowFlag(Qt.WindowStaysOnTopHint, False)
|
902
|
+
self._window.show()
|
935
903
|
|
936
904
|
def show_and_focus(self):
|
937
905
|
"""
|
@@ -943,12 +911,14 @@ class BrowserWindow:
|
|
943
911
|
>>> window = app.create_window("pyloid-window")
|
944
912
|
>>> window.show_and_focus()
|
945
913
|
"""
|
946
|
-
self._window.
|
914
|
+
was_on_top = bool(self._window.windowFlags() & Qt.WindowStaysOnTopHint)
|
915
|
+
if not was_on_top:
|
916
|
+
self._window.setWindowFlag(Qt.WindowStaysOnTopHint, True)
|
917
|
+
self._window.show()
|
947
918
|
self._window.activateWindow()
|
948
|
-
|
949
|
-
|
950
|
-
self._window.
|
951
|
-
)
|
919
|
+
if not was_on_top:
|
920
|
+
self._window.setWindowFlag(Qt.WindowStaysOnTopHint, False)
|
921
|
+
self._window.show()
|
952
922
|
|
953
923
|
def close(self):
|
954
924
|
"""
|
@@ -1190,9 +1160,9 @@ class BrowserWindow:
|
|
1190
1160
|
###########################################################################################
|
1191
1161
|
# Event (Calling the JS from Python)
|
1192
1162
|
###########################################################################################
|
1193
|
-
def
|
1163
|
+
def invoke(self, event_name, data: Optional[Dict] = None):
|
1194
1164
|
"""
|
1195
|
-
|
1165
|
+
Invokes an event to the JavaScript side.
|
1196
1166
|
|
1197
1167
|
Parameters
|
1198
1168
|
----------
|
@@ -1208,7 +1178,7 @@ class BrowserWindow:
|
|
1208
1178
|
app = Pyloid(app_name="Pyloid-App")
|
1209
1179
|
|
1210
1180
|
window = app.create_window("pyloid-window")
|
1211
|
-
window.
|
1181
|
+
window.invoke("customEvent", {"message": "Hello, Pyloid!"})
|
1212
1182
|
|
1213
1183
|
app.run()
|
1214
1184
|
```
|
@@ -1590,52 +1560,52 @@ class BrowserWindow:
|
|
1590
1560
|
###########################################################################################
|
1591
1561
|
# For Custom Pyside6 Features
|
1592
1562
|
###########################################################################################
|
1593
|
-
def get_QMainWindow(self) -> QMainWindow:
|
1594
|
-
|
1595
|
-
|
1563
|
+
# def get_QMainWindow(self) -> QMainWindow:
|
1564
|
+
# """
|
1565
|
+
# Returns the QMainWindow object of the window.
|
1596
1566
|
|
1597
|
-
|
1567
|
+
# you can use all the features of QMainWindow for customizing the window.
|
1598
1568
|
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1569
|
+
# Returns
|
1570
|
+
# -------
|
1571
|
+
# QMainWindow
|
1572
|
+
# QMainWindow object of the window
|
1603
1573
|
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1574
|
+
# Examples
|
1575
|
+
# --------
|
1576
|
+
# ```python
|
1577
|
+
# from PySide6.QtCore import Qt
|
1578
|
+
# from pyloid import Pyloid
|
1609
1579
|
|
1610
|
-
|
1580
|
+
# app = Pyloid(app_name="Pyloid-App")
|
1611
1581
|
|
1612
|
-
|
1613
|
-
|
1582
|
+
# window = app.create_window("pyloid-window")
|
1583
|
+
# qmain = window.get_QMainWindow()
|
1614
1584
|
|
1615
|
-
|
1616
|
-
|
1617
|
-
|
1618
|
-
|
1585
|
+
# qmain.setWindowFlags(qmain.windowFlags() | Qt.WindowStaysOnTopHint) # window stays on top
|
1586
|
+
# ```
|
1587
|
+
# """
|
1588
|
+
# return self._window
|
1619
1589
|
|
1620
|
-
def get_QWebEngineView(self) -> CustomWebEngineView:
|
1621
|
-
|
1622
|
-
|
1590
|
+
# def get_QWebEngineView(self) -> CustomWebEngineView:
|
1591
|
+
# """
|
1592
|
+
# Returns the CustomWebEngineView object which inherits from QWebEngineView.
|
1623
1593
|
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1594
|
+
# Returns
|
1595
|
+
# -------
|
1596
|
+
# CustomWebEngineView
|
1597
|
+
# CustomWebEngineView object of the window
|
1628
1598
|
|
1629
|
-
|
1630
|
-
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1599
|
+
# Examples
|
1600
|
+
# --------
|
1601
|
+
# ```python
|
1602
|
+
# window = app.create_window("pyloid-window")
|
1603
|
+
# web_view = window.get_QWebEngineView()
|
1634
1604
|
|
1635
|
-
|
1636
|
-
|
1637
|
-
|
1638
|
-
|
1605
|
+
# web_view.page().runJavaScript("console.log('Hello, Pyloid!')")
|
1606
|
+
# ```
|
1607
|
+
# """
|
1608
|
+
# return self.web_view
|
1639
1609
|
|
1640
1610
|
###########################################################################################
|
1641
1611
|
# QMainWindow flags
|
@@ -1733,7 +1703,7 @@ class BrowserWindow:
|
|
1733
1703
|
Examples
|
1734
1704
|
--------
|
1735
1705
|
```python
|
1736
|
-
window.
|
1706
|
+
window.set_static_image_splash_screen("./assets/loading.png", close_on_load=True, stay_on_top=True)
|
1737
1707
|
```
|
1738
1708
|
"""
|
1739
1709
|
pixmap = QPixmap(image_path)
|
@@ -1871,150 +1841,1121 @@ class BrowserWindow:
|
|
1871
1841
|
###########################################################################################
|
1872
1842
|
# WebEngineView Attribute setting
|
1873
1843
|
###########################################################################################
|
1874
|
-
def set_web_engine_view_attribute(self, attribute: QWebEngineSettings, on: bool):
|
1844
|
+
# def set_web_engine_view_attribute(self, attribute: QWebEngineSettings, on: bool):
|
1845
|
+
# """
|
1846
|
+
# Sets the attribute of the WebEngineView.
|
1847
|
+
|
1848
|
+
# Parameters
|
1849
|
+
# ----------
|
1850
|
+
# attribute : QWebEngineSettings
|
1851
|
+
# Attribute to set
|
1852
|
+
# on : bool
|
1853
|
+
# True to enable the attribute, False to disable it
|
1854
|
+
|
1855
|
+
# Examples
|
1856
|
+
# --------
|
1857
|
+
# ```python
|
1858
|
+
# window.set_web_engine_view_attribute(QWebEngineSettings.WebAttribute.ScreenCaptureEnabled, False)
|
1859
|
+
# ```
|
1860
|
+
# """
|
1861
|
+
# settings = self.web_view.settings()
|
1862
|
+
# settings.setAttribute(attribute, on)
|
1863
|
+
|
1864
|
+
# def is_web_engine_view_attribute(self, attribute: QWebEngineSettings) -> bool:
|
1865
|
+
# """
|
1866
|
+
# Returns the attribute of the WebEngineView.
|
1867
|
+
|
1868
|
+
# Parameters
|
1869
|
+
# ----------
|
1870
|
+
# attribute : QWebEngineSettings
|
1871
|
+
# Attribute to get
|
1872
|
+
|
1873
|
+
# Returns
|
1874
|
+
# -------
|
1875
|
+
# bool
|
1876
|
+
# True if the attribute is enabled, False otherwise
|
1877
|
+
|
1878
|
+
# Examples
|
1879
|
+
# --------
|
1880
|
+
# ```python
|
1881
|
+
# window.is_web_engine_view_attribute(QWebEngineSettings.WebAttribute.ScreenCaptureEnabled)
|
1882
|
+
# ```
|
1883
|
+
# """
|
1884
|
+
# settings = self.web_view.settings()
|
1885
|
+
# return settings.testAttribute(attribute)
|
1886
|
+
|
1887
|
+
# def set_permission_handler(self, feature: QWebEnginePage.Feature, handler):
|
1888
|
+
# """
|
1889
|
+
# Sets a handler for a specific permission.
|
1890
|
+
|
1891
|
+
# Parameters
|
1892
|
+
# ----------
|
1893
|
+
# feature : QWebEnginePage.Feature
|
1894
|
+
# The type of permission to set
|
1895
|
+
# handler : callable
|
1896
|
+
# The handler function to process the permission request
|
1897
|
+
|
1898
|
+
# Examples
|
1899
|
+
# --------
|
1900
|
+
# ```python
|
1901
|
+
# def handle_camera(origin, feature):
|
1902
|
+
# window.web_view.page().setFeaturePermission(
|
1903
|
+
# origin,
|
1904
|
+
# feature,
|
1905
|
+
# QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
|
1906
|
+
# )
|
1907
|
+
|
1908
|
+
# window.set_permission_handler(
|
1909
|
+
# QWebEnginePage.Feature.MediaVideoCapture,
|
1910
|
+
# handle_camera
|
1911
|
+
# )
|
1912
|
+
# ```
|
1913
|
+
# """
|
1914
|
+
# self.web_view.custom_page.setPermissionHandler(feature, handler)
|
1915
|
+
|
1916
|
+
# def grant_permission(self, feature: QWebEnginePage.Feature):
|
1917
|
+
# """
|
1918
|
+
# Automatically grants a specific permission when a request is made.
|
1919
|
+
|
1920
|
+
# Parameters
|
1921
|
+
# ----------
|
1922
|
+
# feature : QWebEnginePage.Feature
|
1923
|
+
# The type of permission to automatically grant
|
1924
|
+
|
1925
|
+
# Examples
|
1926
|
+
# --------
|
1927
|
+
# ```python
|
1928
|
+
# window.grant_permission(QWebEnginePage.Feature.MediaVideoCapture)
|
1929
|
+
# ```
|
1930
|
+
# """
|
1931
|
+
|
1932
|
+
# def auto_grant(origin, feat):
|
1933
|
+
# self.web_view.page().setFeaturePermission(
|
1934
|
+
# origin, feat, QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
|
1935
|
+
# )
|
1936
|
+
|
1937
|
+
# self.set_permission_handler(feature, auto_grant)
|
1938
|
+
|
1939
|
+
# def deny_permission(self, feature: QWebEnginePage.Feature):
|
1940
|
+
# """
|
1941
|
+
# Automatically denies a specific permission when a request is made.
|
1942
|
+
|
1943
|
+
# Parameters
|
1944
|
+
# ----------
|
1945
|
+
# feature : QWebEnginePage.Feature
|
1946
|
+
# The type of permission to automatically deny
|
1947
|
+
|
1948
|
+
# Examples
|
1949
|
+
# --------
|
1950
|
+
# ```python
|
1951
|
+
# window.deny_permission(QWebEnginePage.Feature.Notifications)
|
1952
|
+
# ```
|
1953
|
+
# """
|
1954
|
+
|
1955
|
+
# def auto_deny(origin, feat):
|
1956
|
+
# self.web_view.page().setFeaturePermission(
|
1957
|
+
# origin, feat, QWebEnginePage.PermissionPolicy.PermissionDeniedByUser
|
1958
|
+
# )
|
1959
|
+
|
1960
|
+
# self.set_permission_handler(feature, auto_deny)
|
1961
|
+
|
1962
|
+
# def set_desktop_media_handler(self, handler):
|
1963
|
+
# """
|
1964
|
+
# 데스크톱 미디어(화면/윈도우) 선택 핸들러를 설정합니다.
|
1965
|
+
|
1966
|
+
# Parameters
|
1967
|
+
# ----------
|
1968
|
+
# handler : callable
|
1969
|
+
# 요청을 처리할 핸들러 함수. QWebEngineDesktopMediaRequest 인자로 받습니다.
|
1970
|
+
|
1971
|
+
# Examples
|
1972
|
+
# --------
|
1973
|
+
# ```python
|
1974
|
+
# def custom_media_handler(request):
|
1975
|
+
# # 사용 가능한 화면 목록 출력
|
1976
|
+
# for screen in request.screenList():
|
1977
|
+
# print(f"Screen: {screen.name}")
|
1978
|
+
|
1979
|
+
# # 사용 가능한 윈도우 목록 출력
|
1980
|
+
# for window in request.windowList():
|
1981
|
+
# print(f"Window: {window.name}")
|
1982
|
+
|
1983
|
+
# # 첫 번째 화면 선택
|
1984
|
+
# if request.screenList():
|
1985
|
+
# request.selectScreen(request.screenList()[0])
|
1986
|
+
|
1987
|
+
# window.set_desktop_media_handler(custom_media_handler)
|
1988
|
+
# ```
|
1989
|
+
# """
|
1990
|
+
# self.web_view.custom_page.setDesktopMediaHandler(handler)
|
1991
|
+
|
1992
|
+
|
1993
|
+
# This wrapper class work in other thread
|
1994
|
+
class BrowserWindow(QObject):
|
1995
|
+
command_signal = Signal(str, str, object)
|
1996
|
+
result_signal = Signal(str, object)
|
1997
|
+
|
1998
|
+
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]):
|
1999
|
+
super().__init__()
|
2000
|
+
self._window = _BrowserWindow(app, title, width, height, x, y, frame, context_menu, dev_tools, js_apis)
|
2001
|
+
self.command_signal.connect(self._handle_command)
|
2002
|
+
|
2003
|
+
@Slot(str, str, object)
|
2004
|
+
def _handle_command(self, command_id: str, command_type: str, params: object) -> None:
|
2005
|
+
"""
|
2006
|
+
Handles commands sent from multiple threads.
|
2007
|
+
Calls the corresponding method of _BrowserWindow based on the command type and returns the result.
|
2008
|
+
|
2009
|
+
:param command_id: Unique identifier for each command
|
2010
|
+
:param command_type: Type of command to execute (e.g., "load_file", "set_title", etc.)
|
2011
|
+
:param params: Object containing parameters needed for command execution
|
2012
|
+
"""
|
2013
|
+
result = None
|
2014
|
+
|
2015
|
+
if command_type == "load_file":
|
2016
|
+
result = self._window.load_file(params["file_path"])
|
2017
|
+
elif command_type == "load_url":
|
2018
|
+
result = self._window.load_url(params["url"])
|
2019
|
+
elif command_type == "load_html":
|
2020
|
+
html_content = params.get("html_content", "")
|
2021
|
+
base_url = params.get("base_url", "")
|
2022
|
+
result = self._window.load_html(html_content, base_url)
|
2023
|
+
elif command_type == "set_title":
|
2024
|
+
result = self._window.set_title(params["title"])
|
2025
|
+
elif command_type == "set_size":
|
2026
|
+
result = self._window.set_size(params["width"], params["height"])
|
2027
|
+
elif command_type == "set_position":
|
2028
|
+
result = self._window.set_position(params["x"], params["y"])
|
2029
|
+
elif command_type == "set_position_by_anchor":
|
2030
|
+
result = self._window.set_position_by_anchor(params["anchor"])
|
2031
|
+
elif command_type == "set_frame":
|
2032
|
+
result = self._window.set_frame(params["frame"])
|
2033
|
+
elif command_type == "set_context_menu":
|
2034
|
+
result = self._window.set_context_menu(params["context_menu"])
|
2035
|
+
elif command_type == "set_dev_tools":
|
2036
|
+
result = self._window.set_dev_tools(params["enable"])
|
2037
|
+
elif command_type == "open_dev_tools":
|
2038
|
+
result = self._window.open_dev_tools()
|
2039
|
+
elif command_type == "hide":
|
2040
|
+
result = self._window.hide()
|
2041
|
+
elif command_type == "show":
|
2042
|
+
result = self._window.show()
|
2043
|
+
elif command_type == "focus":
|
2044
|
+
result = self._window.focus()
|
2045
|
+
elif command_type == "show_and_focus":
|
2046
|
+
result = self._window.show_and_focus()
|
2047
|
+
elif command_type == "close":
|
2048
|
+
result = self._window.close()
|
2049
|
+
elif command_type == "fullscreen":
|
2050
|
+
result = self._window.fullscreen()
|
2051
|
+
elif command_type == "toggle_fullscreen":
|
2052
|
+
result = self._window.toggle_fullscreen()
|
2053
|
+
elif command_type == "minimize":
|
2054
|
+
result = self._window.minimize()
|
2055
|
+
elif command_type == "maximize":
|
2056
|
+
result = self._window.maximize()
|
2057
|
+
elif command_type == "unmaximize":
|
2058
|
+
result = self._window.unmaximize()
|
2059
|
+
elif command_type == "toggle_maximize":
|
2060
|
+
result = self._window.toggle_maximize()
|
2061
|
+
elif command_type == "is_fullscreen":
|
2062
|
+
result = self._window.is_fullscreen()
|
2063
|
+
elif command_type == "is_maximized":
|
2064
|
+
result = self._window.is_maximized()
|
2065
|
+
elif command_type == "capture":
|
2066
|
+
result = self._window.capture(params["save_path"])
|
2067
|
+
elif command_type == "add_shortcut":
|
2068
|
+
result = self._window.add_shortcut(params["key_sequence"], params["callback"])
|
2069
|
+
elif command_type == "remove_shortcut":
|
2070
|
+
result = self._window.remove_shortcut(params["key_sequence"])
|
2071
|
+
elif command_type == "get_all_shortcuts":
|
2072
|
+
result = self._window.get_all_shortcuts()
|
2073
|
+
elif command_type == "emit":
|
2074
|
+
event_name = params["event_name"]
|
2075
|
+
data = params.get("data")
|
2076
|
+
result = self._window.invoke(event_name, data)
|
2077
|
+
elif command_type == "get_window_properties":
|
2078
|
+
result = self._window.get_window_properties()
|
2079
|
+
elif command_type == "get_id":
|
2080
|
+
result = self._window.get_id()
|
2081
|
+
elif command_type == "get_size":
|
2082
|
+
result = self._window.get_size()
|
2083
|
+
elif command_type == "get_position":
|
2084
|
+
result = self._window.get_position()
|
2085
|
+
elif command_type == "get_title":
|
2086
|
+
result = self._window.get_title()
|
2087
|
+
elif command_type == "get_url":
|
2088
|
+
result = self._window.get_url()
|
2089
|
+
elif command_type == "get_visible":
|
2090
|
+
result = self._window.get_visible()
|
2091
|
+
elif command_type == "get_frame":
|
2092
|
+
result = self._window.get_frame()
|
2093
|
+
elif command_type == "set_resizable":
|
2094
|
+
result = self._window.set_resizable(params["resizable"])
|
2095
|
+
elif command_type == "set_minimum_size":
|
2096
|
+
result = self._window.set_minimum_size(params["min_width"], params["min_height"])
|
2097
|
+
elif command_type == "set_maximum_size":
|
2098
|
+
result = self._window.set_maximum_size(params["max_width"], params["max_height"])
|
2099
|
+
elif command_type == "get_minimum_size":
|
2100
|
+
result = self._window.get_minimum_size()
|
2101
|
+
elif command_type == "get_maximum_size":
|
2102
|
+
result = self._window.get_maximum_size()
|
2103
|
+
elif command_type == "get_resizable":
|
2104
|
+
result = self._window.get_resizable()
|
2105
|
+
elif command_type == "set_static_image_splash_screen":
|
2106
|
+
result = self._window.set_static_image_splash_screen(
|
2107
|
+
params["image_path"],
|
2108
|
+
params.get("close_on_load", True),
|
2109
|
+
params.get("stay_on_top", True),
|
2110
|
+
params.get("clickable", True),
|
2111
|
+
params.get("position", "center")
|
2112
|
+
)
|
2113
|
+
elif command_type == "set_gif_splash_screen":
|
2114
|
+
result = self._window.set_gif_splash_screen(
|
2115
|
+
params["gif_path"],
|
2116
|
+
params.get("close_on_load", True),
|
2117
|
+
params.get("stay_on_top", True),
|
2118
|
+
params.get("clickable", True),
|
2119
|
+
params.get("position", "center")
|
2120
|
+
)
|
2121
|
+
elif command_type == "close_splash_screen":
|
2122
|
+
result = self._window.close_splash_screen()
|
2123
|
+
else:
|
2124
|
+
return None
|
2125
|
+
|
2126
|
+
self.result_signal.emit(command_id, result)
|
2127
|
+
|
2128
|
+
def execute_command(self, command_type: str, params: object, timeout: Optional[int] = None):
|
2129
|
+
command_id = str(uuid.uuid4())
|
2130
|
+
|
2131
|
+
result_data = [None]
|
2132
|
+
loop = QEventLoop()
|
2133
|
+
|
2134
|
+
if timeout:
|
2135
|
+
timer = QTimer()
|
2136
|
+
timer.setSingleShot(True)
|
2137
|
+
timer.timeout.connect(loop.quit)
|
2138
|
+
timer.start(timeout)
|
2139
|
+
|
2140
|
+
def on_result(received_id, result):
|
2141
|
+
if received_id == command_id:
|
2142
|
+
result_data[0] = result
|
2143
|
+
loop.quit()
|
2144
|
+
|
2145
|
+
|
2146
|
+
self.result_signal.connect(on_result, Qt.QueuedConnection)
|
2147
|
+
|
2148
|
+
self.command_signal.emit(command_id, command_type, params)
|
2149
|
+
|
2150
|
+
loop.exec()
|
2151
|
+
|
2152
|
+
self.result_signal.disconnect(on_result)
|
2153
|
+
|
2154
|
+
return result_data[0]
|
2155
|
+
|
2156
|
+
# -------------------------------------------------------------------
|
2157
|
+
# Execute_command wrapper functions
|
2158
|
+
# -------------------------------------------------------------------
|
2159
|
+
def load_file(self, file_path: str) -> None:
|
1875
2160
|
"""
|
1876
|
-
|
2161
|
+
Loads a local HTML file into the web view.
|
1877
2162
|
|
1878
2163
|
Parameters
|
1879
2164
|
----------
|
1880
|
-
|
1881
|
-
|
1882
|
-
on : bool
|
1883
|
-
True to enable the attribute, False to disable it
|
2165
|
+
file_path : str
|
2166
|
+
The path to the local HTML file to be loaded.
|
1884
2167
|
|
1885
2168
|
Examples
|
1886
2169
|
--------
|
1887
|
-
|
1888
|
-
window.
|
1889
|
-
|
2170
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2171
|
+
>>> window = app.create_window("pyloid-window")
|
2172
|
+
>>> window.load_file('/path/to/local/file.html')
|
2173
|
+
>>> window.show()
|
1890
2174
|
"""
|
1891
|
-
|
1892
|
-
settings.setAttribute(attribute, on)
|
2175
|
+
return self.execute_command("load_file", {"file_path": file_path})
|
1893
2176
|
|
1894
|
-
def
|
2177
|
+
def load_url(self, url: str) -> None:
|
1895
2178
|
"""
|
1896
|
-
|
2179
|
+
Sets the URL of the window.
|
1897
2180
|
|
1898
2181
|
Parameters
|
1899
2182
|
----------
|
1900
|
-
|
1901
|
-
|
2183
|
+
url : str
|
2184
|
+
The URL to be loaded in the web view.
|
1902
2185
|
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
2186
|
+
Examples
|
2187
|
+
--------
|
2188
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2189
|
+
>>> window = app.create_window("pyloid-window")
|
2190
|
+
>>> window.load_url('https://www.example.com')
|
2191
|
+
>>> window.show()
|
2192
|
+
"""
|
2193
|
+
return self.execute_command("load_url", {"url": url})
|
2194
|
+
|
2195
|
+
def load_html(self, html_content: str, base_url: str = "") -> None:
|
2196
|
+
"""
|
2197
|
+
Loads HTML content directly into the web view.
|
2198
|
+
|
2199
|
+
Parameters
|
2200
|
+
----------
|
2201
|
+
html_content : str
|
2202
|
+
The HTML content to be loaded.
|
2203
|
+
base_url : str, optional
|
2204
|
+
The base URL to use for resolving relative URLs (default is "").
|
1907
2205
|
|
1908
2206
|
Examples
|
1909
2207
|
--------
|
1910
|
-
|
1911
|
-
window.
|
1912
|
-
|
2208
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2209
|
+
>>> window = app.create_window("pyloid-window")
|
2210
|
+
>>> html_content = "<html><body><h1>Hello, Pyloid!</h1></body></html>"
|
2211
|
+
>>> window.load_html(html_content)
|
2212
|
+
>>> window.show()
|
1913
2213
|
"""
|
1914
|
-
|
1915
|
-
return settings.testAttribute(attribute)
|
2214
|
+
return self.execute_command("load_html", {"html_content": html_content, "base_url": base_url})
|
1916
2215
|
|
1917
|
-
def
|
2216
|
+
def set_title(self, title: str) -> None:
|
1918
2217
|
"""
|
1919
|
-
Sets
|
2218
|
+
Sets the title of the window.
|
1920
2219
|
|
1921
2220
|
Parameters
|
1922
2221
|
----------
|
1923
|
-
|
1924
|
-
The
|
1925
|
-
handler : callable
|
1926
|
-
The handler function to process the permission request
|
2222
|
+
title : str
|
2223
|
+
The title to be set for the window.
|
1927
2224
|
|
1928
2225
|
Examples
|
1929
2226
|
--------
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
|
1936
|
-
)
|
2227
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2228
|
+
>>> window = app.create_window("pyloid-window")
|
2229
|
+
>>> window.set_title('My Window Title')
|
2230
|
+
"""
|
2231
|
+
return self.execute_command("set_title", {"title": title})
|
1937
2232
|
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
2233
|
+
def set_size(self, width: int, height: int) -> None:
|
2234
|
+
"""
|
2235
|
+
Sets the size of the window.
|
2236
|
+
|
2237
|
+
Parameters
|
2238
|
+
----------
|
2239
|
+
width : int
|
2240
|
+
The width of the window.
|
2241
|
+
height : int
|
2242
|
+
The height of the window.
|
2243
|
+
|
2244
|
+
Examples
|
2245
|
+
--------
|
2246
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2247
|
+
>>> window = app.create_window("pyloid-window")
|
2248
|
+
>>> window.set_size(800, 600)
|
1943
2249
|
"""
|
1944
|
-
self.
|
2250
|
+
return self.execute_command("set_size", {"width": width, "height": height})
|
1945
2251
|
|
1946
|
-
def
|
2252
|
+
def set_position(self, x: int, y: int) -> None:
|
1947
2253
|
"""
|
1948
|
-
|
2254
|
+
Sets the position of the window.
|
1949
2255
|
|
1950
2256
|
Parameters
|
1951
2257
|
----------
|
1952
|
-
|
1953
|
-
The
|
2258
|
+
x : int
|
2259
|
+
The x-coordinate of the window's position.
|
2260
|
+
y : int
|
2261
|
+
The y-coordinate of the window's position.
|
1954
2262
|
|
1955
2263
|
Examples
|
1956
2264
|
--------
|
1957
|
-
|
1958
|
-
window.
|
1959
|
-
|
2265
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2266
|
+
>>> window = app.create_window("pyloid-window")
|
2267
|
+
>>> window.set_position(100, 100)
|
1960
2268
|
"""
|
2269
|
+
return self.execute_command("set_position", {"x": x, "y": y})
|
1961
2270
|
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
)
|
2271
|
+
def set_position_by_anchor(self, anchor: str) -> None:
|
2272
|
+
"""
|
2273
|
+
Positions the window at a specific location on the screen.
|
1966
2274
|
|
1967
|
-
|
2275
|
+
Parameters
|
2276
|
+
----------
|
2277
|
+
anchor : str
|
2278
|
+
The anchor point indicating where to position the window.
|
2279
|
+
Possible values: 'center', 'top', 'bottom', 'left', 'right',
|
2280
|
+
'top-left', 'top-right', 'bottom-left', 'bottom-right'
|
2281
|
+
|
2282
|
+
Examples
|
2283
|
+
--------
|
2284
|
+
>>> window.set_position_by_anchor('center')
|
2285
|
+
>>> window.set_position_by_anchor('top-right')
|
2286
|
+
"""
|
2287
|
+
return self.execute_command("set_position_by_anchor", {"anchor": anchor})
|
1968
2288
|
|
1969
|
-
def
|
2289
|
+
def set_frame(self, frame: bool) -> None:
|
1970
2290
|
"""
|
1971
|
-
|
2291
|
+
Sets the frame of the window.
|
1972
2292
|
|
1973
2293
|
Parameters
|
1974
2294
|
----------
|
1975
|
-
|
1976
|
-
|
2295
|
+
frame : bool
|
2296
|
+
If True, the window will have a frame. If False, the window will be frameless.
|
1977
2297
|
|
1978
2298
|
Examples
|
1979
2299
|
--------
|
1980
|
-
|
1981
|
-
window.
|
1982
|
-
|
2300
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2301
|
+
>>> window = app.create_window("pyloid-window")
|
2302
|
+
>>> window.set_frame(True)
|
2303
|
+
>>> window.set_frame(False)
|
1983
2304
|
"""
|
2305
|
+
return self.execute_command("set_frame", {"frame": frame})
|
1984
2306
|
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
)
|
2307
|
+
def set_context_menu(self, context_menu: bool) -> None:
|
2308
|
+
"""
|
2309
|
+
Sets the context menu of the window.
|
1989
2310
|
|
1990
|
-
|
2311
|
+
Parameters
|
2312
|
+
----------
|
2313
|
+
context_menu : bool
|
2314
|
+
If True, the context menu will be disabled. If False, the default context menu will be enabled.
|
2315
|
+
|
2316
|
+
Examples
|
2317
|
+
--------
|
2318
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2319
|
+
>>> window = app.create_window("pyloid-window")
|
2320
|
+
>>> window.set_context_menu(True)
|
2321
|
+
>>> window.set_context_menu(False)
|
2322
|
+
"""
|
2323
|
+
return self.execute_command("set_context_menu", {"context_menu": context_menu})
|
1991
2324
|
|
1992
|
-
def
|
2325
|
+
def set_dev_tools(self, enable: bool) -> None:
|
1993
2326
|
"""
|
1994
|
-
|
2327
|
+
Sets the developer tools of the window.
|
2328
|
+
|
2329
|
+
If enabled, the developer tools can be opened using the F12 key.
|
1995
2330
|
|
1996
2331
|
Parameters
|
1997
2332
|
----------
|
1998
|
-
|
1999
|
-
|
2333
|
+
enable : bool
|
2334
|
+
If True, the developer tools will be enabled. If False, the developer tools will be disabled.
|
2000
2335
|
|
2001
2336
|
Examples
|
2002
2337
|
--------
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2338
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2339
|
+
>>> window = app.create_window("pyloid-window")
|
2340
|
+
>>> window.set_dev_tools(True)
|
2341
|
+
>>> window.set_dev_tools(False)
|
2342
|
+
"""
|
2343
|
+
return self.execute_command("set_dev_tools", {"enable": enable})
|
2008
2344
|
|
2009
|
-
|
2010
|
-
|
2011
|
-
|
2345
|
+
def open_dev_tools(self) -> None:
|
2346
|
+
"""
|
2347
|
+
Opens the developer tools window.
|
2012
2348
|
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2349
|
+
Examples
|
2350
|
+
--------
|
2351
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2352
|
+
>>> window = app.create_window("pyloid-window")
|
2353
|
+
>>> window.open_dev_tools()
|
2354
|
+
"""
|
2355
|
+
return self.execute_command("open_dev_tools", {})
|
2016
2356
|
|
2017
|
-
|
2018
|
-
|
2357
|
+
def hide(self) -> None:
|
2358
|
+
"""
|
2359
|
+
Hides the window.
|
2360
|
+
|
2361
|
+
Examples
|
2362
|
+
--------
|
2363
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2364
|
+
>>> window = app.create_window("pyloid-window")
|
2365
|
+
>>> window.hide()
|
2366
|
+
"""
|
2367
|
+
return self.execute_command("hide", {})
|
2368
|
+
|
2369
|
+
def show(self) -> None:
|
2370
|
+
"""
|
2371
|
+
Shows the window.
|
2372
|
+
|
2373
|
+
Examples
|
2374
|
+
--------
|
2375
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2376
|
+
>>> window = app.create_window("pyloid-window")
|
2377
|
+
>>> window.show()
|
2378
|
+
"""
|
2379
|
+
return self.execute_command("show", {})
|
2380
|
+
|
2381
|
+
def focus(self) -> None:
|
2382
|
+
"""
|
2383
|
+
Focuses the window.
|
2384
|
+
|
2385
|
+
Examples
|
2386
|
+
--------
|
2387
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2388
|
+
>>> window = app.create_window("pyloid-window")
|
2389
|
+
>>> window.focus()
|
2390
|
+
"""
|
2391
|
+
return self.execute_command("focus", {})
|
2392
|
+
|
2393
|
+
def show_and_focus(self) -> None:
|
2394
|
+
"""
|
2395
|
+
Shows and focuses the window.
|
2396
|
+
|
2397
|
+
Examples
|
2398
|
+
--------
|
2399
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2400
|
+
>>> window = app.create_window("pyloid-window")
|
2401
|
+
>>> window.show_and_focus()
|
2402
|
+
"""
|
2403
|
+
return self.execute_command("show_and_focus", {})
|
2404
|
+
|
2405
|
+
def close(self) -> None:
|
2406
|
+
"""
|
2407
|
+
Closes the window.
|
2408
|
+
|
2409
|
+
Examples
|
2410
|
+
--------
|
2411
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2412
|
+
>>> window = app.create_window("pyloid-window")
|
2413
|
+
>>> window.close()
|
2414
|
+
"""
|
2415
|
+
return self.execute_command("close", {})
|
2416
|
+
|
2417
|
+
def fullscreen(self) -> None:
|
2418
|
+
"""
|
2419
|
+
Enters fullscreen mode.
|
2420
|
+
|
2421
|
+
Examples
|
2422
|
+
--------
|
2423
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2424
|
+
>>> window = app.create_window("pyloid-window")
|
2425
|
+
>>> window.fullscreen()
|
2426
|
+
"""
|
2427
|
+
return self.execute_command("fullscreen", {})
|
2428
|
+
|
2429
|
+
def toggle_fullscreen(self) -> None:
|
2430
|
+
"""
|
2431
|
+
Toggles the fullscreen mode of the window.
|
2432
|
+
|
2433
|
+
Examples
|
2434
|
+
--------
|
2435
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2436
|
+
>>> window = app.create_window("pyloid-window")
|
2437
|
+
>>> window.toggle_fullscreen()
|
2438
|
+
"""
|
2439
|
+
return self.execute_command("toggle_fullscreen", {})
|
2440
|
+
|
2441
|
+
def minimize(self) -> None:
|
2442
|
+
"""
|
2443
|
+
Minimizes the window.
|
2444
|
+
|
2445
|
+
Examples
|
2446
|
+
--------
|
2447
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2448
|
+
>>> window = app.create_window("pyloid-window")
|
2449
|
+
>>> window.minimize()
|
2450
|
+
"""
|
2451
|
+
return self.execute_command("minimize", {})
|
2452
|
+
|
2453
|
+
def maximize(self) -> None:
|
2454
|
+
"""
|
2455
|
+
Maximizes the window.
|
2456
|
+
|
2457
|
+
Examples
|
2458
|
+
--------
|
2459
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2460
|
+
>>> window = app.create_window("pyloid-window")
|
2461
|
+
>>> window.maximize()
|
2462
|
+
"""
|
2463
|
+
return self.execute_command("maximize", {})
|
2464
|
+
|
2465
|
+
def unmaximize(self) -> None:
|
2466
|
+
"""
|
2467
|
+
Restores the window from maximized state.
|
2468
|
+
|
2469
|
+
Examples
|
2470
|
+
--------
|
2471
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2472
|
+
>>> window = app.create_window("pyloid-window")
|
2473
|
+
>>> window.unmaximize()
|
2474
|
+
"""
|
2475
|
+
return self.execute_command("unmaximize", {})
|
2476
|
+
|
2477
|
+
def toggle_maximize(self) -> None:
|
2478
|
+
"""
|
2479
|
+
Toggles the maximized state of the window.
|
2480
|
+
|
2481
|
+
Examples
|
2482
|
+
--------
|
2483
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2484
|
+
>>> window = app.create_window("pyloid-window")
|
2485
|
+
>>> window.toggle_maximize()
|
2486
|
+
"""
|
2487
|
+
return self.execute_command("toggle_maximize", {})
|
2488
|
+
|
2489
|
+
def is_fullscreen(self) -> bool:
|
2490
|
+
"""
|
2491
|
+
Returns True if the window is fullscreen.
|
2492
|
+
|
2493
|
+
Examples
|
2494
|
+
--------
|
2495
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2496
|
+
>>> window = app.create_window("pyloid-window")
|
2497
|
+
>>> window.is_fullscreen()
|
2498
|
+
"""
|
2499
|
+
return self.execute_command("is_fullscreen", {})
|
2500
|
+
|
2501
|
+
def is_maximized(self) -> bool:
|
2502
|
+
"""
|
2503
|
+
Returns True if the window is maximized.
|
2504
|
+
|
2505
|
+
Examples
|
2506
|
+
--------
|
2507
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2508
|
+
>>> window = app.create_window("pyloid-window")
|
2509
|
+
>>> window.is_maximized()
|
2510
|
+
"""
|
2511
|
+
return self.execute_command("is_maximized", {})
|
2512
|
+
|
2513
|
+
def capture(self, save_path: str) -> "Optional[str]":
|
2514
|
+
"""
|
2515
|
+
Captures the current window.
|
2516
|
+
|
2517
|
+
Parameters
|
2518
|
+
----------
|
2519
|
+
save_path : str
|
2520
|
+
Path to save the captured image. If not specified, it will be saved in the current directory.
|
2521
|
+
|
2522
|
+
Returns
|
2523
|
+
-------
|
2524
|
+
Optional[str]
|
2525
|
+
Returns the path of the saved image.
|
2526
|
+
|
2527
|
+
Examples
|
2528
|
+
--------
|
2529
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2530
|
+
>>> window = app.create_window("pyloid-window")
|
2531
|
+
>>> save_path = window.capture("screenshot.png")
|
2532
|
+
>>> print(f"Image saved at: {save_path}")
|
2533
|
+
"""
|
2534
|
+
return self.execute_command("capture", {"save_path": save_path})
|
2535
|
+
|
2536
|
+
def add_shortcut(self, key_sequence: str, callback: Callable) -> Any:
|
2537
|
+
"""
|
2538
|
+
Adds a keyboard shortcut to the window if it does not already exist.
|
2539
|
+
|
2540
|
+
Parameters
|
2541
|
+
----------
|
2542
|
+
key_sequence : str
|
2543
|
+
Shortcut sequence (e.g., "Ctrl+C")
|
2544
|
+
callback : Callable
|
2545
|
+
Function to be executed when the shortcut is pressed
|
2546
|
+
|
2547
|
+
Returns
|
2548
|
+
-------
|
2549
|
+
QShortcut or None
|
2550
|
+
Created QShortcut object or None if the shortcut already exists
|
2551
|
+
|
2552
|
+
Examples
|
2553
|
+
--------
|
2554
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2555
|
+
>>> window = app.create_window("pyloid-window")
|
2556
|
+
>>> def on_shortcut():
|
2557
|
+
... print("Shortcut activated!")
|
2558
|
+
>>> window.add_shortcut("Ctrl+C", on_shortcut)
|
2559
|
+
>>> app.run()
|
2560
|
+
"""
|
2561
|
+
return self.execute_command("add_shortcut", {"key_sequence": key_sequence, "callback": callback})
|
2562
|
+
|
2563
|
+
def remove_shortcut(self, key_sequence: str) -> None:
|
2564
|
+
"""
|
2565
|
+
Removes a keyboard shortcut from the window.
|
2566
|
+
|
2567
|
+
Parameters
|
2568
|
+
----------
|
2569
|
+
key_sequence : str
|
2570
|
+
Shortcut sequence to be removed
|
2571
|
+
|
2572
|
+
Examples
|
2573
|
+
--------
|
2574
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2575
|
+
>>> window = app.create_window("pyloid-window")
|
2576
|
+
>>> window.remove_shortcut("Ctrl+C")
|
2577
|
+
>>> app.run()
|
2578
|
+
"""
|
2579
|
+
return self.execute_command("remove_shortcut", {"key_sequence": key_sequence})
|
2580
|
+
|
2581
|
+
def get_all_shortcuts(self) -> dict:
|
2582
|
+
"""
|
2583
|
+
Returns all registered shortcuts in the window.
|
2584
|
+
|
2585
|
+
Returns
|
2586
|
+
-------
|
2587
|
+
dict
|
2588
|
+
Dictionary of shortcut sequences and QShortcut objects
|
2589
|
+
|
2590
|
+
Examples
|
2591
|
+
--------
|
2592
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2593
|
+
>>> window = app.create_window("pyloid-window")
|
2594
|
+
>>> shortcuts = window.get_all_shortcuts()
|
2595
|
+
>>> print(shortcuts)
|
2596
|
+
>>> app.run()
|
2597
|
+
"""
|
2598
|
+
return self.execute_command("get_all_shortcuts", {})
|
2599
|
+
|
2600
|
+
def invoke(self, event_name: str, data: "Optional[Dict]" = None) -> None:
|
2601
|
+
"""
|
2602
|
+
Invokes an event to the JavaScript side.
|
2603
|
+
|
2604
|
+
Parameters
|
2605
|
+
----------
|
2606
|
+
event_name : str
|
2607
|
+
Name of the event
|
2608
|
+
data : dict, optional
|
2609
|
+
Data to be sent with the event (default is None)
|
2610
|
+
|
2611
|
+
Examples
|
2612
|
+
--------
|
2613
|
+
(Python)
|
2614
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2615
|
+
>>> window = app.create_window("pyloid-window")
|
2616
|
+
>>> window.invoke("customEvent", {"message": "Hello, Pyloid!"})
|
2617
|
+
|
2618
|
+
(JavaScript)
|
2619
|
+
>>> document.addEventListener('customEvent', (data) => {
|
2620
|
+
... console.log(data.message);
|
2621
|
+
... });
|
2622
|
+
"""
|
2623
|
+
return self.execute_command("invoke", {"event_name": event_name, "data": data})
|
2624
|
+
|
2625
|
+
def get_window_properties(self) -> dict:
|
2626
|
+
"""
|
2627
|
+
Returns the properties of the window.
|
2628
|
+
|
2629
|
+
Returns
|
2630
|
+
-------
|
2631
|
+
dict
|
2632
|
+
Dictionary containing the properties of the window
|
2633
|
+
|
2634
|
+
Examples
|
2635
|
+
--------
|
2636
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2637
|
+
>>> window = app.create_window("pyloid-window")
|
2638
|
+
>>> properties = window.get_window_properties()
|
2639
|
+
>>> print(properties)
|
2640
|
+
>>> app.run()
|
2641
|
+
"""
|
2642
|
+
return self.execute_command("get_window_properties", {})
|
2643
|
+
|
2644
|
+
def get_id(self) -> str:
|
2645
|
+
"""
|
2646
|
+
Returns the ID of the window.
|
2647
|
+
|
2648
|
+
Returns
|
2649
|
+
-------
|
2650
|
+
str
|
2651
|
+
ID of the window
|
2652
|
+
|
2653
|
+
Examples
|
2654
|
+
--------
|
2655
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2656
|
+
>>> window = app.create_window("pyloid-window")
|
2657
|
+
>>> window_id = window.get_id()
|
2658
|
+
>>> print(window_id)
|
2659
|
+
>>> app.run()
|
2660
|
+
"""
|
2661
|
+
return self.execute_command("get_id", {})
|
2662
|
+
|
2663
|
+
def get_size(self) -> "Dict[str, int]":
|
2664
|
+
"""
|
2665
|
+
Returns the size of the window.
|
2666
|
+
|
2667
|
+
Returns
|
2668
|
+
-------
|
2669
|
+
dict
|
2670
|
+
Dictionary containing the width and height of the window
|
2671
|
+
|
2672
|
+
Examples
|
2673
|
+
--------
|
2674
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2675
|
+
>>> window = app.create_window("pyloid-window")
|
2676
|
+
>>> size = window.get_size()
|
2677
|
+
>>> print(size)
|
2678
|
+
>>> app.run()
|
2679
|
+
"""
|
2680
|
+
return self.execute_command("get_size", {})
|
2681
|
+
|
2682
|
+
def get_position(self) -> "Dict[str, int]":
|
2683
|
+
"""
|
2684
|
+
Returns the position of the window.
|
2685
|
+
|
2686
|
+
Returns
|
2687
|
+
-------
|
2688
|
+
dict
|
2689
|
+
Dictionary containing the x and y coordinates of the window
|
2690
|
+
|
2691
|
+
Examples
|
2692
|
+
--------
|
2693
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2694
|
+
>>> window = app.create_window("pyloid-window")
|
2695
|
+
>>> position = window.get_position()
|
2696
|
+
>>> print(position)
|
2697
|
+
>>> app.run()
|
2698
|
+
"""
|
2699
|
+
return self.execute_command("get_position", {})
|
2700
|
+
|
2701
|
+
def get_title(self) -> str:
|
2702
|
+
"""
|
2703
|
+
Returns the title of the window.
|
2704
|
+
|
2705
|
+
Returns
|
2706
|
+
-------
|
2707
|
+
str
|
2708
|
+
Title of the window
|
2709
|
+
|
2710
|
+
Examples
|
2711
|
+
--------
|
2712
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2713
|
+
>>> window = app.create_window("pyloid-window")
|
2714
|
+
>>> title = window.get_title()
|
2715
|
+
>>> print(title)
|
2716
|
+
>>> app.run()
|
2717
|
+
"""
|
2718
|
+
return self.execute_command("get_title", {})
|
2719
|
+
|
2720
|
+
def get_url(self) -> str:
|
2721
|
+
"""
|
2722
|
+
Returns the URL of the window.
|
2723
|
+
|
2724
|
+
Returns
|
2725
|
+
-------
|
2726
|
+
str
|
2727
|
+
URL of the window
|
2728
|
+
|
2729
|
+
Examples
|
2730
|
+
--------
|
2731
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2732
|
+
>>> window = app.create_window("pyloid-window")
|
2733
|
+
>>> url = window.get_url()
|
2734
|
+
>>> print(url)
|
2735
|
+
>>> app.run()
|
2736
|
+
"""
|
2737
|
+
return self.execute_command("get_url", {})
|
2738
|
+
|
2739
|
+
def get_visible(self) -> bool:
|
2740
|
+
"""
|
2741
|
+
Returns the visibility of the window.
|
2742
|
+
|
2743
|
+
Returns
|
2744
|
+
-------
|
2745
|
+
bool
|
2746
|
+
True if the window is visible, False otherwise
|
2747
|
+
|
2748
|
+
Examples
|
2749
|
+
--------
|
2750
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2751
|
+
>>> window = app.create_window("pyloid-window")
|
2752
|
+
>>> visible = window.get_visible()
|
2753
|
+
>>> print(visible)
|
2754
|
+
>>> app.run()
|
2755
|
+
"""
|
2756
|
+
return self.execute_command("get_visible", {})
|
2757
|
+
|
2758
|
+
def get_frame(self) -> bool:
|
2759
|
+
"""
|
2760
|
+
Returns the frame enabled state of the window.
|
2761
|
+
|
2762
|
+
Returns
|
2763
|
+
-------
|
2764
|
+
bool
|
2765
|
+
True if the frame is enabled, False otherwise
|
2766
|
+
|
2767
|
+
Examples
|
2768
|
+
--------
|
2769
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2770
|
+
>>> window = app.create_window("pyloid-window")
|
2771
|
+
>>> frame = window.get_frame()
|
2772
|
+
>>> print(frame)
|
2773
|
+
>>> app.run()
|
2774
|
+
"""
|
2775
|
+
return self.execute_command("get_frame", {})
|
2776
|
+
|
2777
|
+
def set_resizable(self, resizable: bool) -> None:
|
2778
|
+
"""
|
2779
|
+
Sets the resizability of the window.
|
2780
|
+
|
2781
|
+
Parameters
|
2782
|
+
----------
|
2783
|
+
resizable : bool
|
2784
|
+
True to make the window resizable, False to make it fixed size
|
2785
|
+
|
2786
|
+
Examples
|
2787
|
+
--------
|
2788
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2789
|
+
>>> window = app.create_window("pyloid-window")
|
2790
|
+
>>> window.set_resizable(True)
|
2791
|
+
>>> app.run()
|
2792
|
+
"""
|
2793
|
+
return self.execute_command("set_resizable", {"resizable": resizable})
|
2794
|
+
|
2795
|
+
def set_minimum_size(self, min_width: int, min_height: int) -> None:
|
2796
|
+
"""
|
2797
|
+
Sets the minimum size of the window.
|
2798
|
+
|
2799
|
+
Parameters
|
2800
|
+
----------
|
2801
|
+
min_width : int
|
2802
|
+
Minimum width of the window
|
2803
|
+
min_height : int
|
2804
|
+
Minimum height of the window
|
2805
|
+
|
2806
|
+
Examples
|
2807
|
+
--------
|
2808
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2809
|
+
>>> window = app.create_window("pyloid-window")
|
2810
|
+
>>> window.set_minimum_size(400, 300)
|
2811
|
+
>>> app.run()
|
2812
|
+
"""
|
2813
|
+
return self.execute_command("set_minimum_size", {"min_width": min_width, "min_height": min_height})
|
2814
|
+
|
2815
|
+
def set_maximum_size(self, max_width: int, max_height: int) -> None:
|
2816
|
+
"""
|
2817
|
+
Sets the maximum size of the window.
|
2818
|
+
|
2819
|
+
Parameters
|
2820
|
+
----------
|
2821
|
+
max_width : int
|
2822
|
+
Maximum width of the window
|
2823
|
+
max_height : int
|
2824
|
+
Maximum height of the window
|
2825
|
+
|
2826
|
+
Examples
|
2827
|
+
--------
|
2828
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2829
|
+
>>> window = app.create_window("pyloid-window")
|
2830
|
+
>>> window.set_maximum_size(1024, 768)
|
2831
|
+
>>> app.run()
|
2832
|
+
"""
|
2833
|
+
return self.execute_command("set_maximum_size", {"max_width": max_width, "max_height": max_height})
|
2834
|
+
|
2835
|
+
def get_minimum_size(self) -> "Dict[str, int]":
|
2836
|
+
"""
|
2837
|
+
Returns the minimum size of the window.
|
2838
|
+
|
2839
|
+
Returns
|
2840
|
+
-------
|
2841
|
+
dict
|
2842
|
+
Dictionary containing the minimum width and height of the window
|
2843
|
+
|
2844
|
+
Examples
|
2845
|
+
--------
|
2846
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2847
|
+
>>> window = app.create_window("pyloid-window")
|
2848
|
+
>>> min_size = window.get_minimum_size()
|
2849
|
+
>>> print(min_size)
|
2850
|
+
>>> app.run()
|
2851
|
+
"""
|
2852
|
+
return self.execute_command("get_minimum_size", {})
|
2853
|
+
|
2854
|
+
def get_maximum_size(self) -> "Dict[str, int]":
|
2855
|
+
"""
|
2856
|
+
Returns the maximum size of the window.
|
2857
|
+
|
2858
|
+
Returns
|
2859
|
+
-------
|
2860
|
+
dict
|
2861
|
+
Dictionary containing the maximum width and height of the window
|
2862
|
+
|
2863
|
+
Examples
|
2864
|
+
--------
|
2865
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2866
|
+
>>> window = app.create_window("pyloid-window")
|
2867
|
+
>>> max_size = window.get_maximum_size()
|
2868
|
+
>>> print(max_size)
|
2869
|
+
>>> app.run()
|
2870
|
+
"""
|
2871
|
+
return self.execute_command("get_maximum_size", {})
|
2872
|
+
|
2873
|
+
def get_resizable(self) -> bool:
|
2874
|
+
"""
|
2875
|
+
Returns the resizability of the window.
|
2876
|
+
|
2877
|
+
Returns
|
2878
|
+
-------
|
2879
|
+
bool
|
2880
|
+
True if the window is resizable, False otherwise
|
2881
|
+
|
2882
|
+
Examples
|
2883
|
+
--------
|
2884
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
2885
|
+
>>> window = app.create_window("pyloid-window")
|
2886
|
+
>>> resizable = window.get_resizable()
|
2887
|
+
>>> print(resizable)
|
2888
|
+
>>> app.run()
|
2889
|
+
"""
|
2890
|
+
return self.execute_command("get_resizable", {})
|
2891
|
+
|
2892
|
+
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:
|
2893
|
+
"""
|
2894
|
+
Sets the static image splash screen of the window.
|
2895
|
+
|
2896
|
+
Parameters
|
2897
|
+
----------
|
2898
|
+
image_path : str
|
2899
|
+
Path to the image file
|
2900
|
+
close_on_load : bool, optional
|
2901
|
+
True to close the splash screen when the page is loaded, False otherwise (default is True)
|
2902
|
+
stay_on_top : bool, optional
|
2903
|
+
True to keep the splash screen on top, False otherwise (default is True)
|
2904
|
+
clickable : bool, optional
|
2905
|
+
True to make the splash screen clickable, False otherwise (default is True)
|
2906
|
+
if clickable is True, you can click the splash screen to close it.
|
2907
|
+
position : str, optional
|
2908
|
+
Position of the splash screen. Options are 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right' (default is 'center')
|
2909
|
+
|
2910
|
+
Examples
|
2911
|
+
--------
|
2912
|
+
>>> window.set_static_image_splash_screen("./assets/loading.png", close_on_load=True, stay_on_top=True)
|
2913
|
+
"""
|
2914
|
+
return self.execute_command("set_static_image_splash_screen", {
|
2915
|
+
"image_path": image_path,
|
2916
|
+
"close_on_load": close_on_load,
|
2917
|
+
"stay_on_top": stay_on_top,
|
2918
|
+
"clickable": clickable,
|
2919
|
+
"position": position
|
2920
|
+
})
|
2921
|
+
|
2922
|
+
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:
|
2923
|
+
"""
|
2924
|
+
Sets the gif splash screen of the window.
|
2925
|
+
|
2926
|
+
Parameters
|
2927
|
+
----------
|
2928
|
+
gif_path : str
|
2929
|
+
Path to the gif file
|
2930
|
+
close_on_load : bool, optional
|
2931
|
+
True to close the splash screen when the page is loaded, False otherwise (default is True)
|
2932
|
+
stay_on_top : bool, optional
|
2933
|
+
True to keep the splash screen on top, False otherwise (default is True)
|
2934
|
+
clickable : bool, optional
|
2935
|
+
True to make the splash screen clickable, False otherwise (default is True)
|
2936
|
+
if clickable is True, you can click the splash screen to close it.
|
2937
|
+
position : str, optional
|
2938
|
+
Position of the splash screen. Options are 'center', 'top-left', 'top-right', 'bottom-left', 'bottom-right' (default is 'center')
|
2939
|
+
|
2940
|
+
Examples
|
2941
|
+
--------
|
2942
|
+
>>> window.set_gif_splash_screen("./assets/loading.gif", close_on_load=True, stay_on_top=True)
|
2943
|
+
"""
|
2944
|
+
return self.execute_command("set_gif_splash_screen", {
|
2945
|
+
"gif_path": gif_path,
|
2946
|
+
"close_on_load": close_on_load,
|
2947
|
+
"stay_on_top": stay_on_top,
|
2948
|
+
"clickable": clickable,
|
2949
|
+
"position": position
|
2950
|
+
})
|
2951
|
+
|
2952
|
+
def close_splash_screen(self) -> None:
|
2953
|
+
"""
|
2954
|
+
Closes the splash screen if it exists.
|
2955
|
+
|
2956
|
+
Examples
|
2957
|
+
--------
|
2958
|
+
>>> window.close_splash_screen()
|
2019
2959
|
"""
|
2020
|
-
self.
|
2960
|
+
return self.execute_command("close_splash_screen", {})
|
2961
|
+
|