首页 > 解决方案 > 如何通过单击 GUI 中的按钮来创建新的数据图窗口

问题描述

我想在单击按钮时创建一个新窗口。

稍后我将根据输入的数据动态创建窗口。

单击按钮时,生成错误代码如下。

过程完成,退出代码为 -1073740791 (0xC0000409)。

import sys
import numpy as np
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget, QLabel
from PyQt5 import uic

main_ui = uic.loadUiType("GUI_01.ui")[0]


class OptionWindow(QDialog):
    def __init__(self, parent):
        super(OptionWindow, self).__init__(parent)
        option_ui = "GUI_01.ui"
        uic.loadUi(option_ui, self)
        self.show()


class MainWindow(QtWidgets, QMainWindow, main_ui, QPushButton):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.btnclicked1)
        self.pushButton_2.clicked.connect(self.btnclicked2)
        self.pushButton_3.clicked.connect(self.btnclicked3)
        self.pushButton_4.clicked.connect(self.btnclicked4)

    def btnclicked1(self):
        self.setGeometry(2000, 600, 800, 600)
        self.new_window.show()
        self.fig = plt.Figure()
        self.canvas = FigureCanvas(self.fig)
        self.dialog.setWindowModality(Qt.ApplicationModal)
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)
        cb = QComboBox()
        cb.addItem("TEMP")
        cb.addItem("Voltage")
        cb.addItem("Ampere")
        cb.addItem("pH")
        cb.activated[str].connect(self.onComboBoxChanged)
        layout.addWidget(cb)
        self.layout = layout
        self.onComboBoxChanged(cb.currentText())
        plt.show()

    def onComboBoxChanged(self, text):
        if text == "TEMP":
            self.doGraph1()
        elif text == "Voltage":
            self.doGraph2()
        elif text == "Ampere":
            self.doGraph3()
        elif text == "pH":
            self.doGraph4()

    def doGraph1(self):
        x = np.arange(0, 10, 0.5)
        y = np.sin(x)
        self.fig.clear()
        ax = self.fig.add_subplot(111)
        ax.plot(x, y)
        ax.set_xlabel("Time")
        ax.set_ylabel("Temp")
        ax.set_title("TEMP")
        ax.legend()
        self.canvas.draw()

    def btnclicked2(self):
        self.canvas.draw()

    def btnclicked3(self):
        self.canvas.draw()

    def btnclicked4(self):
        self.canvas.draw()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_dialog = MainWindow()
    main_dialog.show()
    # window = WindowClass()
    # window.show()
    plt.show()
    app.exec_()

标签: pythonpyqt

解决方案


我无法重现您的问题,因为您没有包含“GUI_01.ui”文件,但崩溃很可能是由于您matplotlib.pyplot在 PyQt 中使用了该模块。这些模块不混合,pyplot 有它自己的事件循环,它与 Qt 事件循环发生冲突。

如果您从 MatPlotLib 文档中查看此示例,您会发现它们不使用import matplotlib.pyplot as plt. 相反,他们按如下方式导入图from matplotlib.figure import Figure。也不需要plt.show,所以删除这些语句

当我这样做时,您的代码如下所示...

import sys
import numpy as np
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QPushButton, QGridLayout, QWidget, QLabel
from PyQt5 import uic
from matplotlib.figure import Figure

main_ui = uic.loadUiType("GUI_01.ui")[0]


class OptionWindow(QDialog):
    def __init__(self, parent):
        super(OptionWindow, self).__init__(parent)
        option_ui = "GUI_01.ui"
        uic.loadUi(option_ui, self)
        self.show()


class MainWindow(QtWidgets, QMainWindow, main_ui, QPushButton):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.btnclicked1)
        self.pushButton_2.clicked.connect(self.btnclicked2)
        self.pushButton_3.clicked.connect(self.btnclicked3)
        self.pushButton_4.clicked.connect(self.btnclicked4)

    def btnclicked1(self):
        self.setGeometry(2000, 600, 800, 600)
        self.new_window.show()
        self.fig = Figure()
        self.canvas = FigureCanvas(self.fig)
        self.dialog.setWindowModality(Qt.ApplicationModal)
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)
        cb = QComboBox()
        cb.addItem("TEMP")
        cb.addItem("Voltage")
        cb.addItem("Ampere")
        cb.addItem("pH")
        cb.activated[str].connect(self.onComboBoxChanged)
        layout.addWidget(cb)
        self.layout = layout
        self.onComboBoxChanged(cb.currentText())


    def onComboBoxChanged(self, text):
        if text == "TEMP":
            self.doGraph1()
        elif text == "Voltage":
            self.doGraph2()
        elif text == "Ampere":
            self.doGraph3()
        elif text == "pH":
            self.doGraph4()

    def doGraph1(self):
        x = np.arange(0, 10, 0.5)
        y = np.sin(x)
        self.fig.clear()
        ax = self.fig.add_subplot(111)
        ax.plot(x, y)
        ax.set_xlabel("Time")
        ax.set_ylabel("Temp")
        ax.set_title("TEMP")
        ax.legend()
        self.canvas.draw()

    def btnclicked2(self):
        self.canvas.draw()

    def btnclicked3(self):
        self.canvas.draw()

    def btnclicked4(self):
        self.canvas.draw()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_dialog = MainWindow()
    main_dialog.show()
    # window = WindowClass()
    # window.show()
    app.exec_()

你可以试一试。就像我说的,我无法测试自己,因为我缺少“GUI_01.ui”文件。因此,请让您的MRE下次可重现。使其他人可以自己复制粘贴执行代码并自己进行测试。


推荐阅读