PyQt5 更新嵌套 QWidget
我正在尝试编写我的第一个 PyQt 项目,并且当我从菜单栏中选择“新模式”选项时,想要更新右侧的文本字段和左侧的绘图。我认为菜单栏上的操作正确触发,但触发的函数本身没有正确更新画布图形或标签(所以最终当我单击创建时什么也没有发生)。我尝试了不同版本的 self.update() ,但并没有真正找到 pyqt 文档中的解决方案,因为我只找到更新普通 QWidget 的解决方案,但我的结构是嵌套的,所以也许只有一个小错误我不太明白...
我也希望对我的代码风格有任何帮助或反馈,因为我对 Python 或 PyQt 本身不太熟悉。
import sys
import numpy as np
from screeninfo import get_monitors
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenuBar, QAction, QHBoxLayout, QVBoxLayout, QWidget, QLabel
from PyQt5.QtGui import QPalette, QColor
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
# grid class
class Grid(FigureCanvasQTAgg):
def __init__(self, parent = None, width = 5, height = 5, dpi = 120):
fig = Figure(figsize=(width, height), dpi=dpi)
self.ax = fig.add_subplot()
self.ax.set_ylim(-8.75, 8.75)
self.ax.set_xlim(-8.75, 8.75)
ticks = list(range(-8, 9))
self.ax.xaxis.set_ticks(ticks)
self.ax.yaxis.set_ticks(ticks)
self.ax.grid(visible = True)
self.ax.set_axisbelow(True)
self.ax.tick_params(axis='both', which='both', length=0, labeltop=True, labelright=True)
self.ax.set_aspect('equal')
for spine in self.ax.spines.values():
spine.set_visible(False)
self.title_font_ = {'fontsize': 16, 'fontweight': "normal", 'color': "black",
'verticalalignment': "center", 'horizontalalignment': "center"}
self.ax.set_title("Grid Title", fontdict = self.title_font_, pad = 35)
self.circles = []
super(Grid, self).__init__(fig)
def createPattern(self, dots = 8, unified = True):
self.dots = dots
self.unified = unified
# change title
self.ax.set_title("Add Pattern", fontdict = self.title_font_, pad = 35)
x = list(range(-8, -8+dots))
y = [8.01]*dots
if self.unified:
coord = np.array(list(map(list, zip(x, y))))
for i in range(self.pairs):
circ = self.ax.add_patch(plt.Circle((coord[i,0], coord[i,1]), 0.35, color="royalblue"))
self.circles.append(circ)
else:
xw = list(range(1, 1+dots))
coord_blue = np.array(list(map(list, zip(x, y))))
coord_pink = np.array(list(map(list, zip(xw, y))))
for i in range(dots):
circ = self.ax.add_patch(plt.Circle((coord_pink[i,0], coord_pink[i,1]), 0.35, color="deeppink"))
self.circles.append(circ)
for i in range(dots):
circ = self.ax.add_patch(plt.Circle((coord_blue[i,0], coord_blue[i,1]), 0.35, color="deepskyblue"))
self.circles.append(circ)
class Side(QWidget):
def __init__(self, color):
super(Side, self).__init__()
# background color
self.setAutoFillBackground(True)
palette = self.palette()
palette.setColor(QPalette.Window, QColor(color))
self.setPalette(palette)
# add layout and text
self.layout = QVBoxLayout()
self.label = QLabel("Welcome to My first program")
self.layout.addWidget(self.label)
self.setLayout(self.layout)
def createPattern(self):
self.label = QLabel("Now we will create a pattern")
#self.update() ??
#super(Side, self).update() ??
class MainWindow(QMainWindow):
def __init__(self, parent = None):
super().__init__(parent)
screen = get_monitors()[0]
self.setGeometry(int(screen.width*0.125), int(screen.height*0.125),
int(screen.width*0.75), int(screen.height*0.75))
self.setWindowTitle("My Program")
self._createActions()
self._createMenuBar()
# a figure instance to plot on
self.grid = Grid(width=8, height=8, dpi=140)
# a side panel
self.side = Side('white')
self.centralwidget = QWidget()
self.setCentralWidget(self.centralwidget)
self.layout = QHBoxLayout(self.centralwidget)
self.layout.addWidget(self.grid, 55)
self.layout.addWidget(self.side, 45)
def _createActions(self):
self.newPatternAction = QAction("&New Pattern", self)
def _createMenuBar(self):
menuBar = QMenuBar(self)
self.setMenuBar(menuBar)
patternMenu = menuBar.addMenu("&Pattern")
patternMenu.addAction(self.newPatternAction)
def _connectActions(self):
self.newPatternAction.triggered.connect(self.newPattern)
def newPattern(self):
# Logic for creating a new file goes here...
self.grid.createPattern()
self.side.createPattern()
def window():
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(True)
win = MainWindow()
win.show()
sys.exit(app.exec_())
I am trying to code my first PyQt project and want to update both the textfield on the right and the plot on the left when I choose the New Pattern option from the menu bar. I think that the actions from the menu bar trigger correctly but the triggered functions themselves do not update the Canvas Figure or Label correctly (so in the end nothing happens when I click the create). I tried different versions of self.update() and do not really find my way around to the solution in the pyqt documentation, as I only find solutions to updating a normal QWidget but my structure is nested, so maybe there is just one tiny mistake that I am not quite getting...
I would appreciate any help or feedback to the style of my code as well since I am not too familiar with Python or PyQt itself.
import sys
import numpy as np
from screeninfo import get_monitors
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenuBar, QAction, QHBoxLayout, QVBoxLayout, QWidget, QLabel
from PyQt5.QtGui import QPalette, QColor
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
# grid class
class Grid(FigureCanvasQTAgg):
def __init__(self, parent = None, width = 5, height = 5, dpi = 120):
fig = Figure(figsize=(width, height), dpi=dpi)
self.ax = fig.add_subplot()
self.ax.set_ylim(-8.75, 8.75)
self.ax.set_xlim(-8.75, 8.75)
ticks = list(range(-8, 9))
self.ax.xaxis.set_ticks(ticks)
self.ax.yaxis.set_ticks(ticks)
self.ax.grid(visible = True)
self.ax.set_axisbelow(True)
self.ax.tick_params(axis='both', which='both', length=0, labeltop=True, labelright=True)
self.ax.set_aspect('equal')
for spine in self.ax.spines.values():
spine.set_visible(False)
self.title_font_ = {'fontsize': 16, 'fontweight': "normal", 'color': "black",
'verticalalignment': "center", 'horizontalalignment': "center"}
self.ax.set_title("Grid Title", fontdict = self.title_font_, pad = 35)
self.circles = []
super(Grid, self).__init__(fig)
def createPattern(self, dots = 8, unified = True):
self.dots = dots
self.unified = unified
# change title
self.ax.set_title("Add Pattern", fontdict = self.title_font_, pad = 35)
x = list(range(-8, -8+dots))
y = [8.01]*dots
if self.unified:
coord = np.array(list(map(list, zip(x, y))))
for i in range(self.pairs):
circ = self.ax.add_patch(plt.Circle((coord[i,0], coord[i,1]), 0.35, color="royalblue"))
self.circles.append(circ)
else:
xw = list(range(1, 1+dots))
coord_blue = np.array(list(map(list, zip(x, y))))
coord_pink = np.array(list(map(list, zip(xw, y))))
for i in range(dots):
circ = self.ax.add_patch(plt.Circle((coord_pink[i,0], coord_pink[i,1]), 0.35, color="deeppink"))
self.circles.append(circ)
for i in range(dots):
circ = self.ax.add_patch(plt.Circle((coord_blue[i,0], coord_blue[i,1]), 0.35, color="deepskyblue"))
self.circles.append(circ)
class Side(QWidget):
def __init__(self, color):
super(Side, self).__init__()
# background color
self.setAutoFillBackground(True)
palette = self.palette()
palette.setColor(QPalette.Window, QColor(color))
self.setPalette(palette)
# add layout and text
self.layout = QVBoxLayout()
self.label = QLabel("Welcome to My first program")
self.layout.addWidget(self.label)
self.setLayout(self.layout)
def createPattern(self):
self.label = QLabel("Now we will create a pattern")
#self.update() ??
#super(Side, self).update() ??
class MainWindow(QMainWindow):
def __init__(self, parent = None):
super().__init__(parent)
screen = get_monitors()[0]
self.setGeometry(int(screen.width*0.125), int(screen.height*0.125),
int(screen.width*0.75), int(screen.height*0.75))
self.setWindowTitle("My Program")
self._createActions()
self._createMenuBar()
# a figure instance to plot on
self.grid = Grid(width=8, height=8, dpi=140)
# a side panel
self.side = Side('white')
self.centralwidget = QWidget()
self.setCentralWidget(self.centralwidget)
self.layout = QHBoxLayout(self.centralwidget)
self.layout.addWidget(self.grid, 55)
self.layout.addWidget(self.side, 45)
def _createActions(self):
self.newPatternAction = QAction("&New Pattern", self)
def _createMenuBar(self):
menuBar = QMenuBar(self)
self.setMenuBar(menuBar)
patternMenu = menuBar.addMenu("&Pattern")
patternMenu.addAction(self.newPatternAction)
def _connectActions(self):
self.newPatternAction.triggered.connect(self.newPattern)
def newPattern(self):
# Logic for creating a new file goes here...
self.grid.createPattern()
self.side.createPattern()
def window():
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setQuitOnLastWindowClosed(True)
win = MainWindow()
win.show()
sys.exit(app.exec_())
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解决方案令人尴尬 - 我没有正确连接菜单动作。
The solution is rather embarrassing - I did not properly connect the Menu Action.