Add mouse event and signal proxying support
parent
cebfe9dca3
commit
7fc7f72643
|
@ -21,8 +21,8 @@ Qt event proxying and processing using ``trio`` mem chans.
|
|||
from contextlib import asynccontextmanager, AsyncExitStack
|
||||
from typing import Callable
|
||||
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtCore import QEvent
|
||||
from PyQt5 import QtCore, QtGui
|
||||
from PyQt5.QtCore import QEvent, pyqtBoundSignal
|
||||
from PyQt5.QtWidgets import QWidget
|
||||
import trio
|
||||
from pydantic import BaseModel
|
||||
|
@ -35,19 +35,30 @@ class KeyboardMsg(BaseModel):
|
|||
'''Unpacked Qt keyboard event data.
|
||||
|
||||
'''
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
event: QEvent
|
||||
etype: int
|
||||
key: int
|
||||
mods: int
|
||||
txt: str
|
||||
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
def to_tuple(self) -> tuple:
|
||||
return tuple(self.dict().values())
|
||||
|
||||
|
||||
class MouseMsg(BaseModel):
|
||||
'''Unpacked Qt keyboard event data.
|
||||
|
||||
'''
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
event: QEvent
|
||||
etype: int
|
||||
button: int
|
||||
|
||||
# TODO: maybe add some methods to detect key combos? Or is that gonna be
|
||||
# better with pattern matching?
|
||||
# # ctl + alt as combo
|
||||
|
@ -79,7 +90,7 @@ class EventRelay(QtCore.QObject):
|
|||
|
||||
'''
|
||||
etype = ev.type()
|
||||
# print(f'etype: {etype}')
|
||||
# print(f'ev: {ev}')
|
||||
|
||||
if etype in self._event_types:
|
||||
# ev.accept()
|
||||
|
@ -98,7 +109,7 @@ class EventRelay(QtCore.QObject):
|
|||
|
||||
msg = KeyboardMsg(
|
||||
event=ev,
|
||||
etype=ev.type(),
|
||||
etype=etype,
|
||||
key=ev.key(),
|
||||
mods=ev.modifiers(),
|
||||
txt=ev.text(),
|
||||
|
@ -114,12 +125,23 @@ class EventRelay(QtCore.QObject):
|
|||
# processing **before** running a ``trio`` guest mode
|
||||
# tick, thus special handling or copying must be done.
|
||||
|
||||
# send keyboard msg to async handler
|
||||
self._send_chan.send_nowait(msg)
|
||||
elif etype in {
|
||||
QEvent.MouseButtonPress,
|
||||
QEvent.MouseButtonRelease,
|
||||
QtGui.QMouseEvent,
|
||||
}:
|
||||
print('mouse')
|
||||
msg = MouseMsg(
|
||||
event=ev,
|
||||
etype=etype,
|
||||
button=ev.button(),
|
||||
)
|
||||
|
||||
else:
|
||||
# send event to async handler
|
||||
self._send_chan.send_nowait(ev)
|
||||
msg = ev
|
||||
|
||||
# send event-msg to async handler
|
||||
self._send_chan.send_nowait(msg)
|
||||
|
||||
# **do not** filter out this event
|
||||
# and instead forward to the source widget
|
||||
|
@ -156,6 +178,31 @@ async def open_event_stream(
|
|||
source_widget.removeEventFilter(kc)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def open_signal_handler(
|
||||
|
||||
signal: pyqtBoundSignal,
|
||||
async_handler: Callable,
|
||||
|
||||
) -> trio.abc.ReceiveChannel:
|
||||
|
||||
send, recv = trio.open_memory_channel(0)
|
||||
|
||||
def proxy_args_to_chan(*args):
|
||||
send.send_nowait(args)
|
||||
|
||||
signal.connect(proxy_args_to_chan)
|
||||
|
||||
async def proxy_to_handler():
|
||||
async for args in recv:
|
||||
await async_handler(*args)
|
||||
|
||||
async with trio.open_nursery() as n:
|
||||
n.start_soon(proxy_to_handler)
|
||||
async with send:
|
||||
yield
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def open_handlers(
|
||||
|
||||
|
|
Loading…
Reference in New Issue