多线程Python应用在Visual Studio中无法命中断点

9
我正在使用Visual Studio开发一个PyQt应用程序。 调试一直非常顺利,直到我决定通过使用Qt Threads将一些内容移动到工作线程以保持UI的响应性。
class MainWindow(base, form):

    start_work = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        # Create a seperate thread in which the update information is polled.
        self.thread = QtCore.QThread()
        # Create Worker object and move it to new thread
        self.worker = Worker()
        self.worker.moveToThread(self.thread)
        # connect signal to start work in the extra tread
        self.start_work.connect(self.worker.get_work_done)
        self.thread.start()

    #function emit a signal to start doing the work
    def do_work(self):
        self.startWork.emit()

任何在我的worker对象上调用的函数都通过信号槽进行连接。
class Worker(QtCore.QObject):
    @QtCore.pyqtSlot()
    def get_work_done(self):
        #lets do some time consuming work.

代码运行正常。唯一的问题是,我现在无法调试get_work_done函数内发生的任何事情。Visual Studio不会在这些断点处中断。

当我在任何一个MainWindow函数中中断时,Visual Studio调试器只显示一个线程。它似乎不知道应用程序创建的任何其他线程。

2个回答

8

如已经提到的,所有非使用Python创建的线程都需要在PTVS中注册。 对于QThread,请在线程的run方法中调用此方法:

import pydevd;pydevd.settrace(suspend=False)

这里有一些更多信息:我能在Python后台线程上设置断点吗?


(注意:为了遵循格式要求,我保留了HTML标签。)

2

调试器需要使用一些技巧来检测新线程并设置其钩子(这些钩子是打断点等操作所必需的)。它通过劫持标准的Python _thread模块来实现。如果你以某种方式创建线程,完全绕过了该模块,这就是我怀疑Qt在这里所做的,那么调试器将不会意识到这些线程。

尝试使用标准的threading模块而不是QThread,看看是否有所帮助。


2
如果我使用常规的线程模块,就无法使用信号和槽机制在线程之间进行通信。这就是为什么我想利用Qt线程的原因。没有办法让调试器意识到这些线程吗? - kiki
在Python for .Net中遇到了同样的问题...线程是在某个.net模块中创建的,然后在Python中调用一个事件。需要找到一种方法来强制设置钩子吗? - Jay
很遗憾,对于这个问题没有一个好的通用解决方案,除非尝试支持每个特定库所做的事情。您可以通过修改调试器的代码(visualstudio_py_debugger.py)来添加此类支持,或许可以将其扩展以使此过程更加容易。请随意在http://github.com/Microsoft/PTVS上提交所有这些内容。 - Pavel Minaev

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