pyloid 0.13.0__py3-none-any.whl → 0.14.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/api.py +85 -2
- pyloid/browser_window.py +1190 -0
- pyloid/filewatcher.py +137 -9
- pyloid/js_api/event_api.py +25 -0
- pyloid/js_api/window_api.py +166 -0
- pyloid/monitor.py +602 -77
- pyloid/pyloid.py +661 -892
- pyloid/timer.py +222 -38
- pyloid/tray.py +30 -0
- pyloid/utils.py +55 -6
- {pyloid-0.13.0.dist-info → pyloid-0.14.0.dist-info}/METADATA +1 -1
- pyloid-0.14.0.dist-info/RECORD +17 -0
- pyloid-0.13.0.dist-info/RECORD +0 -14
- {pyloid-0.13.0.dist-info → pyloid-0.14.0.dist-info}/LICENSE +0 -0
- {pyloid-0.13.0.dist-info → pyloid-0.14.0.dist-info}/WHEEL +0 -0
pyloid/browser_window.py
ADDED
@@ -0,0 +1,1190 @@
|
|
1
|
+
import sys
|
2
|
+
import os
|
3
|
+
from PySide6.QtWidgets import (
|
4
|
+
QMainWindow,
|
5
|
+
)
|
6
|
+
from PySide6.QtWebEngineWidgets import QWebEngineView
|
7
|
+
from PySide6.QtWebChannel import QWebChannel
|
8
|
+
from PySide6.QtGui import (
|
9
|
+
QKeySequence,
|
10
|
+
QShortcut,
|
11
|
+
QCursor,
|
12
|
+
)
|
13
|
+
from PySide6.QtCore import Qt, QPoint, QUrl, QEvent
|
14
|
+
from PySide6.QtWebEngineCore import QWebEnginePage, QWebEngineSettings
|
15
|
+
from .api import PyloidAPI
|
16
|
+
import uuid
|
17
|
+
from typing import List, Optional, Dict, Callable
|
18
|
+
import json
|
19
|
+
from PySide6.QtWidgets import (
|
20
|
+
QWidget,
|
21
|
+
QVBoxLayout,
|
22
|
+
)
|
23
|
+
from .custom.titlebar import CustomTitleBar
|
24
|
+
from .js_api.window_api import WindowAPI
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
# 어차피 load 부분에만 쓰이니까 나중에 분리해서 load 위에서 선언하자.
|
29
|
+
class CustomWebEngineView(QWebEngineView):
|
30
|
+
def __init__(self, parent=None):
|
31
|
+
super().__init__(parent._window)
|
32
|
+
self.parent = parent
|
33
|
+
self.drag_relative_position = None
|
34
|
+
self.is_dragging = False
|
35
|
+
self.is_resizing = False
|
36
|
+
self.resize_start_pos = None
|
37
|
+
self.resize_direction = None
|
38
|
+
self.screen_geometry = self.screen().availableGeometry()
|
39
|
+
self.is_resizing_enabled = True
|
40
|
+
|
41
|
+
def mouse_press_event(self, event):
|
42
|
+
if event.button() == Qt.LeftButton:
|
43
|
+
self.drag_relative_position = event.pos()
|
44
|
+
if not self.parent.frame and self.is_resizing_enabled:
|
45
|
+
self.resize_direction = self.get_resize_direction(event.pos())
|
46
|
+
if self.resize_direction:
|
47
|
+
self.is_resizing = True
|
48
|
+
self.resize_start_pos = event.globalPos()
|
49
|
+
|
50
|
+
def start_system_drag(self):
|
51
|
+
self.is_dragging = True
|
52
|
+
|
53
|
+
def mouse_move_event(self, event):
|
54
|
+
if self.is_resizing and self.is_resizing_enabled:
|
55
|
+
self.resize_window(event.globalPos())
|
56
|
+
elif not self.parent.frame and self.is_dragging:
|
57
|
+
# 현재 마우스 위치를 전역 좌표로 가져옵니다
|
58
|
+
current_global_pos = event.globalPos()
|
59
|
+
|
60
|
+
# 화면 경계를 계산합니다
|
61
|
+
left_boundary = self.screen_geometry.left()
|
62
|
+
right_boundary = self.screen_geometry.right()
|
63
|
+
top_boundary = self.screen_geometry.top()
|
64
|
+
bottom_boundary = self.screen_geometry.bottom()
|
65
|
+
|
66
|
+
# 마우스 커서 위치를 제한합니다
|
67
|
+
new_cursor_pos = QPoint(
|
68
|
+
max(left_boundary, min(current_global_pos.x(), right_boundary)),
|
69
|
+
max(top_boundary, min(current_global_pos.y(), bottom_boundary)),
|
70
|
+
)
|
71
|
+
|
72
|
+
# 마우스 커서를 새 위치로 이동합니다
|
73
|
+
QCursor.setPos(new_cursor_pos)
|
74
|
+
|
75
|
+
# 창의 새 위치를 계산합니다
|
76
|
+
new_window_pos = new_cursor_pos - self.drag_relative_position
|
77
|
+
|
78
|
+
# 창을 새 위치로 이동합니다
|
79
|
+
self.parent._window.move(new_window_pos)
|
80
|
+
else:
|
81
|
+
# Change cursor based on resize direction
|
82
|
+
resize_direction = self.get_resize_direction(event.pos())
|
83
|
+
if resize_direction and self.is_resizing_enabled:
|
84
|
+
self.set_cursor_for_resize_direction(resize_direction)
|
85
|
+
else:
|
86
|
+
self.unsetCursor()
|
87
|
+
|
88
|
+
def mouse_release_event(self, event):
|
89
|
+
if event.button() == Qt.LeftButton:
|
90
|
+
self.is_dragging = False
|
91
|
+
self.is_resizing = False
|
92
|
+
self.resize_direction = None
|
93
|
+
self.unsetCursor()
|
94
|
+
|
95
|
+
def eventFilter(self, source, event):
|
96
|
+
if self.focusProxy() is source:
|
97
|
+
if event.type() == QEvent.MouseButtonPress:
|
98
|
+
self.mouse_press_event(event)
|
99
|
+
elif event.type() == QEvent.MouseMove:
|
100
|
+
self.mouse_move_event(event)
|
101
|
+
elif event.type() == QEvent.MouseButtonRelease:
|
102
|
+
self.mouse_release_event(event)
|
103
|
+
return super().eventFilter(source, event)
|
104
|
+
|
105
|
+
def get_resize_direction(self, pos):
|
106
|
+
if not self.parent.frame and self.is_resizing_enabled: # Check if frame is not present and resizing is enabled
|
107
|
+
margin = 5 # Margin in pixels to detect edge
|
108
|
+
rect = self.rect()
|
109
|
+
direction = None
|
110
|
+
|
111
|
+
if pos.x() <= margin:
|
112
|
+
direction = 'left'
|
113
|
+
elif pos.x() >= rect.width() - margin:
|
114
|
+
direction = 'right'
|
115
|
+
|
116
|
+
if pos.y() <= margin:
|
117
|
+
direction = 'top' if direction is None else direction + '-top'
|
118
|
+
elif pos.y() >= rect.height() - margin:
|
119
|
+
direction = 'bottom' if direction is None else direction + '-bottom'
|
120
|
+
|
121
|
+
return direction
|
122
|
+
return None
|
123
|
+
|
124
|
+
def set_cursor_for_resize_direction(self, direction):
|
125
|
+
if not self.parent.frame and direction and self.is_resizing_enabled: # Check if frame is not present and resizing is enabled
|
126
|
+
if direction in ['left', 'right']:
|
127
|
+
self.setCursor(Qt.SizeHorCursor)
|
128
|
+
elif direction in ['top', 'bottom']:
|
129
|
+
self.setCursor(Qt.SizeVerCursor)
|
130
|
+
elif direction in ['left-top', 'right-bottom']:
|
131
|
+
self.setCursor(Qt.SizeFDiagCursor)
|
132
|
+
elif direction in ['right-top', 'left-bottom']:
|
133
|
+
self.setCursor(Qt.SizeBDiagCursor)
|
134
|
+
|
135
|
+
def resize_window(self, global_pos):
|
136
|
+
if not self.parent.frame and self.resize_start_pos and self.resize_direction and self.is_resizing_enabled: # Check if frame is not present and resizing is enabled
|
137
|
+
delta = global_pos - self.resize_start_pos
|
138
|
+
new_geometry = self.parent._window.geometry()
|
139
|
+
|
140
|
+
if 'left' in self.resize_direction:
|
141
|
+
new_geometry.setLeft(new_geometry.left() + delta.x())
|
142
|
+
if 'right' in self.resize_direction:
|
143
|
+
new_geometry.setRight(new_geometry.right() + delta.x())
|
144
|
+
if 'top' in self.resize_direction:
|
145
|
+
new_geometry.setTop(new_geometry.top() + delta.y())
|
146
|
+
if 'bottom' in self.resize_direction:
|
147
|
+
new_geometry.setBottom(new_geometry.bottom() + delta.y())
|
148
|
+
|
149
|
+
self.parent._window.setGeometry(new_geometry)
|
150
|
+
self.resize_start_pos = global_pos
|
151
|
+
|
152
|
+
|
153
|
+
class BrowserWindow:
|
154
|
+
def __init__(
|
155
|
+
self,
|
156
|
+
app,
|
157
|
+
title: str = "pyloid app",
|
158
|
+
width: int = 800,
|
159
|
+
height: int = 600,
|
160
|
+
x: int = 200,
|
161
|
+
y: int = 200,
|
162
|
+
frame: bool = True,
|
163
|
+
context_menu: bool = False,
|
164
|
+
dev_tools: bool = False,
|
165
|
+
js_apis: List[PyloidAPI] = [],
|
166
|
+
):
|
167
|
+
###########################################################################################
|
168
|
+
self.id = str(uuid.uuid4()) # Generate unique ID
|
169
|
+
self._window = QMainWindow()
|
170
|
+
self.web_view = CustomWebEngineView(self)
|
171
|
+
|
172
|
+
self._window.closeEvent = self.closeEvent # Override closeEvent method
|
173
|
+
###########################################################################################
|
174
|
+
self.app = app
|
175
|
+
self.title = title
|
176
|
+
self.width = width
|
177
|
+
self.height = height
|
178
|
+
self.x = x
|
179
|
+
self.y = y
|
180
|
+
self.frame = frame
|
181
|
+
self.context_menu = context_menu
|
182
|
+
self.dev_tools = dev_tools
|
183
|
+
self.js_apis = [WindowAPI(self.id, self.app)]
|
184
|
+
for js_api in js_apis:
|
185
|
+
self.js_apis.append(js_api)
|
186
|
+
self.shortcuts = {}
|
187
|
+
###########################################################################################
|
188
|
+
|
189
|
+
def _set_custom_frame(
|
190
|
+
self,
|
191
|
+
use_custom: bool,
|
192
|
+
title: str = "Custom Title",
|
193
|
+
bg_color: str = "darkblue",
|
194
|
+
text_color: str = "white",
|
195
|
+
icon_path: str = None,
|
196
|
+
):
|
197
|
+
"""Sets or removes the custom frame."""
|
198
|
+
if use_custom:
|
199
|
+
self._window.setWindowFlags(Qt.FramelessWindowHint)
|
200
|
+
self.custom_title_bar = CustomTitleBar(self._window)
|
201
|
+
self.custom_title_bar.set_style(bg_color, text_color)
|
202
|
+
self.custom_title_bar.set_title(title)
|
203
|
+
|
204
|
+
if icon_path:
|
205
|
+
self.custom_title_bar.set_icon(icon_path)
|
206
|
+
|
207
|
+
layout = QVBoxLayout()
|
208
|
+
layout.setContentsMargins(0, 0, 0, 0)
|
209
|
+
layout.setSpacing(0)
|
210
|
+
layout.addWidget(self.custom_title_bar)
|
211
|
+
layout.addWidget(self.web_view)
|
212
|
+
|
213
|
+
central_widget = QWidget()
|
214
|
+
central_widget.setLayout(layout)
|
215
|
+
self._window.setCentralWidget(central_widget)
|
216
|
+
|
217
|
+
# Add properties for window movement
|
218
|
+
self._window.moving = False
|
219
|
+
self._window.offset = QPoint()
|
220
|
+
else:
|
221
|
+
self._window.setWindowFlags(Qt.Window)
|
222
|
+
self._window.setCentralWidget(self.web_view)
|
223
|
+
self.custom_title_bar = None
|
224
|
+
|
225
|
+
self._window.show()
|
226
|
+
|
227
|
+
def _load(self):
|
228
|
+
self.set_title(self.title)
|
229
|
+
|
230
|
+
self.set_size(self.width, self.height)
|
231
|
+
self.set_position(self.x, self.y)
|
232
|
+
|
233
|
+
# allow local file access to remote urls
|
234
|
+
self.web_view.settings().setAttribute(
|
235
|
+
QWebEngineSettings.LocalContentCanAccessRemoteUrls, True
|
236
|
+
)
|
237
|
+
|
238
|
+
# Set icon
|
239
|
+
if self.app.icon:
|
240
|
+
self._window.setWindowIcon(self.app.icon)
|
241
|
+
else:
|
242
|
+
print("Icon is not set.")
|
243
|
+
|
244
|
+
# Set Windows taskbar icon
|
245
|
+
if sys.platform == "win32":
|
246
|
+
import ctypes
|
247
|
+
|
248
|
+
myappid = "mycompany.myproduct.subproduct.version"
|
249
|
+
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
|
250
|
+
|
251
|
+
# Remove title bar and borders (if needed)
|
252
|
+
if not self.frame:
|
253
|
+
self._window.setWindowFlags(Qt.FramelessWindowHint)
|
254
|
+
|
255
|
+
# Disable default context menu
|
256
|
+
if not self.context_menu:
|
257
|
+
self.web_view.setContextMenuPolicy(Qt.NoContextMenu)
|
258
|
+
|
259
|
+
# Set up QWebChannel
|
260
|
+
self.channel = QWebChannel()
|
261
|
+
|
262
|
+
# Register additional JS APIs
|
263
|
+
if self.js_apis:
|
264
|
+
for js_api in self.js_apis:
|
265
|
+
self.channel.registerObject(js_api.__class__.__name__, js_api)
|
266
|
+
|
267
|
+
self.web_view.page().setWebChannel(self.channel)
|
268
|
+
|
269
|
+
# Connect pylonjs bridge
|
270
|
+
self.web_view.loadFinished.connect(self._on_load_finished)
|
271
|
+
|
272
|
+
# Add QWebEngineView to main window
|
273
|
+
self._window.setCentralWidget(self.web_view)
|
274
|
+
|
275
|
+
# Set F12 shortcut
|
276
|
+
self.set_dev_tools(self.dev_tools)
|
277
|
+
|
278
|
+
def _on_load_finished(self, ok):
|
279
|
+
"""Handles the event when the web page finishes loading."""
|
280
|
+
if ok and self.js_apis:
|
281
|
+
js_code = """
|
282
|
+
if (typeof QWebChannel !== 'undefined') {
|
283
|
+
new QWebChannel(qt.webChannelTransport, function (channel) {
|
284
|
+
window.pyloid = {
|
285
|
+
EventAPI: {
|
286
|
+
listen: function(eventName, callback) {
|
287
|
+
document.addEventListener(eventName, function(event) {
|
288
|
+
let eventData;
|
289
|
+
try {
|
290
|
+
eventData = JSON.parse(event.detail);
|
291
|
+
} catch (e) {
|
292
|
+
eventData = event.detail;
|
293
|
+
}
|
294
|
+
callback(eventData);
|
295
|
+
});
|
296
|
+
},
|
297
|
+
unlisten: function(eventName) {
|
298
|
+
document.removeEventListener(eventName);
|
299
|
+
}
|
300
|
+
}
|
301
|
+
};
|
302
|
+
console.log('pyloid.EventAPI object initialized:', window.pyloid.EventAPI);
|
303
|
+
|
304
|
+
%s
|
305
|
+
|
306
|
+
document.addEventListener('mousedown', function (e) {
|
307
|
+
if (e.target.hasAttribute('data-pyloid-drag-region')) {
|
308
|
+
window.pyloid.WindowAPI.startSystemDrag();
|
309
|
+
}
|
310
|
+
});
|
311
|
+
|
312
|
+
// Dispatch a custom event to signal that the initialization is ready
|
313
|
+
const event = new CustomEvent('pyloidReady');
|
314
|
+
document.dispatchEvent(event);
|
315
|
+
});
|
316
|
+
} else {
|
317
|
+
console.error('QWebChannel is not defined.');
|
318
|
+
}
|
319
|
+
"""
|
320
|
+
js_api_init = "\n".join(
|
321
|
+
[
|
322
|
+
f"window.pyloid['{js_api.__class__.__name__}'] = channel.objects['{js_api.__class__.__name__}'];\n"
|
323
|
+
f"console.log('pyloid.{js_api.__class__.__name__} object initialized:', window.pyloid['{js_api.__class__.__name__}']);"
|
324
|
+
for js_api in self.js_apis
|
325
|
+
]
|
326
|
+
)
|
327
|
+
self.web_view.page().runJavaScript(js_code % js_api_init)
|
328
|
+
else:
|
329
|
+
pass
|
330
|
+
|
331
|
+
###########################################################################################
|
332
|
+
# Load
|
333
|
+
###########################################################################################
|
334
|
+
def load_file(self, file_path):
|
335
|
+
"""
|
336
|
+
Loads a local HTML file into the web view.
|
337
|
+
|
338
|
+
Parameters
|
339
|
+
----------
|
340
|
+
file_path : str
|
341
|
+
The path to the local HTML file to be loaded.
|
342
|
+
|
343
|
+
Examples
|
344
|
+
--------
|
345
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
346
|
+
>>> window = app.create_window("pyloid-window")
|
347
|
+
>>> window.load_file('/path/to/local/file.html')
|
348
|
+
>>> window.show()
|
349
|
+
"""
|
350
|
+
self._load()
|
351
|
+
file_path = os.path.abspath(file_path) # absolute path
|
352
|
+
self.web_view.setUrl(QUrl.fromLocalFile(file_path))
|
353
|
+
self.web_view.focusProxy().installEventFilter(self.web_view)
|
354
|
+
|
355
|
+
def load_url(self, url):
|
356
|
+
"""
|
357
|
+
Sets the URL of the window.
|
358
|
+
|
359
|
+
Parameters
|
360
|
+
----------
|
361
|
+
url : str
|
362
|
+
The URL to be loaded in the web view.
|
363
|
+
|
364
|
+
Examples
|
365
|
+
--------
|
366
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
367
|
+
>>> window = app.create_window("pyloid-window")
|
368
|
+
>>> window.load_url('https://www.example.com')
|
369
|
+
>>> window.show()
|
370
|
+
"""
|
371
|
+
self._load()
|
372
|
+
self.web_view.setUrl(QUrl(url))
|
373
|
+
self.web_view.focusProxy().installEventFilter(self.web_view)
|
374
|
+
|
375
|
+
###########################################################################################
|
376
|
+
# Set Parameters
|
377
|
+
###########################################################################################
|
378
|
+
def set_title(self, title: str):
|
379
|
+
"""
|
380
|
+
Sets the title of the window.
|
381
|
+
|
382
|
+
Parameters
|
383
|
+
----------
|
384
|
+
title : str
|
385
|
+
The title to be set for the window.
|
386
|
+
|
387
|
+
Examples
|
388
|
+
--------
|
389
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
390
|
+
>>> window = app.create_window("pyloid-window")
|
391
|
+
>>> window.set_title('My Window Title')
|
392
|
+
"""
|
393
|
+
self.title = title
|
394
|
+
self._window.setWindowTitle(self.title)
|
395
|
+
|
396
|
+
def set_size(self, width: int, height: int):
|
397
|
+
"""
|
398
|
+
Sets the size of the window.
|
399
|
+
|
400
|
+
Parameters
|
401
|
+
----------
|
402
|
+
width : int
|
403
|
+
The width of the window.
|
404
|
+
height : int
|
405
|
+
The height of the window.
|
406
|
+
|
407
|
+
Examples
|
408
|
+
--------
|
409
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
410
|
+
>>> window = app.create_window("pyloid-window")
|
411
|
+
>>> window.set_size(800, 600)
|
412
|
+
"""
|
413
|
+
self.width = width
|
414
|
+
self.height = height
|
415
|
+
self._window.setGeometry(self.x, self.y, self.width, self.height)
|
416
|
+
|
417
|
+
def set_position(self, x: int, y: int):
|
418
|
+
"""
|
419
|
+
Sets the position of the window.
|
420
|
+
|
421
|
+
Parameters
|
422
|
+
----------
|
423
|
+
x : int
|
424
|
+
The x-coordinate of the window's position.
|
425
|
+
y : int
|
426
|
+
The y-coordinate of the window's position.
|
427
|
+
|
428
|
+
Examples
|
429
|
+
--------
|
430
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
431
|
+
>>> window = app.create_window("pyloid-window")
|
432
|
+
>>> window.set_position(100, 100)
|
433
|
+
"""
|
434
|
+
self.x = x
|
435
|
+
self.y = y
|
436
|
+
self._window.setGeometry(self.x, self.y, self.width, self.height)
|
437
|
+
|
438
|
+
def set_frame(self, frame: bool):
|
439
|
+
"""
|
440
|
+
Sets the frame of the window.
|
441
|
+
|
442
|
+
Parameters
|
443
|
+
----------
|
444
|
+
frame : bool
|
445
|
+
If True, the window will have a frame. If False, the window will be frameless.
|
446
|
+
|
447
|
+
Examples
|
448
|
+
--------
|
449
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
450
|
+
>>> window = app.create_window("pyloid-window")
|
451
|
+
>>> window.set_frame(True)
|
452
|
+
>>> window.set_frame(False)
|
453
|
+
"""
|
454
|
+
self.frame = frame
|
455
|
+
was_visible = self._window.isVisible()
|
456
|
+
if self.frame:
|
457
|
+
self._window.setWindowFlags(Qt.Window)
|
458
|
+
else:
|
459
|
+
self._window.setWindowFlags(Qt.FramelessWindowHint)
|
460
|
+
if was_visible:
|
461
|
+
self._window.show()
|
462
|
+
|
463
|
+
def set_context_menu(self, context_menu: bool):
|
464
|
+
"""
|
465
|
+
Sets the context menu of the window.
|
466
|
+
|
467
|
+
Parameters
|
468
|
+
----------
|
469
|
+
context_menu : bool
|
470
|
+
If True, the context menu will be disabled. If False, the default context menu will be enabled.
|
471
|
+
|
472
|
+
Examples
|
473
|
+
--------
|
474
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
475
|
+
>>> window = app.create_window("pyloid-window")
|
476
|
+
>>> window.set_context_menu(True)
|
477
|
+
>>> window.set_context_menu(False)
|
478
|
+
"""
|
479
|
+
self.context_menu = context_menu
|
480
|
+
if self.context_menu:
|
481
|
+
self.web_view.setContextMenuPolicy(Qt.NoContextMenu)
|
482
|
+
else:
|
483
|
+
self.web_view.setContextMenuPolicy(Qt.DefaultContextMenu)
|
484
|
+
|
485
|
+
def set_dev_tools(self, enable: bool):
|
486
|
+
"""
|
487
|
+
Sets the developer tools of the window.
|
488
|
+
|
489
|
+
If enabled, the developer tools can be opened using the F12 key.
|
490
|
+
|
491
|
+
Parameters
|
492
|
+
----------
|
493
|
+
enable : bool
|
494
|
+
If True, the developer tools will be enabled. If False, the developer tools will be disabled.
|
495
|
+
|
496
|
+
Examples
|
497
|
+
--------
|
498
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
499
|
+
>>> window = app.create_window("pyloid-window")
|
500
|
+
>>> window.set_dev_tools(True)
|
501
|
+
>>> window.set_dev_tools(False)
|
502
|
+
"""
|
503
|
+
self.dev_tools = enable
|
504
|
+
if self.dev_tools:
|
505
|
+
self.add_shortcut("F12", self.open_dev_tools)
|
506
|
+
else:
|
507
|
+
self.remove_shortcut("F12")
|
508
|
+
|
509
|
+
def open_dev_tools(self):
|
510
|
+
"""
|
511
|
+
Opens the developer tools window.
|
512
|
+
|
513
|
+
Examples
|
514
|
+
--------
|
515
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
516
|
+
>>> window = app.create_window("pyloid-window")
|
517
|
+
>>> window.open_dev_tools()
|
518
|
+
"""
|
519
|
+
self.web_view.page().setDevToolsPage(QWebEnginePage(self.web_view.page()))
|
520
|
+
self.dev_tools_window = QMainWindow(self._window)
|
521
|
+
dev_tools_view = QWebEngineView(self.dev_tools_window)
|
522
|
+
dev_tools_view.setPage(self.web_view.page().devToolsPage())
|
523
|
+
self.dev_tools_window.setCentralWidget(dev_tools_view)
|
524
|
+
self.dev_tools_window.resize(800, 600)
|
525
|
+
self.dev_tools_window.show()
|
526
|
+
|
527
|
+
# Add this line to handle dev tools window closure
|
528
|
+
self.dev_tools_window.closeEvent = lambda event: setattr(
|
529
|
+
self, "dev_tools_window", None
|
530
|
+
)
|
531
|
+
|
532
|
+
def closeEvent(self, event):
|
533
|
+
"""Handles the event when the window is closed."""
|
534
|
+
# Close developer tools if open
|
535
|
+
if hasattr(self, "dev_tools_window") and self.dev_tools_window:
|
536
|
+
self.dev_tools_window.close()
|
537
|
+
self.dev_tools_window = None
|
538
|
+
|
539
|
+
# Solve memory leak issue with web view engine
|
540
|
+
self.web_view.page().deleteLater()
|
541
|
+
self.web_view.deleteLater()
|
542
|
+
self._remove_from_app_windows()
|
543
|
+
event.accept() # Accept the event (allow the window to close)
|
544
|
+
|
545
|
+
def _remove_from_app_windows(self):
|
546
|
+
"""Removes the window from the app's window list."""
|
547
|
+
if self in self.app.windows:
|
548
|
+
self.app.windows.remove(self)
|
549
|
+
if not self.app.windows:
|
550
|
+
self.app.quit() # Quit the app if all windows are closed
|
551
|
+
|
552
|
+
###########################################################################################
|
553
|
+
# Window management (no ID required)
|
554
|
+
###########################################################################################
|
555
|
+
def hide(self):
|
556
|
+
"""
|
557
|
+
Hides the window.
|
558
|
+
|
559
|
+
Examples
|
560
|
+
--------
|
561
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
562
|
+
>>> window = app.create_window("pyloid-window")
|
563
|
+
>>> window.hide()
|
564
|
+
"""
|
565
|
+
self._window.hide()
|
566
|
+
|
567
|
+
def show(self):
|
568
|
+
"""
|
569
|
+
Shows the window.
|
570
|
+
|
571
|
+
Examples
|
572
|
+
--------
|
573
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
574
|
+
>>> window = app.create_window("pyloid-window")
|
575
|
+
>>> window.show()
|
576
|
+
"""
|
577
|
+
self._window.show()
|
578
|
+
|
579
|
+
def focus(self):
|
580
|
+
"""
|
581
|
+
Focuses the window.
|
582
|
+
|
583
|
+
Examples
|
584
|
+
--------
|
585
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
586
|
+
>>> window = app.create_window("pyloid-window")
|
587
|
+
>>> window.focus()
|
588
|
+
"""
|
589
|
+
self._window.activateWindow()
|
590
|
+
self._window.raise_()
|
591
|
+
self._window.setWindowState(
|
592
|
+
self._window.windowState() & ~Qt.WindowMinimized | Qt.WindowActive
|
593
|
+
)
|
594
|
+
|
595
|
+
def show_and_focus(self):
|
596
|
+
"""
|
597
|
+
Shows and focuses the window.
|
598
|
+
|
599
|
+
Examples
|
600
|
+
--------
|
601
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
602
|
+
>>> window = app.create_window("pyloid-window")
|
603
|
+
>>> window.show_and_focus()
|
604
|
+
"""
|
605
|
+
self._window.show()
|
606
|
+
self._window.activateWindow()
|
607
|
+
self._window.raise_()
|
608
|
+
self._window.setWindowState(
|
609
|
+
self._window.windowState() & ~Qt.WindowMinimized | Qt.WindowActive
|
610
|
+
)
|
611
|
+
|
612
|
+
def close(self):
|
613
|
+
"""
|
614
|
+
Closes the window.
|
615
|
+
|
616
|
+
Examples
|
617
|
+
--------
|
618
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
619
|
+
>>> window = app.create_window("pyloid-window")
|
620
|
+
>>> window.close()
|
621
|
+
"""
|
622
|
+
self._window.close()
|
623
|
+
|
624
|
+
def toggle_fullscreen(self):
|
625
|
+
"""
|
626
|
+
Toggles the fullscreen mode of the window.
|
627
|
+
|
628
|
+
Examples
|
629
|
+
--------
|
630
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
631
|
+
>>> window = app.create_window("pyloid-window")
|
632
|
+
>>> window.toggle_fullscreen()
|
633
|
+
"""
|
634
|
+
if self._window.isFullScreen():
|
635
|
+
self._window.showNormal()
|
636
|
+
else:
|
637
|
+
self._window.showFullScreen()
|
638
|
+
|
639
|
+
def minimize(self):
|
640
|
+
"""
|
641
|
+
Minimizes the window.
|
642
|
+
|
643
|
+
Examples
|
644
|
+
--------
|
645
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
646
|
+
>>> window = app.create_window("pyloid-window")
|
647
|
+
>>> window.minimize()
|
648
|
+
"""
|
649
|
+
self._window.showMinimized()
|
650
|
+
|
651
|
+
def maximize(self):
|
652
|
+
"""
|
653
|
+
Maximizes the window.
|
654
|
+
|
655
|
+
Examples
|
656
|
+
--------
|
657
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
658
|
+
>>> window = app.create_window("pyloid-window")
|
659
|
+
>>> window.maximize()
|
660
|
+
"""
|
661
|
+
self._window.showMaximized()
|
662
|
+
|
663
|
+
def unmaximize(self):
|
664
|
+
"""
|
665
|
+
Restores the window from maximized state.
|
666
|
+
|
667
|
+
Examples
|
668
|
+
--------
|
669
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
670
|
+
>>> window = app.create_window("pyloid-window")
|
671
|
+
>>> window.unmaximize()
|
672
|
+
"""
|
673
|
+
self._window.showNormal()
|
674
|
+
|
675
|
+
def capture(self, save_path: str) -> Optional[str]:
|
676
|
+
"""
|
677
|
+
Captures the current window.
|
678
|
+
|
679
|
+
Parameters
|
680
|
+
----------
|
681
|
+
save_path : str
|
682
|
+
Path to save the captured image. If not specified, it will be saved in the current directory.
|
683
|
+
|
684
|
+
Returns
|
685
|
+
-------
|
686
|
+
Optional[str]
|
687
|
+
Returns the path of the saved image.
|
688
|
+
|
689
|
+
Examples
|
690
|
+
--------
|
691
|
+
>>> app = Pyloid(app_name="Pyloid-App")
|
692
|
+
>>> window = app.create_window("pyloid-window")
|
693
|
+
>>> save_path = window.capture("screenshot.png")
|
694
|
+
>>> print(f"Image saved at: {save_path}")
|
695
|
+
Image saved at: screenshot.png
|
696
|
+
"""
|
697
|
+
try:
|
698
|
+
# Capture the window
|
699
|
+
screenshot = self._window.grab()
|
700
|
+
|
701
|
+
# Save the image
|
702
|
+
screenshot.save(save_path)
|
703
|
+
return save_path
|
704
|
+
except Exception as e:
|
705
|
+
print(f"An error occurred while capturing the window: {e}")
|
706
|
+
return None
|
707
|
+
|
708
|
+
###########################################################################################
|
709
|
+
# Shortcut
|
710
|
+
###########################################################################################
|
711
|
+
def add_shortcut(self, key_sequence: str, callback: Callable):
|
712
|
+
"""
|
713
|
+
Adds a keyboard shortcut to the window if it does not already exist.
|
714
|
+
|
715
|
+
Parameters
|
716
|
+
----------
|
717
|
+
key_sequence : str
|
718
|
+
Shortcut sequence (e.g., "Ctrl+C")
|
719
|
+
callback : Callable
|
720
|
+
Function to be executed when the shortcut is pressed
|
721
|
+
|
722
|
+
Returns
|
723
|
+
-------
|
724
|
+
QShortcut or None
|
725
|
+
Created QShortcut object or None if the shortcut already exists
|
726
|
+
|
727
|
+
Examples
|
728
|
+
--------
|
729
|
+
```python
|
730
|
+
app = Pyloid(app_name="Pyloid-App")
|
731
|
+
|
732
|
+
window = app.create_window("pyloid-window")
|
733
|
+
|
734
|
+
def on_shortcut():
|
735
|
+
print("Shortcut activated!")
|
736
|
+
window.add_shortcut("Ctrl+C", on_shortcut)
|
737
|
+
|
738
|
+
app.run()
|
739
|
+
```
|
740
|
+
"""
|
741
|
+
if key_sequence in self.shortcuts:
|
742
|
+
# print(f"Shortcut {key_sequence} already exists.")
|
743
|
+
return None
|
744
|
+
|
745
|
+
shortcut = QShortcut(QKeySequence(key_sequence), self._window)
|
746
|
+
shortcut.activated.connect(callback)
|
747
|
+
self.shortcuts[key_sequence] = shortcut
|
748
|
+
return shortcut
|
749
|
+
|
750
|
+
def remove_shortcut(self, key_sequence: str):
|
751
|
+
"""
|
752
|
+
Removes a keyboard shortcut from the window.
|
753
|
+
|
754
|
+
Parameters
|
755
|
+
----------
|
756
|
+
key_sequence : str
|
757
|
+
Shortcut sequence to be removed
|
758
|
+
|
759
|
+
Examples
|
760
|
+
--------
|
761
|
+
```python
|
762
|
+
app = Pyloid(app_name="Pyloid-App")
|
763
|
+
|
764
|
+
window = app.create_window("pyloid-window")
|
765
|
+
window.remove_shortcut("Ctrl+C")
|
766
|
+
|
767
|
+
app.run()
|
768
|
+
```
|
769
|
+
"""
|
770
|
+
if key_sequence in self.shortcuts:
|
771
|
+
shortcut = self.shortcuts.pop(key_sequence)
|
772
|
+
shortcut.setEnabled(False)
|
773
|
+
shortcut.deleteLater()
|
774
|
+
|
775
|
+
def get_all_shortcuts(self):
|
776
|
+
"""
|
777
|
+
Returns all registered shortcuts in the window.
|
778
|
+
|
779
|
+
Returns
|
780
|
+
-------
|
781
|
+
dict
|
782
|
+
Dictionary of shortcut sequences and QShortcut objects
|
783
|
+
|
784
|
+
Examples
|
785
|
+
--------
|
786
|
+
```python
|
787
|
+
app = Pyloid(app_name="Pyloid-App")
|
788
|
+
|
789
|
+
window = app.create_window("pyloid-window")
|
790
|
+
shortcuts = window.get_all_shortcuts()
|
791
|
+
print(shortcuts)
|
792
|
+
|
793
|
+
app.run()
|
794
|
+
```
|
795
|
+
"""
|
796
|
+
return self.shortcuts
|
797
|
+
|
798
|
+
###########################################################################################
|
799
|
+
# Event (Calling the JS from Python)
|
800
|
+
###########################################################################################
|
801
|
+
def emit(self, event_name, data: Optional[Dict] = None):
|
802
|
+
"""
|
803
|
+
Emits an event to the JavaScript side.
|
804
|
+
|
805
|
+
Parameters
|
806
|
+
----------
|
807
|
+
event_name : str
|
808
|
+
Name of the event
|
809
|
+
data : dict, optional
|
810
|
+
Data to be sent with the event (default is None)
|
811
|
+
|
812
|
+
Examples
|
813
|
+
--------
|
814
|
+
(Python)
|
815
|
+
```python
|
816
|
+
app = Pyloid(app_name="Pyloid-App")
|
817
|
+
|
818
|
+
window = app.create_window("pyloid-window")
|
819
|
+
window.emit("customEvent", {"message": "Hello, Pyloid!"})
|
820
|
+
|
821
|
+
app.run()
|
822
|
+
```
|
823
|
+
---
|
824
|
+
|
825
|
+
(JavaScript)
|
826
|
+
```javascript
|
827
|
+
document.addEventListener('customEvent', (data) => {
|
828
|
+
console.log(data.message);
|
829
|
+
});
|
830
|
+
```
|
831
|
+
"""
|
832
|
+
script = f"""
|
833
|
+
(function() {{
|
834
|
+
const eventData = {json.dumps(data)};
|
835
|
+
const customEvent = new CustomEvent('{event_name}', {{ detail: eventData }});
|
836
|
+
document.dispatchEvent(customEvent);
|
837
|
+
}})();
|
838
|
+
"""
|
839
|
+
self.web_view.page().runJavaScript(script)
|
840
|
+
|
841
|
+
###########################################################################################
|
842
|
+
# Get Properties
|
843
|
+
###########################################################################################
|
844
|
+
def get_window_properties(self):
|
845
|
+
"""
|
846
|
+
Returns the properties of the window.
|
847
|
+
|
848
|
+
Returns
|
849
|
+
-------
|
850
|
+
dict
|
851
|
+
Dictionary containing the properties of the window
|
852
|
+
|
853
|
+
Examples
|
854
|
+
--------
|
855
|
+
```python
|
856
|
+
app = Pyloid(app_name="Pyloid-App")
|
857
|
+
|
858
|
+
window = app.create_window("pyloid-window")
|
859
|
+
properties = window.get_window_properties()
|
860
|
+
print(properties)
|
861
|
+
|
862
|
+
app.run()
|
863
|
+
```
|
864
|
+
"""
|
865
|
+
return {
|
866
|
+
"id": self.id,
|
867
|
+
"title": self.title,
|
868
|
+
"width": self.width,
|
869
|
+
"height": self.height,
|
870
|
+
"x": self.x,
|
871
|
+
"y": self.y,
|
872
|
+
"frame": self.frame,
|
873
|
+
"context_menu": self.context_menu,
|
874
|
+
"dev_tools": self.dev_tools,
|
875
|
+
}
|
876
|
+
|
877
|
+
def get_id(self):
|
878
|
+
"""
|
879
|
+
Returns the ID of the window.
|
880
|
+
|
881
|
+
Returns
|
882
|
+
-------
|
883
|
+
str
|
884
|
+
ID of the window
|
885
|
+
|
886
|
+
Examples
|
887
|
+
--------
|
888
|
+
```python
|
889
|
+
app = Pyloid(app_name="Pyloid-App")
|
890
|
+
|
891
|
+
window = app.create_window("pyloid-window")
|
892
|
+
window_id = window.get_id()
|
893
|
+
print(window_id)
|
894
|
+
|
895
|
+
app.run()
|
896
|
+
```
|
897
|
+
"""
|
898
|
+
return self.id
|
899
|
+
|
900
|
+
def get_size(self) -> Dict[str, int]:
|
901
|
+
"""
|
902
|
+
Returns the size of the window.
|
903
|
+
|
904
|
+
Returns
|
905
|
+
-------
|
906
|
+
dict
|
907
|
+
Dictionary containing the width and height of the window
|
908
|
+
|
909
|
+
Examples
|
910
|
+
--------
|
911
|
+
```python
|
912
|
+
app = Pyloid(app_name="Pyloid-App")
|
913
|
+
|
914
|
+
window = app.create_window("pyloid-window")
|
915
|
+
size = window.get_size()
|
916
|
+
print(size)
|
917
|
+
|
918
|
+
app.run()
|
919
|
+
```
|
920
|
+
"""
|
921
|
+
return {"width": self.width, "height": self.height}
|
922
|
+
|
923
|
+
def get_position(self) -> Dict[str, int]:
|
924
|
+
"""
|
925
|
+
Returns the position of the window.
|
926
|
+
|
927
|
+
Returns
|
928
|
+
-------
|
929
|
+
dict
|
930
|
+
Dictionary containing the x and y coordinates of the window
|
931
|
+
|
932
|
+
Examples
|
933
|
+
--------
|
934
|
+
```python
|
935
|
+
app = Pyloid(app_name="Pyloid-App")
|
936
|
+
|
937
|
+
window = app.create_window("pyloid-window")
|
938
|
+
position = window.get_position()
|
939
|
+
print(position)
|
940
|
+
|
941
|
+
app.run()
|
942
|
+
```
|
943
|
+
"""
|
944
|
+
return {"x": self.x, "y": self.y}
|
945
|
+
|
946
|
+
def get_title(self) -> str:
|
947
|
+
"""
|
948
|
+
Returns the title of the window.
|
949
|
+
|
950
|
+
Returns
|
951
|
+
-------
|
952
|
+
str
|
953
|
+
Title of the window
|
954
|
+
|
955
|
+
Examples
|
956
|
+
--------
|
957
|
+
```python
|
958
|
+
app = Pyloid(app_name="Pyloid-App")
|
959
|
+
|
960
|
+
window = app.create_window("pyloid-window")
|
961
|
+
title = window.get_title()
|
962
|
+
print(title)
|
963
|
+
|
964
|
+
app.run()
|
965
|
+
```
|
966
|
+
"""
|
967
|
+
return self.title
|
968
|
+
|
969
|
+
def get_url(self) -> str:
|
970
|
+
"""
|
971
|
+
Returns the URL of the window.
|
972
|
+
|
973
|
+
Returns
|
974
|
+
-------
|
975
|
+
str
|
976
|
+
URL of the window
|
977
|
+
|
978
|
+
Examples
|
979
|
+
--------
|
980
|
+
```python
|
981
|
+
app = Pyloid(app_name="Pyloid-App")
|
982
|
+
|
983
|
+
window = app.create_window("pyloid-window")
|
984
|
+
url = window.get_url()
|
985
|
+
print(url)
|
986
|
+
|
987
|
+
app.run()
|
988
|
+
```
|
989
|
+
"""
|
990
|
+
return self.web_view.url().toString()
|
991
|
+
|
992
|
+
def get_visible(self) -> bool:
|
993
|
+
"""
|
994
|
+
Returns the visibility of the window.
|
995
|
+
|
996
|
+
Returns
|
997
|
+
-------
|
998
|
+
bool
|
999
|
+
True if the window is visible, False otherwise
|
1000
|
+
|
1001
|
+
Examples
|
1002
|
+
--------
|
1003
|
+
```python
|
1004
|
+
app = Pyloid(app_name="Pyloid-App")
|
1005
|
+
|
1006
|
+
window = app.create_window("pyloid-window")
|
1007
|
+
visible = window.get_visible()
|
1008
|
+
print(visible)
|
1009
|
+
|
1010
|
+
app.run()
|
1011
|
+
```
|
1012
|
+
"""
|
1013
|
+
return self._window.isVisible()
|
1014
|
+
|
1015
|
+
def get_frame(self) -> bool:
|
1016
|
+
"""
|
1017
|
+
Returns the frame enabled state of the window.
|
1018
|
+
|
1019
|
+
Returns
|
1020
|
+
-------
|
1021
|
+
bool
|
1022
|
+
True if the frame is enabled, False otherwise
|
1023
|
+
|
1024
|
+
Examples
|
1025
|
+
--------
|
1026
|
+
```python
|
1027
|
+
app = Pyloid(app_name="Pyloid-App")
|
1028
|
+
|
1029
|
+
window = app.create_window("pyloid-window")
|
1030
|
+
frame = window.get_frame()
|
1031
|
+
print(frame)
|
1032
|
+
|
1033
|
+
app.run()
|
1034
|
+
```
|
1035
|
+
"""
|
1036
|
+
return self.frame
|
1037
|
+
|
1038
|
+
###########################################################################################
|
1039
|
+
# Resize
|
1040
|
+
###########################################################################################
|
1041
|
+
def set_resizable(self, resizable: bool):
|
1042
|
+
"""
|
1043
|
+
Sets the resizability of the window.
|
1044
|
+
|
1045
|
+
Parameters
|
1046
|
+
----------
|
1047
|
+
resizable : bool
|
1048
|
+
True to make the window resizable, False to make it fixed size
|
1049
|
+
|
1050
|
+
Examples
|
1051
|
+
--------
|
1052
|
+
```python
|
1053
|
+
app = Pyloid(app_name="Pyloid-App")
|
1054
|
+
|
1055
|
+
window = app.create_window("pyloid-window")
|
1056
|
+
window.set_resizable(True)
|
1057
|
+
|
1058
|
+
app.run()
|
1059
|
+
```
|
1060
|
+
"""
|
1061
|
+
self.resizable = resizable
|
1062
|
+
if self.frame:
|
1063
|
+
flags = self._window.windowFlags() | Qt.WindowCloseButtonHint
|
1064
|
+
if resizable:
|
1065
|
+
pass
|
1066
|
+
else:
|
1067
|
+
flags |= Qt.MSWindowsFixedSizeDialogHint
|
1068
|
+
self._window.setWindowFlags(flags)
|
1069
|
+
else:
|
1070
|
+
# 프레임이 없는 경우 커스텀 리사이징 로직을 설정합니다.
|
1071
|
+
self.web_view.is_resizing_enabled = resizable
|
1072
|
+
|
1073
|
+
self._window.show() # 변경사항을 적용하기 위해 창을 다시 표시합니다.
|
1074
|
+
|
1075
|
+
def set_minimum_size(self, min_width: int, min_height: int):
|
1076
|
+
"""
|
1077
|
+
Sets the minimum size of the window.
|
1078
|
+
|
1079
|
+
Parameters
|
1080
|
+
----------
|
1081
|
+
min_width : int
|
1082
|
+
Minimum width of the window
|
1083
|
+
min_height : int
|
1084
|
+
Minimum height of the window
|
1085
|
+
|
1086
|
+
Examples
|
1087
|
+
--------
|
1088
|
+
```python
|
1089
|
+
app = Pyloid(app_name="Pyloid-App")
|
1090
|
+
|
1091
|
+
window = app.create_window("pyloid-window")
|
1092
|
+
window.set_minimum_size(400, 300)
|
1093
|
+
|
1094
|
+
app.run()
|
1095
|
+
```
|
1096
|
+
"""
|
1097
|
+
self._window.setMinimumSize(min_width, min_height)
|
1098
|
+
|
1099
|
+
def set_maximum_size(self, max_width: int, max_height: int):
|
1100
|
+
"""
|
1101
|
+
Sets the maximum size of the window.
|
1102
|
+
|
1103
|
+
Parameters
|
1104
|
+
----------
|
1105
|
+
max_width : int
|
1106
|
+
Maximum width of the window
|
1107
|
+
max_height : int
|
1108
|
+
Maximum height of the window
|
1109
|
+
|
1110
|
+
Examples
|
1111
|
+
--------
|
1112
|
+
```python
|
1113
|
+
app = Pyloid(app_name="Pyloid-App")
|
1114
|
+
|
1115
|
+
window = app.create_window("pyloid-window")
|
1116
|
+
window.set_maximum_size(1024, 768)
|
1117
|
+
|
1118
|
+
app.run()
|
1119
|
+
```
|
1120
|
+
"""
|
1121
|
+
self._window.setMaximumSize(max_width, max_height)
|
1122
|
+
|
1123
|
+
def get_minimum_size(self) -> Dict[str, int]:
|
1124
|
+
"""
|
1125
|
+
Returns the minimum size of the window.
|
1126
|
+
|
1127
|
+
Returns
|
1128
|
+
-------
|
1129
|
+
dict
|
1130
|
+
Dictionary containing the minimum width and height of the window
|
1131
|
+
|
1132
|
+
Examples
|
1133
|
+
--------
|
1134
|
+
```python
|
1135
|
+
app = Pyloid(app_name="Pyloid-App")
|
1136
|
+
|
1137
|
+
window = app.create_window("pyloid-window")
|
1138
|
+
min_size = window.get_minimum_size()
|
1139
|
+
print(min_size)
|
1140
|
+
|
1141
|
+
app.run()
|
1142
|
+
```
|
1143
|
+
"""
|
1144
|
+
return {'width': self._window.minimumWidth(), 'height': self._window.minimumHeight()}
|
1145
|
+
|
1146
|
+
def get_maximum_size(self) -> Dict[str, int]:
|
1147
|
+
"""
|
1148
|
+
Returns the maximum size of the window.
|
1149
|
+
|
1150
|
+
Returns
|
1151
|
+
-------
|
1152
|
+
dict
|
1153
|
+
Dictionary containing the maximum width and height of the window
|
1154
|
+
|
1155
|
+
Examples
|
1156
|
+
--------
|
1157
|
+
```python
|
1158
|
+
app = Pyloid(app_name="Pyloid-App")
|
1159
|
+
|
1160
|
+
window = app.create_window("pyloid-window")
|
1161
|
+
max_size = window.get_maximum_size()
|
1162
|
+
print(max_size)
|
1163
|
+
|
1164
|
+
app.run()
|
1165
|
+
```
|
1166
|
+
"""
|
1167
|
+
return {'width': self._window.maximumWidth(), 'height': self._window.maximumHeight()}
|
1168
|
+
|
1169
|
+
def get_resizable(self) -> bool:
|
1170
|
+
"""
|
1171
|
+
Returns the resizability of the window.
|
1172
|
+
|
1173
|
+
Returns
|
1174
|
+
-------
|
1175
|
+
bool
|
1176
|
+
True if the window is resizable, False otherwise
|
1177
|
+
|
1178
|
+
Examples
|
1179
|
+
--------
|
1180
|
+
```python
|
1181
|
+
app = Pyloid(app_name="Pyloid-App")
|
1182
|
+
|
1183
|
+
window = app.create_window("pyloid-window")
|
1184
|
+
resizable = window.get_resizable()
|
1185
|
+
print(resizable)
|
1186
|
+
|
1187
|
+
app.run()
|
1188
|
+
```
|
1189
|
+
"""
|
1190
|
+
return self.resizable
|