调试一个pyQT4应用程序?

51

我有一个使用pyqt4构建的相当简单的应用程序。我想要调试与我应用程序中一个按钮连接的函数之一。但是,当我执行以下操作时

python -m pdb app.pyw
> break app.pyw:55  # This is where the signal handling function starts.

我希望的方式并没有发挥作用。调试器没有在我设置断点的函数中停下来让我逐步执行,相反,它进入了一个无限循环,不停地打印出 QCoreApplication :: exec:事件循环已经运行,我无法输入任何东西。有更好的方法吗?


只是想知道,第55行是什么?是你注册信号的地方还是处理它的函数? - Federico klez Culloca
在这种情况下,那就是处理信号的函数。 - Paul Wicks
1
我认为这不是一个完整的答案,但你可以尝试使用ERIC作为Python和PyQt的GUI调试器:http://eric-ide.python-projects.org/ - Berschi
3个回答

97

你需要调用QtCore.pyqtRemoveInputHook。 我在自己的版本的set_trace中进行了封装:

def debug_trace():
  '''Set a tracepoint in the Python debugger that works with Qt'''
  from PyQt4.QtCore import pyqtRemoveInputHook

  # Or for Qt5
  #from PyQt5.QtCore import pyqtRemoveInputHook

  from pdb import set_trace
  pyqtRemoveInputHook()
  set_trace()

当你完成调试后,可以调用 QtCore.pyqtRestoreInputHook(),最好在pdb中执行此操作,并在按回车键后,控制台出现垃圾信息时不断按 'c'(表示继续),直到应用程序正常恢复。我不知道为什么,但我必须按 'c' 多次,它才能正常恢复。

有关更多信息,请搜索“pyqtRemoveInputHook pdb”。(非常显然,不是吗?;P)


5
有用的答案,仅供参考。我发现这在PyQt4中有效,但在PySide中无效。 - Philip Clarke

6

我在跟踪点上使用了“下一步”命令,以先从该函数中退出。为此,我修改了mgrandi的代码:

def pyqt_set_trace():
    '''Set a tracepoint in the Python debugger that works with Qt'''
    from PyQt4.QtCore import pyqtRemoveInputHook
    import pdb
    import sys
    pyqtRemoveInputHook()
    # set up the debugger
    debugger = pdb.Pdb()
    debugger.reset()
    # custom next to get outside of function scope
    debugger.do_next(None) # run the next command
    users_frame = sys._getframe().f_back # frame where the user invoked `pyqt_set_trace()`
    debugger.interaction(users_frame, None)

这对我很有帮助。我从这里找到了解决方案:Python(pdb)-排队执行命令


pdb.Pdb()现在在pyqt5中导致了一个段错误。 - nmz787

0
在我的测试中,jamk的解决方案有效,而之前的那个虽然更简单,但却无法实现。
在某些情况下,出于我不清楚的原因,我能够在不进行任何操作的情况下调试Qt。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接