刷新布局并更新数据

2024-01-09

我有以下显示数据网格的 pyqt 代码。

我能够单击一个字母,打开一个文本输入框并成功将数据保存到网格并在终端中打印更新的数据。

我努力了update() and repaint()但他们什么也没做,并打电话给createLayout()方法抛出错误QLayout: Attempting to add QLayout "" to Widget "", which already has a layout

如何刷新网格/小部件/布局以显示新数据?

from PyQt5 import QtWidgets, QtCore, QtGui
import string

grid = [[["text", "GREEN"], 0, ["text", "RED"], 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0]]

BTN = """QPushButton{{font-weight: bold; color: {};
        font-size: 14px; background-color: {}; 
        border-width: 2px; border-radius: 100px}}"""


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

        self.letter_count = dict(zip(string.ascii_uppercase, [x for x in range(26)]))

        self.initUI()
        self.createLayout()
        self.center_widget()

    def initUI(self):
        p = self.palette()
        gradient = QtGui.QLinearGradient(0, 0, 0, 400)
        gradient.setColorAt(0.0, QtGui.QColor('#f1f1f1'))
        gradient.setColorAt(1.0, QtGui.QColor('#00a1de'))
        p.setBrush(QtGui.QPalette.Window, QtGui.QBrush(gradient))
        self.setPalette(p)

    def createLayout(self):
        hlay = QtWidgets.QHBoxLayout(self)
        frameL = QtWidgets.QFrame()

        vlay = QtWidgets.QVBoxLayout(frameL)
        frame = QtWidgets.QFrame()
        frame.setObjectName("principal")
        frame.setStyleSheet("#principal{border: 2px solid white;}")
        hlay.addWidget(frameL)
        hlay.addWidget(frame)

        gridLayout = QtWidgets.QGridLayout(frame)

        h = 60  # height

        for i, row in enumerate(grid):
            letter = "{}".format(string.ascii_uppercase[i])
            frameButton = QtWidgets.QFrame()
            frameButton.setFixedHeight(h)
            frameButton.setContentsMargins(0, 0, 0, 0)
            lay = QtWidgets.QVBoxLayout(frameButton)
            button = QtWidgets.QPushButton(letter)
            button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
            button.clicked.connect(lambda x, letter=letter: self.populate_row(letter)) # Every button click returns 'J'
            lay.addWidget(button)
            vlay.addWidget(frameButton)
            for j, val in enumerate(row):
                gridButton = QtWidgets.QPushButton()
                gridButton.setFixedSize(h, h)
                if isinstance(val, list):
                    gridButton.setText(val[0])
                    if val[1] == "GREEN":
                        gridButton.setStyleSheet(BTN.format('white', 'green'))
                    elif val[1] == "RED":
                        gridButton.setStyleSheet(BTN.format('white', 'red'))
                else:
                    gridButton.setStyleSheet(BTN.format('black', 'white'))
                    gridButton.setText("{}".format(val))
                gridLayout.addWidget(gridButton, i, j)

        for ix in range(j + 1):
            label = QtWidgets.QLabel("{}".format(ix + 1))
            label.setAlignment(QtCore.Qt.AlignCenter)
            gridLayout.addWidget(label, i + 1, ix)
        vlay.addWidget(QtWidgets.QLabel())

    def center_widget(self):
        self.window().setGeometry(
            QtWidgets.QStyle.alignedRect(
                QtCore.Qt.LeftToRight,
                QtCore.Qt.AlignCenter,
                self.window().size(),
                QtWidgets.QApplication.desktop().availableGeometry())
        )

    def populate_row(self, letter):
        """ Populate the row from index 0 - end """
        print(letter)
        self.wi = QtWidgets.QWidget()
        self.wi.resize(660, 360)
        textBox = QtWidgets.QPlainTextEdit(self.wi)
        Rbtn = QtWidgets.QPushButton('Add To Row')
        Rbtn.clicked.connect(lambda: self.input_to_grid(textBox.toPlainText(), letter))       

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(textBox)
        layout.addWidget(Rbtn)

        Rbtn.move(600, 300)

        self.wi.setLayout(layout)

        self.wi.show()
        return self.wi

    def input_to_grid(self, text, letter):
        print(text, letter)
        lst = text.split(' ')
        for i, x in enumerate(lst):
            self.add_to_grid((letter, i + 1), x)
            print((letter, i + 1), x)
        self.print_grid()


    def add_to_grid(self, loc, item):
        x, y = self.translate(loc)
        grid[x][y] = [item] 

    def translate(self, loc):
        for k, v in self.letter_count.items():
            if loc[0].upper() == k:
                x = v
        y = int(loc[1]) - 1
        return x, y

    def print_grid(self):
        """ Print the grid prettier than normal.. """
        print('\n'.join(['\t'.join([str(c) for c in r]) for r in grid]))


if __name__ == '__main__':
    import sys

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

替换布局或小部件是一个坏主意,因为浪费了时间和内存,正确的做法是重用,在这种情况下,我将创建一个映射按钮的列表列表,因此当您想要更新中的某些数据时grid 中的数据将在按钮中更新。

from PyQt5 import QtWidgets, QtCore, QtGui
import string

grid = [[["text", "GREEN"], 0, ["text", "RED"], 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0]]

BTN = """QPushButton{{font-weight: bold; color: {};
        font-size: 14px; background-color: {}; 
        border-width: 2px; border-radius: 100px}}"""


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

        self.letter_count = dict(zip(string.ascii_uppercase, [x for x in range(26)]))

        self.initUI()
        self.buttons = []
        self.createLayout()
        self.center_widget()

    def initUI(self):
        p = self.palette()
        gradient = QtGui.QLinearGradient(0, 0, 0, 400)
        gradient.setColorAt(0.0, QtGui.QColor('#f1f1f1'))
        gradient.setColorAt(1.0, QtGui.QColor('#00a1de'))
        p.setBrush(QtGui.QPalette.Window, QtGui.QBrush(gradient))
        self.setPalette(p)

    def createLayout(self):
        hlay = QtWidgets.QHBoxLayout(self)
        frameL = QtWidgets.QFrame()

        vlay = QtWidgets.QVBoxLayout(frameL)
        frame = QtWidgets.QFrame()
        frame.setObjectName("principal")
        frame.setStyleSheet("#principal{border: 2px solid white;}")
        hlay.addWidget(frameL)
        hlay.addWidget(frame)

        self.gridLayout = QtWidgets.QGridLayout(frame)

        h = 60  # height

        for i, row in enumerate(grid):
            letter = "{}".format(string.ascii_uppercase[i])
            frameButton = QtWidgets.QFrame()
            frameButton.setFixedHeight(h)
            frameButton.setContentsMargins(0, 0, 0, 0)
            lay = QtWidgets.QVBoxLayout(frameButton)
            button = QtWidgets.QPushButton(letter)
            button.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
            button.clicked.connect(lambda x, letter=letter: self.populate_row(letter)) # Every button click returns 'J'
            lay.addWidget(button)
            vlay.addWidget(frameButton)
            self.buttons.append([])
            for j, val in enumerate(row):
                gridButton = QtWidgets.QPushButton()
                gridButton.setFixedSize(h, h)
                self.buttons[i].append(gridButton)
                self.gridLayout.addWidget(gridButton, i, j)
        for ix in range(j + 1):
            label = QtWidgets.QLabel("{}".format(ix + 1))
            label.setAlignment(QtCore.Qt.AlignCenter)
            self.gridLayout.addWidget(label, i + 1, ix)
        vlay.addWidget(QtWidgets.QLabel())
        self.update_data()


    def update_data(self):
        for i, row in enumerate(grid):
            for j, val in enumerate(row):
                btn = self.buttons[i][j]
                if isinstance(val, list):
                    btn.setText(val[0])
                    if val[1] == "GREEN":
                        btn.setStyleSheet(BTN.format('white', 'green'))
                    elif val[1] == "RED":
                        btn.setStyleSheet(BTN.format('white', 'red'))
                else:
                    btn.setStyleSheet(BTN.format('black', 'white'))
                    btn.setText("{}".format(val))


    def center_widget(self):
        self.window().setGeometry(
            QtWidgets.QStyle.alignedRect(
                QtCore.Qt.LeftToRight,
                QtCore.Qt.AlignCenter,
                self.window().size(),
                QtWidgets.QApplication.desktop().availableGeometry())
        )

    def populate_row(self, letter):
        dialog = QtWidgets.QDialog()
        dialog.resize(660, 360)
        textBox = QtWidgets.QPlainTextEdit(dialog)
        Rbtn = QtWidgets.QPushButton('Add To Row')
        Rbtn.clicked.connect(lambda: self.input_to_grid(textBox.toPlainText(), letter))       

        layout = QtWidgets.QVBoxLayout(dialog)
        layout.addWidget(textBox)
        layout.addWidget(Rbtn)
        dialog.exec_()

    def input_to_grid(self, text, letter):
        print(text, letter)
        lst = text.split(' ')
        for i, x in enumerate(lst):
            self.add_to_grid((letter, i + 1), x)
            print((letter, i + 1), x)
        self.print_grid()
        self.update_data()

    def add_to_grid(self, loc, item):
        x, y = self.translate(loc)
        grid[x][y] = item

    def translate(self, loc):
        for k, v in self.letter_count.items():
            if loc[0].upper() == k:
                x = v
        y = int(loc[1]) - 1
        return x, y

    def print_grid(self):
        """ Print the grid prettier than normal.. """
        print('\n'.join(['\t'.join([str(c) for c in r]) for r in grid]))


if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

刷新布局并更新数据 的相关文章

随机推荐