简体   繁体   English

PyQt5 更新嵌套的 QWidgets

[英]PyQt5 updating nested QWidgets

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.我正在尝试编写我的第一个 PyQt 项目的代码,当我从菜单栏中选择“新建模式”选项时,我想更新右侧的文本字段和左侧的 plot。 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).我认为菜单栏中的操作可以正确触发,但触发的功能本身不会正确更新 Canvas 图或 Label(所以最后当我点击创建时没有任何反应)。 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...我尝试了不同版本的 self.update() 并没有真正找到 pyqt 文档中的解决方案,因为我只找到更新普通 QWidget 的解决方案,但我的结构是嵌套的,所以可能只有一个小错误我不太明白……

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.由于我对 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_())

The solution is rather embarrassing - I did not properly connect the Menu Action.解决方案相当尴尬 - 我没有正确连接菜单操作。

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)
        # THIS IS NEW TO UPDATE THE PLOT
        self.draw()

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):
        # THIS IS NEW - THANK YOU MUSICAMENTE
        self.label.setText("Now we will create a pattern")

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()
        # THIS IS NEW TO PROPERLY CONNECT THE MENU ACTION
        self._connectActions()
        
        # 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_())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM