From dd8754295c9262df8c32a78b23f1388ed10537aa Mon Sep 17 00:00:00 2001 From: Nir Izraeli Date: Sat, 25 Mar 2017 18:05:53 +0300 Subject: [PATCH 1/2] WIP: Fix pyside.Signal.connect complex objects resolves #7 Signed-off-by: Nir Izraeli --- idasix.py | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/idasix.py b/idasix.py index 763d56b..fde54fd 100644 --- a/idasix.py +++ b/idasix.py @@ -149,15 +149,51 @@ class action_handler_t_objprotect(action_handler_t_obj): # noqa: N801 @staticmethod def qtsignalslot(): - """While pre-6.8 qt4 library pyside exposted `Qtcore.Signal` and + """While pre-6.8 qt4 library pyside exposed `Qtcore.Signal` and `QtCore.Slot`, new pyqt library exposes those same methods as `QtCore.pyqtSignal` and `QtCore.pyqtSlot`. This fix makes sure - `Qtcore.Signal` and `QtCore.Slot` are always available""" - if IDA_SDK_VERSION >= 690: + `Qtcore.Signal` and `QtCore.Slot` are always available. + + While pyqt4 and pyside are equivalent, they are different implementations. + Therefore some slight variations and bugs may manifest in one but not the + other. An example of this is pyside's buggy handling of callback closures. + """ + + class idasix_ + + if IDA_SDK_VERSION >= 700: + # pyqt5 is available + QtCore.Signal = QtCore.pyqtSignal + QtCore.Slot = QtCore.pyqtSlot + elif IDA_SDK_VERSION >= 690: + # pyqt4 is available QtCore.Signal = QtCore.pyqtSignal QtCore.Slot = QtCore.pyqtSlot elif IDA_SDK_VERSION < 690: - pass + # pyside is available + class pysideSignal_wrapper(QtCore.QObject): + pysideSignal_cls = QtCore.Signal + pysideSignalInstance = QtCore.Signal(dict) + + def __init__(self, *args, **kwargs): + self.pysideSignal_obj = self.pysideSignal_cls(*args, **kwargs) + + def __getattr__(self, attr): + print(self, self.pysideSignalInstance, attr) + return getattr(self.pysideSignal_obj, attr) + + def connect(self, callback, *w_args, **w_kwargs): + print(self, callback) + wrapped_callback = lambda *args, **kwargs: callback(*args, **kwargs) + return self.pysideSignal_obj.connect(wrapped_callback, *w_args, **w_kwargs) + + QtCore.Signal = pysideSignal_wrapper + print(pysideSignal_wrapper.pysideSignalInstance, type(pysideSignal_wrapper.pysideSignalInstance)) + i = pysideSignal_wrapper() + print(i, type(i)) + print(i.connect) + i.connect = None + @staticmethod def idaname_getname(): From d9e781b7309a821216ecaa130b339de840f8a09d Mon Sep 17 00:00:00 2001 From: Nir Izraeli Date: Tue, 29 May 2018 19:18:27 -0700 Subject: [PATCH 2/2] line wraps and comment out debug prints --- idasix.py | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/idasix.py b/idasix.py index fde54fd..3f14489 100644 --- a/idasix.py +++ b/idasix.py @@ -154,13 +154,12 @@ def qtsignalslot(): `QtCore.pyqtSignal` and `QtCore.pyqtSlot`. This fix makes sure `Qtcore.Signal` and `QtCore.Slot` are always available. - While pyqt4 and pyside are equivalent, they are different implementations. - Therefore some slight variations and bugs may manifest in one but not the - other. An example of this is pyside's buggy handling of callback closures. + While pyqt4 and pyside are equivalent, they are different + implementations. Therefore some slight variations and bugs may manifest + in one but not the other. An example of this is pyside's buggy handling + of callback closures. """ - class idasix_ - if IDA_SDK_VERSION >= 700: # pyqt5 is available QtCore.Signal = QtCore.pyqtSignal @@ -176,23 +175,26 @@ class pysideSignal_wrapper(QtCore.QObject): pysideSignalInstance = QtCore.Signal(dict) def __init__(self, *args, **kwargs): - self.pysideSignal_obj = self.pysideSignal_cls(*args, **kwargs) + self.pysideSignal_obj = self.pysideSignal_cls(*args, + **kwargs) def __getattr__(self, attr): - print(self, self.pysideSignalInstance, attr) + # print(self, self.pysideSignalInstance, attr) return getattr(self.pysideSignal_obj, attr) def connect(self, callback, *w_args, **w_kwargs): - print(self, callback) - wrapped_callback = lambda *args, **kwargs: callback(*args, **kwargs) - return self.pysideSignal_obj.connect(wrapped_callback, *w_args, **w_kwargs) - - QtCore.Signal = pysideSignal_wrapper - print(pysideSignal_wrapper.pysideSignalInstance, type(pysideSignal_wrapper.pysideSignalInstance)) - i = pysideSignal_wrapper() - print(i, type(i)) - print(i.connect) - i.connect = None + # print(self, callback) + wrapped_callback = lambda *args, **kwargs: callback(*args, + **kwargs) + return self.pysideSignal_obj.connect(wrapped_callback, + *w_args, **w_kwargs) + + QtCore.Signal = pysideSignal_wrapper + # print(pysideSignal_wrapper.pysideSignalInstance, type(pysideSignal_wrapper.pysideSignalInstance)) + # i = pysideSignal_wrapper() + # print(i, type(i)) + # print(i.connect) + # i.connect = None @staticmethod