Python PyQt回调从不运行-如何调试?
我使用PyQt4有一段相当复杂的代码,有时我的信号回调根本就不会运行 它似乎与我注册回调的位置/时间有关,即self.someobj.somesig.connect(self.callback) 我可以在调试器中看到回调已连接,并且信号已发出 代码太大,无法在此处发布,但我将尝试总结:Python PyQt回调从不运行-如何调试?,python,events,pyqt,signals,pyqt4,Python,Events,Pyqt,Signals,Pyqt4,我使用PyQt4有一段相当复杂的代码,有时我的信号回调根本就不会运行 它似乎与我注册回调的位置/时间有关,即self.someobj.somesig.connect(self.callback) 我可以在调试器中看到回调已连接,并且信号已发出 代码太大,无法在此处发布,但我将尝试总结: class RC(QtCore.QObject): render_ready = QtCore.pyqtSignal(object) def __init__(self, pc, ...): su
class RC(QtCore.QObject):
render_ready = QtCore.pyqtSignal(object)
def __init__(self, pc, ...):
super(RC, self).__init__()
self.pc = pc
self.pc.rr.new_render.connect(self.insert)
def check(self):
...
if a: self.pc.replot_request.emit()
else: self.pc.render_request.emit()
def insert(self, r):
...
if b: self.render_ready.emit(r)
self.check()
class RR(QtCore.QObject):
new_render = QtCore.pyqtSignal(object)
def __init__(self, pc, app,...):
super(RR, self).__init__()
self.app = app
self.pc = pc
def run(self):
self.pc.replot_request.connect(self.on_replot_request)
self.pc.render_request.connect(self.render)
...
def render(self, scale):
...
r = R(i)
r.moveToThread(QtGui.QApplication.instance().thread())
r.new_render.emit(r)
class R(QtCore.QObject):
def __init__(self, i):
super(R, self).__init__()
...
...
class PC(QtCore.QObject):
render_request = QtCore.pyqtSignal(int)
replot_request = QtCore.pyqtSignal(object)
def __init__(self, container, app):
super(PC, self).__init__()
...
self.rr = RR(self.app)
self.rr_thread = QtCore.QThread()
self.rr.moveToThread(self.rr_thread)
self.connect(self.rr_thread, QtCore.SIGNAL("started()"), self.rr.run)
self.c = RC(self)
...
self.c.render_ready.connect(self.on_nr)
def start(self):
self.rr_thread.start()
def on_nr(self, r):
print "on_nr(...)"
class App(QtCore.QObject):
...
def __init__(self):
..
self.pc = PC(container, app)
...
self.pc.start(self) # Last thing in constructor
X = QtGui.QApplication(sys.argv)
a = App()
sys.exit(X.exec_())
我看到
render\u ready
连接到\u nr上的,并且发出render\u ready
。但是_nr上的从不运行。信号序列是复杂的,它跨越线程,但是所讨论的信号和回调在同一个线程中。此外,事件循环显然正在运行。我怎样才能开始深入挖掘?还是我犯了什么明显的错误?谢谢。不幸的是,正如对问题的评论中所建议的那样,这是一个愚蠢的错误。它与PyQt或信号的使用无关。我发布了问题是什么以及我是如何调试它的,希望它仍然可以帮助别人
问题出在哪里
我正在用一个新的对象覆盖发出信号的对象(试图重置状态),因此它的信号不再连接到回调
它是如何被检测到的
在调试器中,我注意到当我将信号连接到a.pp.rr
时,它的地址有一个值,当信号发出时,它的地址不同。两个不同的物体
因此,代码是干净的,PyQt信号的使用是正确的。也许学到的教训是在替换实例时要小心。确保重新连接新实例的所有信号,或者在对象中创建一个方法来重置其状态(我就是这么做的),以避免破坏原始实例
其他选项
关于如前所述创建一个问题解决方案,这可能是在本论坛中形成问题的最合适方式,也是确定问题根源的一个很好的练习。同样有效,并且可能更适合于更模糊和复杂的问题的是通过熟练使用调试器。如果您将A编码为连接到B,而A对B没有影响,则A可能与“连接”时的“A”或“B”不相同,或者连接在某个点被删除。当你遗漏了一些东西时,也许你想要的是对正在发生的事情有更多的了解。我认为你需要创建一个。现在代码中有太多的未知项(例如,在classRC
中,您引用了self.pc.r
,但我看不到在任何地方定义了它。在RR.render
中,您创建了r
的一个新实例并发出一个信号,但您在任何地方都没有r
的定义)@三个菠萝如果我能创造一个新的答案,那就意味着我自己几乎解决了这个问题。现在我还不知道是什么导致了这个问题,所以我真的不知道如何创建一个独立的问题。顺便说一下,R
只是QtCore.QObject
的一个简单子类。我现在正在更新示例。好的,我仍然不理解RR.render
。创建R
的一个实例,将其移动到另一个线程(为什么?),并发出一个似乎没有连接到任何东西的信号。同时,RC.render\u ready
在调用RC.insert
之前不会发出,这发生在发出PC.r.new\u render
时,但该对象(PC.r
)似乎不存在于代码中。因此,我不确定您是否过度简化了代码,或者这是否是问题的根本原因。我知道做一个遗嘱意味着你有可能解决你的问题,但坦率地说,这就是重点。所以我对标题“如何调试”中的问题的回答是做一个遗嘱。你要么意识到你做了傻事,要么设法重新制造问题,在这种情况下,这里的人将能够解释你发现的信号、插槽和线程的任何微妙之处。@three_Pinepples我修复了代码PC.r
更改为PC.rr
。我能够解决这个问题,但不幸的是,它与PyQt和信号的使用无关。我尝试了MVCE,但正如我所怀疑的那样,问题没有出现,因为我没有包括原因。。。我还没有找到它的确切位置。见下面我的答案。无论如何,谢谢你。