Source code for traits_futures.qt.pingee
# (C) Copyright 2018-2024 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
"""
Qt cross-thread pinger.
This module provides a way for a background thread to request that
the main thread execute a (fixed, parameterless) callback.
"""
from pyface.qt.QtCore import QObject, Qt, Signal, Slot
from traits_futures.i_pingee import IPingee, IPinger
class _Signaller(QObject):
"""
Private object used to send signals to the corresponding Qt receiver.
"""
ping = Signal()
[docs]
@IPingee.register
class Pingee(QObject):
"""
Receiver for pings.
Whenever a ping is received from a linked Pinger, the receiver
calls the given fixed parameterless callable.
The ping receiver must be connected (using the ``connect``) method
before use, and should call ``disconnect`` when it's no longer
expected to receive pings.
Parameters
----------
on_ping
Zero-argument callable that's called on the main thread
every time a ping is received.
"""
def __init__(self, on_ping):
QObject.__init__(self)
self._on_ping = on_ping
@Slot()
def _execute_ping_callback(self):
callback = getattr(self, "_on_ping", None)
if callback is not None:
callback()
[docs]
def connect(self):
"""
Prepare Pingee to receive pings.
"""
pass
[docs]
def disconnect(self):
"""
Disconnect from the on_ping callable.
"""
del self._on_ping
[docs]
def pinger(self):
"""
Create and return a new pinger linked to this pingee.
This method is thread-safe. Typically the pingee will be passed to
a background thread, and this method used within that background thread
to create a pinger.
This method should only be called after the 'connect' method has
been called.
Returns
-------
pinger : Pinger
New pinger, linked to this pingee.
"""
return Pinger(pingee=self)
[docs]
@IPinger.register
class Pinger:
"""
Ping emitter, which can send pings to a receiver in a thread-safe manner.
Parameters
----------
pingee : Pingee
The target receiver for the pings. The receiver must already be
connected.
"""
def __init__(self, pingee):
self._pingee = pingee
[docs]
def connect(self):
"""
Connect to the ping receiver. No pings should be sent until
this function is called.
"""
self._signaller = _Signaller()
self._signaller.ping.connect(
self._pingee._execute_ping_callback,
Qt.QueuedConnection,
)
[docs]
def disconnect(self):
"""
Disconnect from the ping receiver. No pings should be sent
after calling this function.
"""
self._signaller.ping.disconnect(self._pingee._execute_ping_callback)
del self._signaller
del self._pingee
[docs]
def ping(self):
"""
Send a ping to the receiver.
"""
self._signaller.ping.emit()