Python PyQt callback never runs - how to debug?

試著忘記壹切 提交于 2019-12-12 04:17:05

问题


I have a fairly complicated piece of code using PyQt4 and sometimes my signal callbacks simply never run.

It seems to be related to where/when I register the callbacks, ie. self.someobj.somesig.connect(self.callback).

I can see in the debugger that the callback is connected and that the signal es emitted.

The code is too large to post here, but I will try to summarize:

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_())

I see render_ready being connected to on_nr and the render_ready being emitted. But on_nr never runs. The signal sequence is complicated, it goes across threads, but the signal and callback in question are in the same thread. Also, the event loop is clearly running. How could I start digging deeper? Or am I making some evident mistake? Thanks.


回答1:


Unfortunately it was a silly mistake as suggested in the comments to the question. It had nothing to do with PyQt or the use of signals. I post what the problem was and how I debugged it in hopes that it still might help somebody.

What the problem was

I was overwriting the object that emitted the signal with a new one (an attempt to reset state), so its signal was not connected to the callback any more.

How it was detected

In the debugger I noticed that the address of a.pp.rr had one value when I connected the signal to it, and when the signal was emitted, it's address was different. Two different objects.

So the code was clean and the use of PyQt signals was correct. Perhaps the lesson learned is to be careful when replacing an instance. Make sure to reconnect all signals to/from the new instance, or create a method in the object to reset it's state (this is what I did) to avoid destroying the original instance.

Other Options

With regards to creating an Minimal, Complete, and Verifiable example as suggested earlier, it is perhaps the most appropriate way to format a question in this forum and a good exercise in identifying the source of problems. Equally valid, and perhaps more appropriate for more obscure and complex problems is through the skillful use of the debugger. If you are coding A to be connected to B and A is not having and impact on B, then it is possible that A is not the same "A" or B is not the same "B" as when the "connection" was made, or the connection was removed at some point. When you are missing something, perhaps you want is to gain more visibility into what is happening.



来源:https://stackoverflow.com/questions/34700152/python-pyqt-callback-never-runs-how-to-debug

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!