pyloid 0.9.5__tar.gz → 0.9.8__tar.gz
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-0.9.5 → pyloid-0.9.8}/PKG-INFO +26 -26
- {pyloid-0.9.5 → pyloid-0.9.8}/README.md +25 -25
- {pyloid-0.9.5 → pyloid-0.9.8}/pyproject.toml +2 -2
- pyloid-0.9.8/src/pyloid/__init__.py +6 -0
- {pyloid-0.9.5/src/pylonic → pyloid-0.9.8/src/pyloid}/api.py +1 -1
- pyloid-0.9.5/src/pylonic/pylonic.py → pyloid-0.9.8/src/pyloid/pyloid.py +15 -16
- pyloid-0.9.5/src/pylonic/__init__.py +0 -6
- {pyloid-0.9.5 → pyloid-0.9.8}/LICENSE +0 -0
- {pyloid-0.9.5/src/pylonic → pyloid-0.9.8/src/pyloid}/autostart.py +0 -0
- {pyloid-0.9.5/src/pylonic → pyloid-0.9.8/src/pyloid}/monitor.py +0 -0
- {pyloid-0.9.5/src/pylonic → pyloid-0.9.8/src/pyloid}/tray.py +0 -0
- {pyloid-0.9.5/src/pylonic → pyloid-0.9.8/src/pyloid}/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyloid
|
3
|
-
Version: 0.9.
|
3
|
+
Version: 0.9.8
|
4
4
|
Summary:
|
5
5
|
Author: aesthetics-of-record
|
6
6
|
Author-email: 111675679+aesthetics-of-record@users.noreply.github.com
|
@@ -13,15 +13,15 @@ Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Requires-Dist: pyside6 (>=6.7.3,<7.0.0)
|
14
14
|
Description-Content-Type: text/markdown
|
15
15
|
|
16
|
-
#
|
16
|
+
# Pyloid 👋
|
17
17
|
|
18
|
-
|
18
|
+
Pyloid is the Python backend version of Electron and Tauri, designed to simplify desktop application development. This open-source project, built on **QtWebEngine** and **PySide6**, provides seamless integration with various Python features, making it easy to build powerful applications effortlessly.
|
19
19
|
|
20
20
|

|
21
21
|
|
22
|
-
## 🚀 Why
|
22
|
+
## 🚀 Why Pyloid?
|
23
23
|
|
24
|
-
With
|
24
|
+
With Pyloid, you can leverage the full power of Python in your desktop applications. Its simplicity and flexibility make it the perfect choice for both beginners and experienced developers looking for a Python-focused alternative to Electron or Tauri. It is especially optimized for building AI-powered desktop applications.
|
25
25
|
|
26
26
|
## Key Features 🚀
|
27
27
|
|
@@ -38,44 +38,44 @@ With Pylonic, you can leverage the full power of Python in your desktop applicat
|
|
38
38
|
|
39
39
|
## Documentation 📚
|
40
40
|
|
41
|
-
[
|
41
|
+
[Pyloid Documentation](https://docs.pyloid.com/)
|
42
42
|
|
43
43
|
### Create Project 📦
|
44
44
|
|
45
|
-
#### Creating a HTML/CSS/JS +
|
45
|
+
#### Creating a HTML/CSS/JS + Pyloid Project 🌐
|
46
46
|
|
47
|
-
[https://github.com/pylonic/
|
47
|
+
[https://github.com/pylonic/pyloid_html_boilerplate](https://github.com/Pyloid/pyloid_html_boilerplate)
|
48
48
|
|
49
|
-
#### Creating a React + Vite +
|
49
|
+
#### Creating a React + Vite + Pyloid Project ⚛️
|
50
50
|
|
51
|
-
[https://github.com/pylonic/
|
51
|
+
[https://github.com/pylonic/pyloid_react_boilerplate](https://github.com/Pyloid/yloid_react_boilerplate)
|
52
52
|
|
53
53
|
### Custom Your Boilerplate 🔨
|
54
54
|
|
55
55
|
```bash
|
56
|
-
pip install
|
56
|
+
pip install pyloid
|
57
57
|
```
|
58
58
|
|
59
|
-
Package URL: [https://pypi.org/project/
|
59
|
+
Package URL: [https://pypi.org/project/pyloid/](https://pypi.org/project/pyloid/)
|
60
60
|
|
61
61
|
## Usage 🛠️
|
62
62
|
|
63
63
|
### Creating a Basic Application
|
64
64
|
|
65
65
|
```python
|
66
|
-
from
|
66
|
+
from pyloid import Pyloid
|
67
67
|
|
68
|
-
app =
|
68
|
+
app = Pyloid(single_instance=True)
|
69
69
|
|
70
70
|
# set icon
|
71
71
|
if (is_production()):
|
72
72
|
app.set_icon(os.path.join(get_production_path(), "icons/icon.png"))
|
73
73
|
else:
|
74
|
-
app.set_icon("src-
|
74
|
+
app.set_icon("src-pyloid/icons/icon.png")
|
75
75
|
|
76
76
|
# create window
|
77
77
|
window = app.create_window(
|
78
|
-
title="
|
78
|
+
title="Pyloid Browser",
|
79
79
|
js_apis=[CustomAPI()],
|
80
80
|
dev_tools=True
|
81
81
|
)
|
@@ -98,7 +98,7 @@ app.run()
|
|
98
98
|
### Setting Up System Tray
|
99
99
|
|
100
100
|
```python
|
101
|
-
from
|
101
|
+
from pyloid import TrayEvent
|
102
102
|
|
103
103
|
def on_double_click():
|
104
104
|
print("Tray icon was double-clicked.")
|
@@ -115,23 +115,23 @@ app.setup_tray()
|
|
115
115
|
|
116
116
|
```javascript
|
117
117
|
// CustomAPI method usage example
|
118
|
-
document.addEventListener('
|
118
|
+
document.addEventListener('pyloidReady', function () {
|
119
119
|
// Using the echo method
|
120
|
-
|
120
|
+
window.pyloid.CustomAPI.echo('Hello', 42).then((result) => {
|
121
121
|
console.log(result); // "Message received in Python: Hello, 42" output
|
122
122
|
});
|
123
123
|
|
124
124
|
// Using the getAppVersion method
|
125
|
-
|
125
|
+
window.pyloid.CustomAPI.getAppVersion().then((version) => {
|
126
126
|
console.log('App version:', version); // "App version: 1.0.0" output
|
127
127
|
});
|
128
128
|
|
129
129
|
// Example using async/await syntax
|
130
130
|
async function useCustomAPI() {
|
131
|
-
const echoResult = await
|
131
|
+
const echoResult = await window.pyloid.CustomAPI.echo('Test', 100);
|
132
132
|
console.log(echoResult);
|
133
133
|
|
134
|
-
const appVersion = await
|
134
|
+
const appVersion = await window.pyloid.CustomAPI.getAppVersion();
|
135
135
|
console.log('Current app version:', appVersion);
|
136
136
|
}
|
137
137
|
|
@@ -140,7 +140,7 @@ document.addEventListener('pylonReady', function () {
|
|
140
140
|
// Button click event binding
|
141
141
|
document.getElementById('myButton').addEventListener('click', function () {
|
142
142
|
// Using the create_window method
|
143
|
-
|
143
|
+
window.pyloid.CustomAPI.create_window().then((windowId) => {
|
144
144
|
console.log('New window ID:', windowId); // "New window ID: [generated window ID]" output
|
145
145
|
});
|
146
146
|
});
|
@@ -155,7 +155,7 @@ import { createRoot } from 'react-dom/client';
|
|
155
155
|
import App from './App.jsx';
|
156
156
|
import './index.css';
|
157
157
|
|
158
|
-
document.addEventListener('
|
158
|
+
document.addEventListener('pyloidReady', function () {
|
159
159
|
createRoot(document.getElementById('root')).render(
|
160
160
|
<StrictMode>
|
161
161
|
<App />
|
@@ -164,9 +164,9 @@ document.addEventListener('pylonReady', function () {
|
|
164
164
|
});
|
165
165
|
|
166
166
|
function App() {
|
167
|
-
console.log('
|
167
|
+
console.log('Pyloid is ready');
|
168
168
|
|
169
|
-
window.
|
169
|
+
window.pyloid.CustomAPI.getAppVersion().then((version) => {
|
170
170
|
console.log('App version:', version); // "App version: 1.0.0"
|
171
171
|
});
|
172
172
|
return <h1>Hello World</h1>;
|
@@ -1,12 +1,12 @@
|
|
1
|
-
#
|
1
|
+
# Pyloid 👋
|
2
2
|
|
3
|
-
|
3
|
+
Pyloid is the Python backend version of Electron and Tauri, designed to simplify desktop application development. This open-source project, built on **QtWebEngine** and **PySide6**, provides seamless integration with various Python features, making it easy to build powerful applications effortlessly.
|
4
4
|
|
5
5
|

|
6
6
|
|
7
|
-
## 🚀 Why
|
7
|
+
## 🚀 Why Pyloid?
|
8
8
|
|
9
|
-
With
|
9
|
+
With Pyloid, you can leverage the full power of Python in your desktop applications. Its simplicity and flexibility make it the perfect choice for both beginners and experienced developers looking for a Python-focused alternative to Electron or Tauri. It is especially optimized for building AI-powered desktop applications.
|
10
10
|
|
11
11
|
## Key Features 🚀
|
12
12
|
|
@@ -23,44 +23,44 @@ With Pylonic, you can leverage the full power of Python in your desktop applicat
|
|
23
23
|
|
24
24
|
## Documentation 📚
|
25
25
|
|
26
|
-
[
|
26
|
+
[Pyloid Documentation](https://docs.pyloid.com/)
|
27
27
|
|
28
28
|
### Create Project 📦
|
29
29
|
|
30
|
-
#### Creating a HTML/CSS/JS +
|
30
|
+
#### Creating a HTML/CSS/JS + Pyloid Project 🌐
|
31
31
|
|
32
|
-
[https://github.com/pylonic/
|
32
|
+
[https://github.com/pylonic/pyloid_html_boilerplate](https://github.com/Pyloid/pyloid_html_boilerplate)
|
33
33
|
|
34
|
-
#### Creating a React + Vite +
|
34
|
+
#### Creating a React + Vite + Pyloid Project ⚛️
|
35
35
|
|
36
|
-
[https://github.com/pylonic/
|
36
|
+
[https://github.com/pylonic/pyloid_react_boilerplate](https://github.com/Pyloid/yloid_react_boilerplate)
|
37
37
|
|
38
38
|
### Custom Your Boilerplate 🔨
|
39
39
|
|
40
40
|
```bash
|
41
|
-
pip install
|
41
|
+
pip install pyloid
|
42
42
|
```
|
43
43
|
|
44
|
-
Package URL: [https://pypi.org/project/
|
44
|
+
Package URL: [https://pypi.org/project/pyloid/](https://pypi.org/project/pyloid/)
|
45
45
|
|
46
46
|
## Usage 🛠️
|
47
47
|
|
48
48
|
### Creating a Basic Application
|
49
49
|
|
50
50
|
```python
|
51
|
-
from
|
51
|
+
from pyloid import Pyloid
|
52
52
|
|
53
|
-
app =
|
53
|
+
app = Pyloid(single_instance=True)
|
54
54
|
|
55
55
|
# set icon
|
56
56
|
if (is_production()):
|
57
57
|
app.set_icon(os.path.join(get_production_path(), "icons/icon.png"))
|
58
58
|
else:
|
59
|
-
app.set_icon("src-
|
59
|
+
app.set_icon("src-pyloid/icons/icon.png")
|
60
60
|
|
61
61
|
# create window
|
62
62
|
window = app.create_window(
|
63
|
-
title="
|
63
|
+
title="Pyloid Browser",
|
64
64
|
js_apis=[CustomAPI()],
|
65
65
|
dev_tools=True
|
66
66
|
)
|
@@ -83,7 +83,7 @@ app.run()
|
|
83
83
|
### Setting Up System Tray
|
84
84
|
|
85
85
|
```python
|
86
|
-
from
|
86
|
+
from pyloid import TrayEvent
|
87
87
|
|
88
88
|
def on_double_click():
|
89
89
|
print("Tray icon was double-clicked.")
|
@@ -100,23 +100,23 @@ app.setup_tray()
|
|
100
100
|
|
101
101
|
```javascript
|
102
102
|
// CustomAPI method usage example
|
103
|
-
document.addEventListener('
|
103
|
+
document.addEventListener('pyloidReady', function () {
|
104
104
|
// Using the echo method
|
105
|
-
|
105
|
+
window.pyloid.CustomAPI.echo('Hello', 42).then((result) => {
|
106
106
|
console.log(result); // "Message received in Python: Hello, 42" output
|
107
107
|
});
|
108
108
|
|
109
109
|
// Using the getAppVersion method
|
110
|
-
|
110
|
+
window.pyloid.CustomAPI.getAppVersion().then((version) => {
|
111
111
|
console.log('App version:', version); // "App version: 1.0.0" output
|
112
112
|
});
|
113
113
|
|
114
114
|
// Example using async/await syntax
|
115
115
|
async function useCustomAPI() {
|
116
|
-
const echoResult = await
|
116
|
+
const echoResult = await window.pyloid.CustomAPI.echo('Test', 100);
|
117
117
|
console.log(echoResult);
|
118
118
|
|
119
|
-
const appVersion = await
|
119
|
+
const appVersion = await window.pyloid.CustomAPI.getAppVersion();
|
120
120
|
console.log('Current app version:', appVersion);
|
121
121
|
}
|
122
122
|
|
@@ -125,7 +125,7 @@ document.addEventListener('pylonReady', function () {
|
|
125
125
|
// Button click event binding
|
126
126
|
document.getElementById('myButton').addEventListener('click', function () {
|
127
127
|
// Using the create_window method
|
128
|
-
|
128
|
+
window.pyloid.CustomAPI.create_window().then((windowId) => {
|
129
129
|
console.log('New window ID:', windowId); // "New window ID: [generated window ID]" output
|
130
130
|
});
|
131
131
|
});
|
@@ -140,7 +140,7 @@ import { createRoot } from 'react-dom/client';
|
|
140
140
|
import App from './App.jsx';
|
141
141
|
import './index.css';
|
142
142
|
|
143
|
-
document.addEventListener('
|
143
|
+
document.addEventListener('pyloidReady', function () {
|
144
144
|
createRoot(document.getElementById('root')).render(
|
145
145
|
<StrictMode>
|
146
146
|
<App />
|
@@ -149,9 +149,9 @@ document.addEventListener('pylonReady', function () {
|
|
149
149
|
});
|
150
150
|
|
151
151
|
function App() {
|
152
|
-
console.log('
|
152
|
+
console.log('Pyloid is ready');
|
153
153
|
|
154
|
-
window.
|
154
|
+
window.pyloid.CustomAPI.getAppVersion().then((version) => {
|
155
155
|
console.log('App version:', version); // "App version: 1.0.0"
|
156
156
|
});
|
157
157
|
return <h1>Hello World</h1>;
|
@@ -1,11 +1,11 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "pyloid"
|
3
|
-
version = "0.9.
|
3
|
+
version = "0.9.8"
|
4
4
|
description = ""
|
5
5
|
authors = ["aesthetics-of-record <111675679+aesthetics-of-record@users.noreply.github.com>"]
|
6
6
|
readme = "README.md"
|
7
7
|
packages = [
|
8
|
-
{ include = "
|
8
|
+
{ include = "pyloid", from = "src" },
|
9
9
|
]
|
10
10
|
|
11
11
|
[tool.poetry.dependencies]
|
@@ -12,7 +12,7 @@ from PySide6.QtGui import QIcon, QKeySequence, QShortcut, QClipboard, QImage
|
|
12
12
|
from PySide6.QtCore import Qt, Signal, QUrl, QObject
|
13
13
|
from PySide6.QtNetwork import QLocalServer, QLocalSocket
|
14
14
|
from PySide6.QtWebEngineCore import QWebEnginePage, QWebEngineSettings
|
15
|
-
from .api import
|
15
|
+
from .api import PyloidAPI, Bridge
|
16
16
|
import uuid
|
17
17
|
from typing import List, Optional, Dict, Callable, Union, Any
|
18
18
|
from PySide6.QtCore import qInstallMessageHandler
|
@@ -26,11 +26,10 @@ from .autostart import AutoStart
|
|
26
26
|
os.environ['QTWEBENGINE_DICTIONARIES_PATH'] = '/'
|
27
27
|
|
28
28
|
# for macos debug
|
29
|
-
os.environ['QT_MAC_WANTS_LAYER'] = '1'
|
30
29
|
|
31
30
|
def custom_message_handler(mode, context, message):
|
32
31
|
if not hasattr(custom_message_handler, 'vulkan_warning_shown') and (('Failed to load vulkan' in message) or ('No Vulkan library available' in message) or ('Failed to create platform Vulkan instance' in message)):
|
33
|
-
print('\033[
|
32
|
+
print('\033[93mPyloid Warning: Vulkan GPU API issue detected. Switching to software backend.\033[0m')
|
34
33
|
os.environ['QT_QUICK_BACKEND'] = 'software'
|
35
34
|
custom_message_handler.vulkan_warning_shown = True
|
36
35
|
if 'vulkan' not in message.lower():
|
@@ -38,11 +37,11 @@ def custom_message_handler(mode, context, message):
|
|
38
37
|
|
39
38
|
qInstallMessageHandler(custom_message_handler)
|
40
39
|
|
41
|
-
class WindowAPI(
|
40
|
+
class WindowAPI(PyloidAPI):
|
42
41
|
def __init__(self, window_id: str, app):
|
43
42
|
super().__init__()
|
44
43
|
self.window_id: str = window_id
|
45
|
-
self.app:
|
44
|
+
self.app: Pyloid = app
|
46
45
|
|
47
46
|
@Bridge(result=str)
|
48
47
|
def getWindowId(self):
|
@@ -183,7 +182,7 @@ class BrowserWindow:
|
|
183
182
|
frame: bool=True,
|
184
183
|
context_menu: bool=False,
|
185
184
|
dev_tools: bool=False,
|
186
|
-
js_apis: List[
|
185
|
+
js_apis: List[PyloidAPI]=[],
|
187
186
|
):
|
188
187
|
###########################################################################################
|
189
188
|
self.id = str(uuid.uuid4()) # Generate unique ID
|
@@ -265,7 +264,7 @@ class BrowserWindow:
|
|
265
264
|
js_code = """
|
266
265
|
if (typeof QWebChannel !== 'undefined') {
|
267
266
|
new QWebChannel(qt.webChannelTransport, function (channel) {
|
268
|
-
window.
|
267
|
+
window.pyloid = {
|
269
268
|
EventAPI: {
|
270
269
|
listen: function(eventName, callback) {
|
271
270
|
document.addEventListener(eventName, function(event) {
|
@@ -283,12 +282,12 @@ class BrowserWindow:
|
|
283
282
|
}
|
284
283
|
}
|
285
284
|
};
|
286
|
-
console.log('
|
285
|
+
console.log('pyloid.EventAPI object initialized:', window.pyloid.EventAPI);
|
287
286
|
|
288
287
|
%s
|
289
288
|
|
290
289
|
// Dispatch a custom event to signal that the initialization is ready
|
291
|
-
const event = new CustomEvent('
|
290
|
+
const event = new CustomEvent('pyloidReady');
|
292
291
|
document.dispatchEvent(event);
|
293
292
|
});
|
294
293
|
} else {
|
@@ -297,8 +296,8 @@ class BrowserWindow:
|
|
297
296
|
"""
|
298
297
|
js_api_init = "\n".join(
|
299
298
|
[
|
300
|
-
f"window.
|
301
|
-
f"console.log('
|
299
|
+
f"window.pyloid['{js_api.__class__.__name__}'] = channel.objects['{js_api.__class__.__name__}'];\n"
|
300
|
+
f"console.log('pyloid.{js_api.__class__.__name__} object initialized:', window.pyloid['{js_api.__class__.__name__}']);"
|
302
301
|
for js_api in self.js_apis
|
303
302
|
]
|
304
303
|
)
|
@@ -537,7 +536,7 @@ class _WindowController(QObject):
|
|
537
536
|
QApplication, str, int, int, int, int, bool, bool, bool, list
|
538
537
|
)
|
539
538
|
|
540
|
-
class
|
539
|
+
class Pyloid(QApplication):
|
541
540
|
def __init__(self, app_name, single_instance=True, icon_path: str=None, tray_icon_path: str=None):
|
542
541
|
super().__init__(sys.argv)
|
543
542
|
|
@@ -586,7 +585,7 @@ class Pylonic(QApplication):
|
|
586
585
|
frame: bool=True,
|
587
586
|
context_menu: bool=False,
|
588
587
|
dev_tools: bool=False,
|
589
|
-
js_apis: List[
|
588
|
+
js_apis: List[PyloidAPI]=[],
|
590
589
|
) -> BrowserWindow:
|
591
590
|
"""Creates a new browser window."""
|
592
591
|
self.controller.create_window_signal.emit(
|
@@ -614,7 +613,7 @@ class Pylonic(QApplication):
|
|
614
613
|
frame: bool,
|
615
614
|
context_menu: bool,
|
616
615
|
dev_tools: bool,
|
617
|
-
js_apis: List[
|
616
|
+
js_apis: List[PyloidAPI]=[],
|
618
617
|
) -> BrowserWindow:
|
619
618
|
"""Function to create a new browser window."""
|
620
619
|
window = BrowserWindow(
|
@@ -643,14 +642,14 @@ class Pylonic(QApplication):
|
|
643
642
|
def _init_single_instance(self):
|
644
643
|
"""Initializes the application as a single instance."""
|
645
644
|
socket = QLocalSocket()
|
646
|
-
socket.connectToServer("
|
645
|
+
socket.connectToServer("PyloidBrowserApp")
|
647
646
|
if socket.waitForConnected(500):
|
648
647
|
# Another instance is already running
|
649
648
|
sys.exit(1)
|
650
649
|
|
651
650
|
# Create a new server
|
652
651
|
self.server = QLocalServer()
|
653
|
-
self.server.listen("
|
652
|
+
self.server.listen("PyloidBrowserApp")
|
654
653
|
self.server.newConnection.connect(self._handle_new_connection)
|
655
654
|
|
656
655
|
def _handle_new_connection(self):
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|