matplotlib 在调试 PyQt5 应用程序时显示空白图。

huangapple go评论181阅读模式
英文:

matplotlib giving empty figure during debugging of a pyqt5 app

问题

我从1中学到了如何在运行PyQt5应用程序并使用断点时避免以下错误消息:

> QCoreApplication::exec: The event loop is already running

这对于在控制台中进行打印操作很有效,但如果我在断点期间运行matplotlib的plt.show(),那么我会收到上面的消息并获得一个空的图形。

有什么办法可以解决这个问题吗?

已解决:将plt.show()替换为plt.pause(0.01)。感谢 @jared。

下面是一个完整的示例代码。通过点击按钮触发断点,我在断点下面的注释中说明了我在控制台上键入的内容,以获得空的图形。

import sys
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QPushButton, QLabel

class MainWindow(QMainWindow):
    """Class main window."""

    def __init__(self):
        super().__init__()

        self.setWindowTitle('test')
        self.widget = QWidget()

        box = QHBoxLayout()
        self.widget.setLayout(box)
        self.lbl = QLabel('Hello')
        box.addWidget(self.lbl)

        self.btn = QPushButton('Push to breakpoint')
        box.addWidget(self.btn)
        self.btn.clicked.connect(self.run_script1)

        self.setCentralWidget(self.widget)

    def run_script1(self):
        breakpoint()
        #import matplotlib.pyplot as plt
        #plt.plot([1,2,3])
        #plt.show() / should be: plt.pause(0.01)

    def exit_app(self):
        """Exit app by menu."""
        sys.exit()

def prepare_debug():
    """Set a tracepoint in PDB that works with Qt."""
    # https://stackoverflow.com/questions/1736015/debugging-a-pyqt4-app
    from PyQt5.QtCore import pyqtRemoveInputHook
    import pdb
    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 user invoked `pyqt_set_trace()`
    debugger.interaction(users_frame, None)

if __name__ == '__main__':
    prepare_debug()
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec()
英文:

I learned from
https://stackoverflow.com/questions/1736015/debugging-a-pyqt4-app
how to be able to avoid the

> QCoreApplication::exec: The event loop is already running

when running a PyQt5 application and using breakpoints. This works fine for doing prints to the console, but I still have trouble if I want to run matplotlib plt.show() during that breakpoint. Then I get the message above and just an empty figure.

Any idea how to overcome that?

Solved: replace plt.show() with plt.pause(0.01). Thank you @jared.

Below is a full example code. The breakpoint is triggered by pushing the button and I have commented under the breakpoint what I am typing on the console to get the empty figure.

import sys

from PyQt5 import QtWidgets
from PyQt5.QtWidgets import (
    QMainWindow, QWidget, QHBoxLayout, QPushButton, QLabel
    )

class MainWindow(QMainWindow):
    """Class main window."""

    def __init__(self):
        super().__init__()

        self.setWindowTitle('test')
        self.widget = QWidget()

        box = QHBoxLayout()
        self.widget.setLayout(box)
        self.lbl = QLabel('Hello')
        box.addWidget(self.lbl)

        self.btn = QPushButton('Push to breakpoint')
        box.addWidget(self.btn)
        self.btn.clicked.connect(self.run_script1)

        self.setCentralWidget(self.widget)

    def run_script1(self):
        breakpoint()
        #import matplotlib.pyplot as plt
        #plt.plot([1,2,3])
        #plt.show() / should be: plt.pause(0.01)

    def exit_app(self):
        """Exit app by menu."""
        sys.exit()

def prepare_debug():
    """Set a tracepoint in PDB that works with Qt."""
    # https://stackoverflow.com/questions/1736015/debugging-a-pyqt4-app
    from PyQt5.QtCore import pyqtRemoveInputHook
    import pdb
    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 user invoked `pyqt_set_trace()`
    debugger.interaction(users_frame, None)

if __name__ == '__main__':
    prepare_debug()
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    app.exec()

答案1

得分: 0

在调试时,如果您想显示一个pyplot图形,可以使用plt.pause(0.01)命令(时间实际上并不重要)。根据文档

如果存在活动图形,它将在暂停之前更新并显示,并且在暂停期间将运行GUI事件循环(如果有的话)。

如果您想了解pauseshow之间的区别,文档中包含了它们的源代码链接。为了方便起见,我在下面包含了这些链接。

英文:

While debugging, if you want to show a pyplot figure, you can use the plt.pause(0.01) command (the time doesn't really matter). As per the documentation,

> If there is an active figure, it will be updated and displayed before the pause, and the GUI event loop (if any) will run during the pause.

If you're interested in understanding the difference between pause and show, the documentation includes the links to their source code. For convenience, I have included those links below.

huangapple
  • 本文由 发表于 2023年6月29日 04:11:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76576433.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定