pyloid 0.16.12__py3-none-any.whl → 0.17.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/browser_window.py +60 -5
- pyloid/js_api/window_api.py +9 -0
- pyloid/pyloid.py +10 -1
- pyloid/thread_pool.py +501 -0
- {pyloid-0.16.12.dist-info → pyloid-0.17.0.dist-info}/METADATA +2 -3
- {pyloid-0.16.12.dist-info → pyloid-0.17.0.dist-info}/RECORD +8 -7
- {pyloid-0.16.12.dist-info → pyloid-0.17.0.dist-info}/LICENSE +0 -0
- {pyloid-0.16.12.dist-info → pyloid-0.17.0.dist-info}/WHEEL +0 -0
pyloid/browser_window.py
CHANGED
@@ -36,26 +36,36 @@ if TYPE_CHECKING:
|
|
36
36
|
class CustomWebPage(QWebEnginePage):
|
37
37
|
def __init__(self, profile=None):
|
38
38
|
super().__init__(profile)
|
39
|
-
# 권한 요청 시그널 연결
|
40
39
|
self.featurePermissionRequested.connect(self._handlePermissionRequest)
|
40
|
+
self.desktopMediaRequested.connect(self._handleDesktopMediaRequest)
|
41
41
|
self._permission_handlers = {}
|
42
|
+
self._desktop_media_handler = None
|
42
43
|
|
43
44
|
def _handlePermissionRequest(self, origin: QUrl, feature: QWebEnginePage.Feature):
|
44
|
-
|
45
|
+
print(origin, feature)
|
46
|
+
|
47
|
+
"""Default permission request handler"""
|
45
48
|
if feature in self._permission_handlers:
|
46
|
-
#
|
49
|
+
# Execute if a handler is registered
|
47
50
|
handler = self._permission_handlers[feature]
|
48
51
|
handler(origin, feature)
|
49
52
|
else:
|
50
|
-
#
|
53
|
+
# Allow all permissions by default
|
51
54
|
self.setFeaturePermission(
|
52
55
|
origin, feature, QWebEnginePage.PermissionPolicy.PermissionGrantedByUser
|
53
56
|
)
|
54
57
|
|
55
58
|
def setPermissionHandler(self, feature: QWebEnginePage.Feature, handler):
|
56
|
-
"""
|
59
|
+
"""Register a handler for a specific permission"""
|
57
60
|
self._permission_handlers[feature] = handler
|
58
61
|
|
62
|
+
def _handleDesktopMediaRequest(self, *args, **kwargs):
|
63
|
+
print("Desktop media request received:", args, kwargs)
|
64
|
+
|
65
|
+
# def setDesktopMediaHandler(self, handler):
|
66
|
+
# """desktop media handler"""
|
67
|
+
# self._desktop_media_handler = handler
|
68
|
+
|
59
69
|
|
60
70
|
class CustomWebEngineView(QWebEngineView):
|
61
71
|
def __init__(self, parent: "BrowserWindow" = None):
|
@@ -291,6 +301,21 @@ class BrowserWindow:
|
|
291
301
|
self.web_view.settings().setUnknownUrlSchemePolicy(
|
292
302
|
QWebEngineSettings.UnknownUrlSchemePolicy.AllowAllUnknownUrlSchemes
|
293
303
|
)
|
304
|
+
self.web_view.settings().setAttribute(
|
305
|
+
QWebEngineSettings.WebAttribute.AllowRunningInsecureContent, True
|
306
|
+
)
|
307
|
+
self.web_view.settings().setAttribute(
|
308
|
+
QWebEngineSettings.WebAttribute.AllowGeolocationOnInsecureOrigins, True
|
309
|
+
)
|
310
|
+
self.web_view.settings().setAttribute(
|
311
|
+
QWebEngineSettings.WebAttribute.AllowWindowActivationFromJavaScript, True
|
312
|
+
)
|
313
|
+
self.web_view.settings().setAttribute(
|
314
|
+
QWebEngineSettings.WebAttribute.JavascriptCanPaste, True
|
315
|
+
)
|
316
|
+
self.web_view.settings().setAttribute(
|
317
|
+
QWebEngineSettings.WebAttribute.WebRTCPublicInterfacesOnly, False
|
318
|
+
)
|
294
319
|
|
295
320
|
# Set icon
|
296
321
|
if self.app.icon:
|
@@ -1805,3 +1830,33 @@ class BrowserWindow:
|
|
1805
1830
|
)
|
1806
1831
|
|
1807
1832
|
self.set_permission_handler(feature, auto_deny)
|
1833
|
+
|
1834
|
+
def set_desktop_media_handler(self, handler):
|
1835
|
+
"""
|
1836
|
+
데스크톱 미디어(화면/윈도우) 선택 핸들러를 설정합니다.
|
1837
|
+
|
1838
|
+
Parameters
|
1839
|
+
----------
|
1840
|
+
handler : callable
|
1841
|
+
요청을 처리할 핸들러 함수. QWebEngineDesktopMediaRequest를 인자로 받습니다.
|
1842
|
+
|
1843
|
+
Examples
|
1844
|
+
--------
|
1845
|
+
```python
|
1846
|
+
def custom_media_handler(request):
|
1847
|
+
# 사용 가능한 화면 목록 출력
|
1848
|
+
for screen in request.screenList():
|
1849
|
+
print(f"Screen: {screen.name}")
|
1850
|
+
|
1851
|
+
# 사용 가능한 윈도우 목록 출력
|
1852
|
+
for window in request.windowList():
|
1853
|
+
print(f"Window: {window.name}")
|
1854
|
+
|
1855
|
+
# 첫 번째 화면 선택
|
1856
|
+
if request.screenList():
|
1857
|
+
request.selectScreen(request.screenList()[0])
|
1858
|
+
|
1859
|
+
window.set_desktop_media_handler(custom_media_handler)
|
1860
|
+
```
|
1861
|
+
"""
|
1862
|
+
self.web_view.custom_page.setDesktopMediaHandler(handler)
|
pyloid/js_api/window_api.py
CHANGED
@@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Optional
|
|
2
2
|
|
3
3
|
from ..api import PyloidAPI, Bridge
|
4
4
|
from PySide6.QtCore import QByteArray, QBuffer, QIODeviceBase
|
5
|
+
import base64
|
5
6
|
|
6
7
|
if TYPE_CHECKING:
|
7
8
|
from ..pyloid import Pyloid
|
@@ -244,3 +245,11 @@ class WindowAPI(PyloidAPI):
|
|
244
245
|
base64_data = byte_array.toBase64().data().decode()
|
245
246
|
return f"data:image/png;base64,{base64_data}"
|
246
247
|
return ""
|
248
|
+
|
249
|
+
###########################################################################################
|
250
|
+
# Quit
|
251
|
+
###########################################################################################
|
252
|
+
@Bridge()
|
253
|
+
def quit(self):
|
254
|
+
"""Quits the application."""
|
255
|
+
self.app.quit()
|
pyloid/pyloid.py
CHANGED
@@ -26,6 +26,9 @@ import logging
|
|
26
26
|
from .browser_window import BrowserWindow
|
27
27
|
from .tray import TrayEvent
|
28
28
|
from PySide6.QtCore import QCoreApplication
|
29
|
+
from PySide6.QtCore import QRunnable, QThreadPool, Signal, QObject
|
30
|
+
import time
|
31
|
+
from .thread_pool import PyloidThreadPool
|
29
32
|
|
30
33
|
# for linux debug
|
31
34
|
os.environ["QTWEBENGINE_DICTIONARIES_PATH"] = "/"
|
@@ -431,10 +434,16 @@ class Pyloid(QApplication):
|
|
431
434
|
app.quit()
|
432
435
|
```
|
433
436
|
"""
|
437
|
+
# 먼저 스레드 풀 정리
|
438
|
+
thread_pool = self.get_thread_pool()
|
439
|
+
thread_pool.clear() # 대기 중인 작업 제거
|
440
|
+
|
441
|
+
# 윈도우 정리
|
434
442
|
for window in self.windows:
|
435
443
|
window._window.close()
|
436
444
|
window.web_page.deleteLater()
|
437
445
|
window.web_view.deleteLater()
|
446
|
+
|
438
447
|
QApplication.quit()
|
439
448
|
|
440
449
|
###########################################################################################
|
@@ -1395,4 +1404,4 @@ class Pyloid(QApplication):
|
|
1395
1404
|
window.web_view.page().runJavaScript(js_code)
|
1396
1405
|
window.web_view.page().setBackgroundColor(
|
1397
1406
|
Qt.GlobalColor.black if self.theme == "dark" else Qt.GlobalColor.white
|
1398
|
-
)
|
1407
|
+
)
|
pyloid/thread_pool.py
ADDED
@@ -0,0 +1,501 @@
|
|
1
|
+
from PySide6.QtCore import QRunnable, QThreadPool, QDeadlineTimer, QObject, Signal
|
2
|
+
from typing import Callable, Optional, Union
|
3
|
+
|
4
|
+
class PyloidRunnable(QRunnable):
|
5
|
+
"""
|
6
|
+
A runnable task class that extends QRunnable from Qt.
|
7
|
+
|
8
|
+
Defines a unit of work that can be executed in a thread pool.
|
9
|
+
"""
|
10
|
+
|
11
|
+
def __init__(self):
|
12
|
+
"""
|
13
|
+
Initializes a PyloidRunnable instance.
|
14
|
+
|
15
|
+
By default, auto-delete is enabled.
|
16
|
+
"""
|
17
|
+
super().__init__()
|
18
|
+
self.setAutoDelete(True)
|
19
|
+
|
20
|
+
def get_auto_delete(self) -> bool:
|
21
|
+
"""
|
22
|
+
Returns whether the task is automatically deleted after completion in the thread pool.
|
23
|
+
|
24
|
+
The default value is True.
|
25
|
+
|
26
|
+
Returns
|
27
|
+
-------
|
28
|
+
bool
|
29
|
+
True if the task is automatically deleted after completion, False if manual deletion is required
|
30
|
+
|
31
|
+
Examples
|
32
|
+
--------
|
33
|
+
```python
|
34
|
+
from pyloid.thread_pool import PyloidRunnable
|
35
|
+
import time
|
36
|
+
|
37
|
+
class Worker(PyloidRunnable):
|
38
|
+
def run(self):
|
39
|
+
time.sleep(1)
|
40
|
+
print("Task executed")
|
41
|
+
|
42
|
+
worker = Worker()
|
43
|
+
print(worker.get_auto_delete())
|
44
|
+
```
|
45
|
+
"""
|
46
|
+
return self.autoDelete()
|
47
|
+
|
48
|
+
def set_auto_delete(self, value: bool) -> None:
|
49
|
+
"""
|
50
|
+
Sets whether the task is automatically deleted after completion in the thread pool.
|
51
|
+
|
52
|
+
Parameters
|
53
|
+
----------
|
54
|
+
value : bool
|
55
|
+
True to enable auto-delete after task completion,
|
56
|
+
False to require manual deletion
|
57
|
+
|
58
|
+
Examples
|
59
|
+
--------
|
60
|
+
```python
|
61
|
+
from pyloid.thread_pool import PyloidRunnable
|
62
|
+
import time
|
63
|
+
|
64
|
+
class Worker(PyloidRunnable):
|
65
|
+
def run(self):
|
66
|
+
time.sleep(1)
|
67
|
+
print("Task executed")
|
68
|
+
|
69
|
+
worker = Worker()
|
70
|
+
worker.set_auto_delete(False)
|
71
|
+
```
|
72
|
+
"""
|
73
|
+
self.setAutoDelete(value)
|
74
|
+
|
75
|
+
def run(self) -> None:
|
76
|
+
"""
|
77
|
+
Defines the actual work to be executed in the thread pool.
|
78
|
+
|
79
|
+
This method must be implemented in subclasses.
|
80
|
+
|
81
|
+
Examples
|
82
|
+
--------
|
83
|
+
```python
|
84
|
+
from pyloid.thread_pool import PyloidRunnable, PyloidThreadPool
|
85
|
+
import time
|
86
|
+
|
87
|
+
class Worker(PyloidRunnable):
|
88
|
+
def run(self):
|
89
|
+
time.sleep(1)
|
90
|
+
print("Task executed")
|
91
|
+
|
92
|
+
worker = Worker()
|
93
|
+
thread_pool = PyloidThreadPool()
|
94
|
+
thread_pool.start(worker)
|
95
|
+
```
|
96
|
+
"""
|
97
|
+
pass
|
98
|
+
|
99
|
+
class PyloidDefaultSignals(QObject):
|
100
|
+
"""
|
101
|
+
Default signal class.
|
102
|
+
|
103
|
+
Defines signals used for task start, completion, and error occurrence in the thread pool.
|
104
|
+
|
105
|
+
Attributes
|
106
|
+
----------
|
107
|
+
started : Signal
|
108
|
+
Signal emitted when a task starts
|
109
|
+
finished : Signal
|
110
|
+
Signal emitted when a task completes
|
111
|
+
error : Signal(str)
|
112
|
+
Signal emitted when an error occurs
|
113
|
+
progress : Signal(int)
|
114
|
+
Signal emitted when progress changes
|
115
|
+
|
116
|
+
Examples
|
117
|
+
--------
|
118
|
+
```python
|
119
|
+
from pyloid.thread_pool import PyloidRunnable, PyloidThreadPool, PyloidDefaultSignals
|
120
|
+
import time
|
121
|
+
|
122
|
+
class Worker(PyloidRunnable):
|
123
|
+
def __init__(self):
|
124
|
+
super().__init__()
|
125
|
+
self.signals = PyloidDefaultSignals()
|
126
|
+
|
127
|
+
def run(self):
|
128
|
+
for i in range(101):
|
129
|
+
self.signals.progress.emit(i)
|
130
|
+
time.sleep(0.1)
|
131
|
+
|
132
|
+
worker = Worker()
|
133
|
+
|
134
|
+
worker.signals.finished.connect(lambda: print("Task completed."))
|
135
|
+
worker.signals.error.connect(lambda error: print(f"Error occurred: {error}"))
|
136
|
+
worker.signals.progress.connect(lambda progress: print(f"Progress: {progress}%"))
|
137
|
+
|
138
|
+
thread_pool = PyloidThreadPool()
|
139
|
+
thread_pool.start(worker)
|
140
|
+
```
|
141
|
+
"""
|
142
|
+
started = Signal()
|
143
|
+
finished = Signal()
|
144
|
+
error = Signal(str)
|
145
|
+
progress = Signal(int)
|
146
|
+
|
147
|
+
|
148
|
+
class PyloidThreadPool:
|
149
|
+
def __init__(self):
|
150
|
+
self.thread_pool = QThreadPool.globalInstance()
|
151
|
+
|
152
|
+
def start(self, runnable: Union[PyloidRunnable, Callable], priority: int = ...) -> None:
|
153
|
+
"""
|
154
|
+
Adds a task to the thread pool and executes it.
|
155
|
+
|
156
|
+
Parameters
|
157
|
+
----------
|
158
|
+
runnable : Union[PyloidRunnable, Callable]
|
159
|
+
Task to be executed
|
160
|
+
priority : int
|
161
|
+
Task priority
|
162
|
+
|
163
|
+
Examples
|
164
|
+
--------
|
165
|
+
```python
|
166
|
+
from pyloid.thread_pool import PyloidRunnable, PyloidThreadPool
|
167
|
+
import time
|
168
|
+
|
169
|
+
class Worker(PyloidRunnable):
|
170
|
+
def run(self):
|
171
|
+
time.sleep(1)
|
172
|
+
print("Task executed")
|
173
|
+
|
174
|
+
worker = Worker()
|
175
|
+
thread_pool = PyloidThreadPool()
|
176
|
+
thread_pool.start(worker)
|
177
|
+
```
|
178
|
+
"""
|
179
|
+
self.thread_pool.start(runnable, priority)
|
180
|
+
|
181
|
+
def active_thread_count(self) -> int:
|
182
|
+
"""
|
183
|
+
Returns the number of currently active threads.
|
184
|
+
|
185
|
+
Returns
|
186
|
+
-------
|
187
|
+
int
|
188
|
+
Number of currently active threads
|
189
|
+
|
190
|
+
Examples
|
191
|
+
--------
|
192
|
+
```python
|
193
|
+
from pyloid.thread_pool import PyloidThreadPool
|
194
|
+
|
195
|
+
thread_pool = PyloidThreadPool()
|
196
|
+
print(thread_pool.active_thread_count())
|
197
|
+
```
|
198
|
+
"""
|
199
|
+
return self.thread_pool.activeThreadCount()
|
200
|
+
|
201
|
+
def max_thread_count(self) -> int:
|
202
|
+
"""
|
203
|
+
Returns the maximum number of threads that can run simultaneously in the thread pool.
|
204
|
+
|
205
|
+
Returns
|
206
|
+
-------
|
207
|
+
int
|
208
|
+
Maximum number of threads
|
209
|
+
|
210
|
+
Examples
|
211
|
+
--------
|
212
|
+
```python
|
213
|
+
from pyloid.thread_pool import PyloidThreadPool
|
214
|
+
|
215
|
+
thread_pool = PyloidThreadPool()
|
216
|
+
print(thread_pool.max_thread_count())
|
217
|
+
```
|
218
|
+
"""
|
219
|
+
return self.thread_pool.maxThreadCount()
|
220
|
+
|
221
|
+
def set_max_thread_count(self, max_thread_count: int) -> None:
|
222
|
+
"""
|
223
|
+
Sets the maximum number of threads that can run simultaneously in the thread pool.
|
224
|
+
|
225
|
+
Parameters
|
226
|
+
----------
|
227
|
+
max_thread_count : int
|
228
|
+
Maximum number of threads
|
229
|
+
|
230
|
+
Examples
|
231
|
+
--------
|
232
|
+
```python
|
233
|
+
from pyloid.thread_pool import PyloidThreadPool
|
234
|
+
|
235
|
+
thread_pool = PyloidThreadPool()
|
236
|
+
thread_pool.set_max_thread_count(10)
|
237
|
+
```
|
238
|
+
"""
|
239
|
+
self.thread_pool.setMaxThreadCount(max_thread_count)
|
240
|
+
|
241
|
+
def reserve_thread(self) -> None:
|
242
|
+
"""
|
243
|
+
Reserves a thread in the thread pool.
|
244
|
+
|
245
|
+
Examples
|
246
|
+
--------
|
247
|
+
```python
|
248
|
+
from pyloid.thread_pool import PyloidThreadPool, PyloidRunnable
|
249
|
+
import time
|
250
|
+
|
251
|
+
class Worker(PyloidRunnable):
|
252
|
+
def run(self):
|
253
|
+
time.sleep(1)
|
254
|
+
print("Task executed on reserved thread")
|
255
|
+
|
256
|
+
# Create thread pool
|
257
|
+
thread_pool = PyloidThreadPool()
|
258
|
+
|
259
|
+
# Reserve thread
|
260
|
+
thread_pool.reserve_thread()
|
261
|
+
|
262
|
+
try:
|
263
|
+
# Execute task on reserved thread
|
264
|
+
worker = Worker()
|
265
|
+
thread_pool.start_on_reserved_thread(worker)
|
266
|
+
|
267
|
+
# Wait for task completion
|
268
|
+
thread_pool.wait_for_done()
|
269
|
+
finally:
|
270
|
+
# Important: Reserved threads must be released
|
271
|
+
thread_pool.release_thread()
|
272
|
+
```
|
273
|
+
"""
|
274
|
+
self.thread_pool.reserveThread()
|
275
|
+
|
276
|
+
def release_thread(self) -> None:
|
277
|
+
"""
|
278
|
+
Releases a reserved thread in the thread pool.
|
279
|
+
|
280
|
+
Examples
|
281
|
+
--------
|
282
|
+
```python
|
283
|
+
from pyloid.thread_pool import PyloidThreadPool
|
284
|
+
|
285
|
+
thread_pool = PyloidThreadPool()
|
286
|
+
thread_pool.release_thread()
|
287
|
+
```
|
288
|
+
"""
|
289
|
+
self.thread_pool.releaseThread()
|
290
|
+
|
291
|
+
def clear(self) -> None:
|
292
|
+
"""
|
293
|
+
Removes all pending tasks from the thread pool.
|
294
|
+
|
295
|
+
Examples
|
296
|
+
--------
|
297
|
+
```python
|
298
|
+
from pyloid.thread_pool import PyloidThreadPool
|
299
|
+
|
300
|
+
thread_pool = PyloidThreadPool()
|
301
|
+
thread_pool.clear()
|
302
|
+
```
|
303
|
+
"""
|
304
|
+
self.thread_pool.clear()
|
305
|
+
|
306
|
+
# def contains(self, thread: QThread) -> bool:
|
307
|
+
# return self.thread_pool.contains(thread)
|
308
|
+
|
309
|
+
def get_expiry_timeout(self) -> int:
|
310
|
+
"""
|
311
|
+
Returns the thread expiry timeout in the thread pool.
|
312
|
+
|
313
|
+
Returns
|
314
|
+
-------
|
315
|
+
int
|
316
|
+
Thread expiry timeout
|
317
|
+
|
318
|
+
Examples
|
319
|
+
--------
|
320
|
+
```python
|
321
|
+
from pyloid.thread_pool import PyloidThreadPool
|
322
|
+
|
323
|
+
thread_pool = PyloidThreadPool()
|
324
|
+
print(thread_pool.get_expiry_timeout())
|
325
|
+
```
|
326
|
+
"""
|
327
|
+
return self.thread_pool.expiryTimeout()
|
328
|
+
|
329
|
+
def set_expiry_timeout(self, expiry_timeout: int) -> None:
|
330
|
+
"""
|
331
|
+
Sets the thread expiry timeout in the thread pool.
|
332
|
+
|
333
|
+
Parameters
|
334
|
+
----------
|
335
|
+
expiry_timeout : int
|
336
|
+
Thread expiry timeout
|
337
|
+
|
338
|
+
Examples
|
339
|
+
--------
|
340
|
+
```python
|
341
|
+
from pyloid.thread_pool import PyloidThreadPool
|
342
|
+
|
343
|
+
thread_pool = PyloidThreadPool()
|
344
|
+
thread_pool.set_expiry_timeout(1000)
|
345
|
+
```
|
346
|
+
"""
|
347
|
+
self.thread_pool.setExpiryTimeout(expiry_timeout)
|
348
|
+
|
349
|
+
# def set_stack_size(self, stack_size: int) -> None:
|
350
|
+
# self.thread_pool.setStackSize(stack_size)
|
351
|
+
|
352
|
+
# def stack_size(self) -> int:
|
353
|
+
# return self.thread_pool.stackSize()
|
354
|
+
|
355
|
+
# def set_thread_priority(self, priority: QThread.Priority) -> None:
|
356
|
+
# self.thread_pool.setThreadPriority(priority)
|
357
|
+
|
358
|
+
# def thread_priority(self) -> QThread.Priority:
|
359
|
+
# return self.thread_pool.threadPriority()
|
360
|
+
|
361
|
+
def start_on_reserved_thread(self, runnable: QRunnable) -> None:
|
362
|
+
"""
|
363
|
+
Executes a task on a reserved thread.
|
364
|
+
|
365
|
+
Parameters
|
366
|
+
----------
|
367
|
+
runnable : QRunnable
|
368
|
+
Task to be executed
|
369
|
+
|
370
|
+
Examples
|
371
|
+
--------
|
372
|
+
```python
|
373
|
+
from pyloid.thread_pool import PyloidThreadPool, PyloidRunnable
|
374
|
+
import time
|
375
|
+
|
376
|
+
class Worker(PyloidRunnable):
|
377
|
+
def run(self):
|
378
|
+
time.sleep(1)
|
379
|
+
print("Task executed on reserved thread")
|
380
|
+
|
381
|
+
worker = Worker()
|
382
|
+
thread_pool = PyloidThreadPool()
|
383
|
+
thread_pool.reserve_thread()
|
384
|
+
thread_pool.start_on_reserved_thread(worker)
|
385
|
+
thread_pool.wait_for_done()
|
386
|
+
thread_pool.release_thread()
|
387
|
+
```
|
388
|
+
"""
|
389
|
+
self.thread_pool.startOnReservedThread(runnable)
|
390
|
+
|
391
|
+
def try_start(self, runnable: Union[QRunnable, Callable]) -> bool:
|
392
|
+
"""
|
393
|
+
Adds a new task to the thread pool and attempts to execute it immediately.
|
394
|
+
|
395
|
+
Only executes the task if the thread pool has available capacity.
|
396
|
+
Operates in a non-blocking manner and does not start the task if the thread pool is full.
|
397
|
+
|
398
|
+
Parameters
|
399
|
+
----------
|
400
|
+
runnable : Union[QRunnable, Callable]
|
401
|
+
Task to be executed
|
402
|
+
|
403
|
+
Returns
|
404
|
+
-------
|
405
|
+
bool
|
406
|
+
True: Task successfully started
|
407
|
+
False: Task could not be started because the thread pool is full
|
408
|
+
|
409
|
+
Examples
|
410
|
+
--------
|
411
|
+
```python
|
412
|
+
from pyloid.thread_pool import PyloidThreadPool, PyloidRunnable
|
413
|
+
|
414
|
+
class Worker(PyloidRunnable):
|
415
|
+
def run(self):
|
416
|
+
print("Task executed")
|
417
|
+
|
418
|
+
thread_pool = PyloidThreadPool()
|
419
|
+
worker = Worker()
|
420
|
+
|
421
|
+
if thread_pool.try_start(worker):
|
422
|
+
print("Task started")
|
423
|
+
else:
|
424
|
+
print("Task could not be started because the thread pool is full")
|
425
|
+
```
|
426
|
+
"""
|
427
|
+
return self.thread_pool.tryStart(runnable)
|
428
|
+
|
429
|
+
def try_take(self, runnable: QRunnable) -> bool:
|
430
|
+
"""
|
431
|
+
Attempts to remove a specific task from the thread pool queue.
|
432
|
+
|
433
|
+
Only removes tasks that have not yet been executed. Tasks that are already running cannot be removed.
|
434
|
+
Used when task cancellation is needed.
|
435
|
+
|
436
|
+
Parameters
|
437
|
+
----------
|
438
|
+
runnable : QRunnable
|
439
|
+
Task to be removed from the queue
|
440
|
+
|
441
|
+
Returns
|
442
|
+
-------
|
443
|
+
bool
|
444
|
+
True: Task successfully removed from the queue
|
445
|
+
False: Task could not be removed (already running or not found)
|
446
|
+
|
447
|
+
Examples
|
448
|
+
--------
|
449
|
+
```python
|
450
|
+
from pyloid.thread_pool import PyloidThreadPool, PyloidRunnable
|
451
|
+
|
452
|
+
class Worker(PyloidRunnable):
|
453
|
+
def run(self):
|
454
|
+
print("Task executed")
|
455
|
+
|
456
|
+
thread_pool = PyloidThreadPool()
|
457
|
+
worker = Worker()
|
458
|
+
|
459
|
+
# Add task
|
460
|
+
thread_pool.start(worker)
|
461
|
+
|
462
|
+
# Attempt to remove task
|
463
|
+
if thread_pool.try_take(worker):
|
464
|
+
print("Task removed from queue")
|
465
|
+
else:
|
466
|
+
print("Task could not be removed (already running or not found)")
|
467
|
+
```
|
468
|
+
"""
|
469
|
+
return self.thread_pool.tryTake(runnable)
|
470
|
+
|
471
|
+
def wait_for_done(self, timeout: Optional[int] = None) -> bool:
|
472
|
+
"""
|
473
|
+
Waits for tasks to complete.
|
474
|
+
|
475
|
+
If no timeout is specified, waits indefinitely until completion.
|
476
|
+
|
477
|
+
Parameters
|
478
|
+
----------
|
479
|
+
timeout : Optional[int]
|
480
|
+
Wait time
|
481
|
+
|
482
|
+
Returns
|
483
|
+
-------
|
484
|
+
bool
|
485
|
+
True if tasks completed, False otherwise
|
486
|
+
|
487
|
+
Examples
|
488
|
+
--------
|
489
|
+
```python
|
490
|
+
from pyloid.thread_pool import PyloidThreadPool
|
491
|
+
|
492
|
+
thread_pool = PyloidThreadPool()
|
493
|
+
thread_pool.wait_for_done()
|
494
|
+
|
495
|
+
print("Tasks completed.")
|
496
|
+
```
|
497
|
+
"""
|
498
|
+
if timeout is None:
|
499
|
+
return self.thread_pool.waitForDone(-1)
|
500
|
+
else:
|
501
|
+
return self.thread_pool.waitForDone(timeout)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyloid
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.17.0
|
4
4
|
Summary:
|
5
5
|
Author: aesthetics-of-record
|
6
6
|
Author-email: 111675679+aesthetics-of-record@users.noreply.github.com
|
@@ -10,8 +10,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.10
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
13
|
-
Requires-Dist:
|
14
|
-
Requires-Dist: pyside6 (>=6.7.3,<7.0.0)
|
13
|
+
Requires-Dist: pyside6 (>=6.8.0.2,<7.0.0.0)
|
15
14
|
Description-Content-Type: text/markdown
|
16
15
|
|
17
16
|
# Pyloid 👋
|
@@ -1,17 +1,18 @@
|
|
1
1
|
pyloid/__init__.py,sha256=OOPhOKNQVmAM8hnfTeE7lHzxb8LsFNcgegBAvDrA-vY,293
|
2
2
|
pyloid/api.py,sha256=np0pFVUlen_GpN0svY0A3awY_ZjVFk-RpHQZZKFUMuo,2157
|
3
3
|
pyloid/autostart.py,sha256=K7DQYl4LHItvPp0bt1V9WwaaZmVSTeGvadkcwG-KKrI,3899
|
4
|
-
pyloid/browser_window.py,sha256=
|
4
|
+
pyloid/browser_window.py,sha256=YoScOpHQjxZBGZsYZ_TrDjyoyvwhBsc74ySVNzw5g1g,60873
|
5
5
|
pyloid/custom/titlebar.py,sha256=itzK9pJbZMQ7BKca9kdbuHMffurrw15UijR6OU03Xsk,3894
|
6
6
|
pyloid/filewatcher.py,sha256=3M5zWVUf1OhlkWJcDFC8ZA9agO4Q-U8WdgGpy6kaVz0,4601
|
7
7
|
pyloid/js_api/event_api.py,sha256=_52yyBonqecmMvJpFW7OMNi_jX8Nrteqw_kI6r-DGG0,951
|
8
|
-
pyloid/js_api/window_api.py,sha256=
|
8
|
+
pyloid/js_api/window_api.py,sha256=QutXXAOZkpYmytOYSenpzVSCl15-OFEjDDr75fHfLvk,8481
|
9
9
|
pyloid/monitor.py,sha256=1mXvHm5deohnNlTLcRx4sT4x-stnOIb0dUQnnxN50Uo,28295
|
10
|
-
pyloid/pyloid.py,sha256=
|
10
|
+
pyloid/pyloid.py,sha256=klY6-O7rEZZYfhayq9RTwvO9f8KCXWxIo7G8BDFy2hg,44236
|
11
|
+
pyloid/thread_pool.py,sha256=fKOBb8jMfZn_7crA_fJCno8dObBRZE31EIWaNQ759aw,14616
|
11
12
|
pyloid/timer.py,sha256=RqMsChFUd93cxMVgkHWiIKrci0QDTBgJSTULnAtYT8M,8712
|
12
13
|
pyloid/tray.py,sha256=D12opVEc2wc2T4tK9epaN1oOdeziScsIVNM2uCN7C-A,1710
|
13
14
|
pyloid/utils.py,sha256=VGZE2liY8_AElEqxVe1YLbk3fWlcAevpRc6oOTTgi-U,1927
|
14
|
-
pyloid-0.
|
15
|
-
pyloid-0.
|
16
|
-
pyloid-0.
|
17
|
-
pyloid-0.
|
15
|
+
pyloid-0.17.0.dist-info/LICENSE,sha256=F96EzotgWhhpnQTW2TcdoqrMDir1jyEo6H915tGQ-QE,11524
|
16
|
+
pyloid-0.17.0.dist-info/METADATA,sha256=iuLvJxvORyzQNX-ZDgkOJ8TP6onbfIcFUc5OQZSuPHs,3054
|
17
|
+
pyloid-0.17.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
18
|
+
pyloid-0.17.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|