Python PyQt回调从不运行-如何调试?

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

我使用PyQt4有一段相当复杂的代码,有时我的信号回调根本就不会运行

它似乎与我注册回调的位置/时间有关,即self.someobj.somesig.connect(self.callback)

我可以在调试器中看到回调已连接,并且信号已发出

代码太大,无法在此处发布,但我将尝试总结:

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”不相同,或者连接在某个点被删除。当你遗漏了一些东西时,也许你想要的是对正在发生的事情有更多的了解。

我认为你需要创建一个。现在代码中有太多的未知项(例如,在class
RC
中,您引用了
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,但正如我所怀疑的那样,问题没有出现,因为我没有包括原因。。。我还没有找到它的确切位置。见下面我的答案。无论如何,谢谢你。