如何将小部件推广到具有不同选择的不同类?
Posted
技术标签:
【中文标题】如何将小部件推广到具有不同选择的不同类?【英文标题】:how to promote widget to different classes with different selection? 【发布时间】:2021-02-15 01:11:38 【问题描述】:我正在使用 pyqt5 在小部件上绘制股票趋势。有时小部件只有一个情节,有时我想有 3 个子情节。我为同一个小部件设计了两个类,如下所示。首先,我将小部件提升到下面的第一类,只有一个情节。稍后当我选择不同的按钮来绘制不同的图时,我想将图更改为具有 3 个子图,这意味着我需要更改小部件的类。是否可以为具有不同选择的相同小部件更改类?或者有没有其他方法?
class gui_stock_oneplot(QWidget):
def __init__(self,parent=None):
QWidget.__init__(self,parent)
self.canvas=FigureCanvas(Figure())
vertical_layout=QVBoxLayout()
vertical_layout.addWidget(self.canvas)
self.canvas.axis1=self.canvas.figure.add_subplot(111)
self.canvas.axis2=self.canvas.axis1.twinx()
self.canvas.axis3=self.canvas.axis1.twinx()
self.canvas.figure.set_facecolor("white") #lightblue
self.setLayout(vertical_layout)
想要将小部件类更改为:
class gui_stock_3plot(QWidget):
def __init__(self,parent=None):
QWidget.__init__(self,parent)
self.canvas=FigureCanvas(Figure())
vertical_layout=QVBoxLayout()
vertical_layout.addWidget(self.canvas)
self.canvas.axis1=self.canvas.figure.add_subplot(311)
self.canvas.axis2=self.canvas.figure.add_subplot(312)
self.canvas.axis3=self.canvas.figure.add_subplot(313)
self.canvas.figure.set_facecolor("white") #lightblue
self.setLayout(vertical_layout)
【问题讨论】:
你的问题不清楚,自己解释清楚。请提供minimal reproducible example 对不起eyllanesc。是的,我的问题不清楚。我不知道怎么问?我是 Pyqt5 的新手。基本上,我设计了一个小部件来绘制区域。我想让同一个小部件灵活地绘制一个子图和 3 个子图。怎么做?我的想法是改变小部件类。谢谢 如果您提供 MRE,也许您可以提供帮助,否则我会走我的路 “promote”是指通过 Designer 中的提升小部件使用自定义类吗?如果是这样,不,你不能:一旦 ui 被实例化,小部件实例被创建,你不能“改变类”实例(这与 PyQt 无关,它是类和实例背后的基本概念任何语言)。如果您创建一个表格,您可以自定义它(子类表格),使其具有 3、4 或更多条腿、宽度和高度,但是一旦创建它,您就无法将其变成直升机。 【参考方案1】:如果通过“提升” OP 意味着在 .ui 中使用自定义小部件,那么答案是否定的,你不能。
显然,OP 有一个 XY 问题,因为他想知道一个可能的解决方案:如何在 2 个类之间切换一个被提升的小部件,而不是背景问题:如何更改自定义小部件中的绘图?
对于根本问题,至少有两种可能的解决方案:
你可以先在同一个小部件中实现所有逻辑,方法是清理图形,然后重新绘制:
class Widget(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout(self)
self.canvas = FigureCanvas(Figure())
layout.addWidget(self.canvas)
def one_plot(self):
self.canvas.figure.clear()
self.canvas.axis1 = self.canvas.figure.add_subplot(111)
self.canvas.axis2 = self.canvas.axis1.twinx()
self.canvas.axis3 = self.canvas.axis1.twinx()
self.canvas.figure.set_facecolor("white") # lightblue
self.canvas.draw()
def three_plot(self):
self.canvas.figure.clear()
self.canvas.axis1 = self.canvas.figure.add_subplot(311)
self.canvas.axis2 = self.canvas.figure.add_subplot(312)
self.canvas.axis3 = self.canvas.figure.add_subplot(313)
self.canvas.figure.set_facecolor("white") # lightblue
self.canvas.draw()
然后只需使用每个函数的 clicked 信号来更改绘图:
self.one_button.clicked.connect(self.foo_widget.one_plot)
self.three_button.clicked.connect(self.foo_widget.three_plot)
另一个解决方案不是推广而是使用 QStackedWidget。逻辑是将每个小部件添加到 QStackedWidget 并通过按钮更改索引。
self.one_widget = gui_stock_oneplot()
one_index = self.stacked_widget.addWidget(self.one_widget)
self.one_button.clicked.connect(
lambda *args, index=one_index: self.stacked_widget.setCurrentIndex(index)
)
self.three_widget = gui_stock_3plot()
three_index = self.stacked_widget.addWidget(self.three_widget)
self.three_button.clicked.connect(
lambda *args, index=three_index: self.stacked_widget.setCurrentIndex(index)
)
【讨论】:
哇,eyllanesc,这令人印象深刻!你让我一整个晚上感觉很好。第一个解决方案对我来说更容易理解。第二种方法我以前从未这样做过,但它非常聪明。这真是太棒了!非常感谢 eyllanesc,非常感谢您的帮助。 我想的另一个解决方案是不要在要提升的类中定义任何子图。相反,我可以在主程序中添加子图吗?例如 self.widgetPlot.canvas.axis1=self.widgetPlot.canvas.figure.add_subplot(311) self.widgetPlot.canvas.axis2=self.widgetPlot.canvas.figure.add_subplot(312)以上是关于如何将小部件推广到具有不同选择的不同类?的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 如何将小部件扩展为具有更多内容的更大小部件?