-
Notifications
You must be signed in to change notification settings - Fork 13
/
QtBinding.py
47 lines (38 loc) · 1.92 KB
/
QtBinding.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# In Python source files where we want to use Qt facilities, do the following:
#
# from QtBinding import QtCore, QtGui, QtSignal, QtSlot
#
# ... then, use the QtSlot() decorator for slots, and the QtSignal() function to declare signals.
import sys, logging
usePySide = ("--pyside" in sys.argv[1:])
if usePySide:
from PySide import QtCore, QtGui
QtSignal = QtCore.Signal
QtSlot_Unchecked = QtCore.Slot
else:
from PyQt4 import QtCore, QtGui
QtSignal = QtCore.pyqtSignal
QtSlot_Unchecked = QtCore.pyqtSlot
def QtSlot_Checked(*args, **kwargs):
# The QtSlot_Checked decorator function wraps the functionality of the QtSlot_Unchecked decorator function,
# and verifies that (1) the function being decorated does not throw an exception and (2) that it returns None.
def check_slot_function_result(f):
def check_slot_function_result_wrapper(*args, **kwargs):
try:
result = f(*args, **kwargs)
if result is not None:
raise ValueError("Value returned from slot function '{}' is not None as required, but '{}', of type {}.".format(f, result, type(result)))
except BaseException as exception:
logging.exception("intercepted an exception: {}".format(exception))
sys.exit(1)
return None # this is the expected behavior for a slot function.
# The __name__ assignment is needed to allow the Qt binding to work properly (at least in PySide).
# If this is omitted, slots are executed in the incorrect thread when using PySide.
check_slot_function_result_wrapper.__name__ = f.__name__
return check_slot_function_result_wrapper
decorator = QtSlot_Unchecked(*args, **kwargs)
def wrapped_qtslot_decorator(f):
return decorator(check_slot_function_result(f))
return wrapped_qtslot_decorator
# Use the "checked" variant of QtSlot.
QtSlot = QtSlot_Checked