PyQt now also uses asyncio and its thread contains the main loop
This commit is contained in:
parent
bf2e854cdd
commit
089de1ff93
4 changed files with 50 additions and 19 deletions
15
poetry.lock
generated
15
poetry.lock
generated
|
@ -1,4 +1,4 @@
|
|||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "aiohappyeyeballs"
|
||||
|
@ -1452,6 +1452,17 @@ files = [
|
|||
{file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qasync"
|
||||
version = "0.27.1"
|
||||
description = "Python library for using asyncio in Qt-based applications"
|
||||
optional = false
|
||||
python-versions = ">=3.8,<4.0"
|
||||
files = [
|
||||
{file = "qasync-0.27.1-py3-none-any.whl", hash = "sha256:5d57335723bc7d9b328dadd8cb2ed7978640e4bf2da184889ce50ee3ad2602c7"},
|
||||
{file = "qasync-0.27.1.tar.gz", hash = "sha256:8dc768fd1ee5de1044c7c305eccf2d39d24d87803ea71189d4024fb475f4985f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "qrcode"
|
||||
version = "7.4.2"
|
||||
|
@ -1961,4 +1972,4 @@ server = ["alt-profanity-check"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "a53a034e3cccdb40b71d708df2e82b2e5840639414a3bc727a31cb27b7a0d286"
|
||||
content-hash = "8d19f746a97720e770c47baed26571c2e53aa79a5e7a5a10f62450f519f211a8"
|
||||
|
|
|
@ -43,6 +43,7 @@ pyyaml = { version = "^6.0.1", optional = true }
|
|||
alt-profanity-check = {version = "^1.4.1", optional = true}
|
||||
pyqt6 = {version="^6.7.1", optional = true}
|
||||
mpv = "^1.0.7"
|
||||
qasync = "^0.27.1"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
types-pyyaml = "^6.0.12.12"
|
||||
|
|
|
@ -452,6 +452,7 @@ class Client:
|
|||
:type config: dict[str, Any]
|
||||
:rtype: None
|
||||
"""
|
||||
print("Starting client")
|
||||
|
||||
self.loop = asyncio.get_running_loop()
|
||||
|
||||
|
@ -495,7 +496,9 @@ class Client:
|
|||
|
||||
|
||||
def create_async_and_start_client(
|
||||
config: dict[str, Any], queue: Optional[Queue[LogRecord]] = None
|
||||
config: dict[str, Any],
|
||||
queue: Optional[Queue[LogRecord]] = None,
|
||||
client: Optional[Client] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Create an asyncio event loop and start the client.
|
||||
|
@ -512,7 +515,8 @@ def create_async_and_start_client(
|
|||
if queue is not None:
|
||||
logger.addHandler(QueueHandler(queue))
|
||||
|
||||
client = Client(config)
|
||||
if client is None:
|
||||
client = Client(config)
|
||||
|
||||
asyncio.run(client.start_client(config))
|
||||
|
||||
|
|
45
syng/gui.py
45
syng/gui.py
|
@ -1,15 +1,18 @@
|
|||
import asyncio
|
||||
from io import BytesIO
|
||||
import sys
|
||||
import logging
|
||||
from logging.handlers import QueueListener
|
||||
from multiprocessing import Process, Queue
|
||||
|
||||
# from multiprocessing import Process, Queue
|
||||
from queue import Queue
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime
|
||||
import os
|
||||
from functools import partial
|
||||
import random
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
import multiprocessing
|
||||
import threading
|
||||
import secrets
|
||||
import string
|
||||
import signal
|
||||
|
@ -24,11 +27,11 @@ try:
|
|||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
from qasync import QEventLoop, QApplication
|
||||
from PyQt6.QtCore import QTimer, Qt
|
||||
from PyQt6.QtGui import QCloseEvent, QIcon, QPixmap
|
||||
from PyQt6.QtWidgets import (
|
||||
QApplication,
|
||||
# QApplication,
|
||||
QCheckBox,
|
||||
QComboBox,
|
||||
QDateTimeEdit,
|
||||
|
@ -54,7 +57,7 @@ from qrcode.main import QRCode
|
|||
import platformdirs
|
||||
|
||||
from . import resources # noqa
|
||||
from .client import create_async_and_start_client, default_config
|
||||
from .client import Client, create_async_and_start_client, default_config
|
||||
|
||||
from .sources import available_sources
|
||||
from .config import (
|
||||
|
@ -626,8 +629,9 @@ class SyngGui(QMainWindow):
|
|||
if os.name != "nt":
|
||||
self.setWindowIcon(QIcon(":/icons/syng.ico"))
|
||||
|
||||
self.syng_server: Optional[Process] = None
|
||||
self.syng_client: Optional[Process] = None
|
||||
self.loop = asyncio.get_event_loop()
|
||||
self.syng_server: Optional[threading.Thread] = None
|
||||
self.syng_client: Optional[threading.Thread] = None
|
||||
self.syng_client_logging_listener: Optional[QueueListener] = None
|
||||
|
||||
self.configfile = os.path.join(platformdirs.user_config_dir("syng"), "config.yaml")
|
||||
|
@ -752,9 +756,11 @@ class SyngGui(QMainWindow):
|
|||
return
|
||||
|
||||
if not self.syng_client.is_alive():
|
||||
print("Client is not running")
|
||||
self.syng_client = None
|
||||
self.set_client_button_start()
|
||||
else:
|
||||
print("Client is running")
|
||||
self.set_client_button_stop()
|
||||
|
||||
def set_client_button_stop(self) -> None:
|
||||
|
@ -767,24 +773,28 @@ class SyngGui(QMainWindow):
|
|||
if self.syng_client is None or not self.syng_client.is_alive():
|
||||
self.save_config()
|
||||
config = self.gather_config()
|
||||
queue: Queue[logging.LogRecord] = multiprocessing.Queue()
|
||||
queue: Queue[logging.LogRecord] = Queue()
|
||||
|
||||
self.syng_client_logging_listener = QueueListener(
|
||||
queue, LoggingLabelHandler(self.notification_label)
|
||||
)
|
||||
self.syng_client_logging_listener.start()
|
||||
|
||||
self.syng_client = multiprocessing.Process(
|
||||
target=create_async_and_start_client, args=[config, queue]
|
||||
)
|
||||
self.syng_client.start()
|
||||
# self.syng_client = multiprocessing.Process(
|
||||
# target=create_async_and_start_client, args=[config, queue]
|
||||
# )
|
||||
self.client = Client(config)
|
||||
asyncio.run_coroutine_threadsafe(self.client.start_client(config), self.loop)
|
||||
# self.syng_client = threading.Thread(
|
||||
# target=create_async_and_start_client, args=[config, queue, self.client]
|
||||
# )
|
||||
# self.syng_client.start()
|
||||
self.notification_label.setText("")
|
||||
self.timer.start(500)
|
||||
self.set_client_button_stop()
|
||||
else:
|
||||
self.syng_client.terminate()
|
||||
self.client.quit_callback()
|
||||
self.syng_client.join(1.0)
|
||||
self.syng_client.kill()
|
||||
self.set_client_button_start()
|
||||
|
||||
# def start_syng_server(self) -> None:
|
||||
|
@ -853,6 +863,9 @@ def run_gui() -> None:
|
|||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
|
||||
app = QApplication([])
|
||||
event_loop = QEventLoop(app)
|
||||
asyncio.set_event_loop(event_loop)
|
||||
|
||||
if os.name == "nt":
|
||||
app.setWindowIcon(QIcon(os.path.join(base_dir, "syng.ico")))
|
||||
else:
|
||||
|
@ -861,7 +874,9 @@ def run_gui() -> None:
|
|||
app.setDesktopFileName("rocks.syng.Syng")
|
||||
window = SyngGui()
|
||||
window.show()
|
||||
app.exec()
|
||||
# app.exec()
|
||||
with event_loop:
|
||||
event_loop.run_forever()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Add table
Reference in a new issue