【问题标题】:Dynamic Canvas Control动态画布控制
【发布时间】:2020-09-19 03:07:23
【问题描述】:

我想根据选定的 QRadiobutton 更改 Figure。在我的真实代码中,我尝试了各种方法来使用和不使用信号(另外,检查其他主题。)。 为了使它看起来不那么复杂,我重新排列了我的代码以供提问。

我希望有人可以帮助我克服这种情况。

这是我的代码; figure.py

from PyQt5.QtWidgets import*

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas

from matplotlib.figure import Figure

from numpy import arange, sin, cos, pi


class MainCanvas(FigureCanvas):
    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self, QSizePolicy.Expanding, QSizePolicy.Expanding)

        FigureCanvas.updateGeometry(self)

        t = arange(0.0, 5.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s, color="red", linestyle="solid")


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    ui = MainCanvas()
    ui.show()
    sys.exit(app.exec_())

main.py

from PyQt5.QtWidgets import *
from figure import MainCanvas


class RadioButton(QWidget):
    def __init__(self):
        super().__init__()

        self.main_cavnas = MainCanvas()

        self.InitUi()

    def InitUi(self):
        groups = {"Functions": ("Sinus", "Cosines"),
                  "Colors": ("Red", "Green"),
                  "Line Styles": ("Solid", "Dashed")
                  }

        widget_layout = QVBoxLayout()

        main_group = QGroupBox("Operations")
        main_group_layout = QHBoxLayout()

        for group, buttons in groups.items():
            group_box = QGroupBox(group)
            group_layout = QVBoxLayout()
            for button_text in buttons:
                button = QRadioButton(button_text)
                button.setObjectName("radiobutton_%s" % button_text.lower())
                if button_text == "Sinus" or button_text == "Red" or button_text == "Solid":
                    button.setChecked(True)

                group_layout.addWidget(button)

            group_box.setLayout(group_layout)
            main_group_layout.addWidget(group_box)

        main_group.setLayout(main_group_layout)
        widget_layout.addWidget(self.main_cavnas)
        widget_layout.addWidget(main_group)

        self.setLayout(widget_layout)


if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    ui = RadioButton()
    ui.show()
    sys.exit(app.exec_())

【问题讨论】:

  • 你可以使用 matplotlib 的小部件,为你的情况RadioButtons
  • 谢谢你的回答,但我有更复杂的 GUI。我只是把它作为我的问题的基础。您发送的代码无法满足需求。

标签: python python-3.x matplotlib pyqt5


【解决方案1】:

逻辑是检测按钮状态的变化,然后获取信息,清理画布,重绘。

from PyQt5 import QtCore, QtWidgets

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

import numpy as np


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        fig = Figure(figsize=(5, 4), dpi=100)
        self.canvas = FigureCanvas(fig)

        groups = {
            "Functions": (("Sinus", np.sin), ("Cosines", np.cos)),
            "Colors": (("Red", "red"), ("Green", "green")),
            "Line Styles": (("Solid", "solid"), ("Dashed", "dashed")),
        }

        main_group = QtWidgets.QGroupBox("Operations")
        main_group_layout = QtWidgets.QHBoxLayout(main_group)

        self.group_btns = []

        for group_title, v in groups.items():
            group = QtWidgets.QGroupBox(group_title)
            main_group_layout.addWidget(group)
            vlay = QtWidgets.QVBoxLayout(group)
            group_btn = QtWidgets.QButtonGroup(self)
            self.group_btns.append(group_btn)
            for (text, value) in v:
                radio = QtWidgets.QRadioButton(text)
                radio.setProperty("prop", value)
                vlay.addWidget(radio)
                group_btn.addButton(radio)
                if text in ("Sinus", "Red", "Solid"):
                    radio.setChecked(True)

        for group_btn in self.group_btns:
            group_btn.buttonToggled.connect(self.update_canvas)

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.canvas, stretch=1)
        lay.addWidget(main_group)

        self.update_canvas()

    @QtCore.pyqtSlot()
    def update_canvas(self):
        func, color, style = (
            group.checkedButton().property("prop") for group in self.group_btns
        )
        t = np.arange(0.0, 5.0, 0.01)
        s = func(2 * np.pi * t)

        self.canvas.figure.clear()
        ax = self.canvas.figure.subplots()
        ax.plot(t, s, color=color, linestyle=style)
        self.canvas.draw()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ui = Widget()
    ui.show()
    sys.exit(app.exec_())

【讨论】:

  • 感谢您的快速答复。您的代码实际上解决了我的大部分问题。正如我在回答中分享的那样,有什么方法可以对单独的buttons.py 和canvas.py 文件执行此操作吗?
  • @Gokberk 我认为这部分是不可能的,它也可以是一个练习,帮助你理解如何分离逻辑。
  • 我根据你的回答更新了我的代码。但是,我无法弄清楚如何克服发送正弦和余弦函数。有没有其他方法可以做到这一点,或者我错过了什么
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
  • 2012-05-15
  • 1970-01-01
  • 2013-03-26
  • 2021-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多