【问题标题】:PyQt - Blink Background Color based on Value UpdatePyQt - 基于值更新闪烁背景颜色
【发布时间】:2017-10-03 15:14:54
【问题描述】:

我在根据更改的值设置 QWidgetItem 的背景颜色时遇到问题。

我有以下设置,它只是基于单击按钮将随机数生成到 QTableWidget 中。

我想让单元格的背景根据新值高于或低于旧值而改变。例如,如果新值较高,则闪烁蓝色一秒钟(或半秒),或者如果新值较低,则闪烁/闪烁黄色一段时间。

我不知道从哪里开始这个过程。

非常感谢

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
from random import randint

class App(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(100, 100, 350, 380)
        self.createTable()
        self.button = QPushButton('Update Values', self)
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.tableWidget)
        self.layout.addWidget(self.button)
        self.setLayout(self.layout)
        self.button.clicked.connect(self.on_click)
        self.show()

    def createTable(self):
        self.tableWidget = QTableWidget()
        self.nrows=10
        self.ncols=3
        self.tableWidget.setRowCount(self.nrows)
        self.tableWidget.setColumnCount(self.ncols)

        for i in range(self.nrows):
            for j in range(self.ncols):
                self.tableWidget.setItem(i, j, QTableWidgetItem('{}'.format(randint(0,9))))

        self.tableWidget.move(0,0)
        self.tableWidget.doubleClicked.connect(self.on_click)

    @pyqtSlot()
    def on_click(self):
        for i in range(self.nrows):
            for j in range(self.ncols):
                self.tableWidget.setItem(i, j, QTableWidgetItem('{}'.format(randint(0,9))))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt5 qtablewidget


    【解决方案1】:

    可能有许多不同的方法来实现这一点。一种方法是创建QTableWidgetItem 的子类并覆盖setData 方法。这将允许您监视特定 item data role 的哪些值正在更改。 (如果你使用像QTableWidgem.itemChanged() 这样的信号,这是不可能的,因为它没有给你角色)。

    以这种方式做事的唯一要记住的是,它只能在项目添加到表格后监控更改。因此,您需要先添加空白项,然后再更新所有值。

    改变背景颜色的机制要简单得多,因为它只需要一个single-shot timer

    这是基于您的示例的上述所有内容的演示:

    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import QIcon, QColor
    from PyQt5.QtCore import pyqtSlot, Qt, QTimer
    from random import randint
    
    class TableWidgetItem(QTableWidgetItem):
        def setData(self, role, value):
            if role == Qt.DisplayRole:
                try:
                    newvalue = int(value)
                    oldvalue = int(self.data(role))
                except (ValueError, TypeError):
                    pass
                else:
                    if newvalue != oldvalue:
                        if newvalue > oldvalue:
                            color = QColor('aliceblue')
                        elif newvalue < oldvalue:
                            color = QColor('lightyellow')
                        def update_background(color=None):
                            super(TableWidgetItem, self).setData(
                                Qt.BackgroundRole, color)
                        update_background(color)
                        QTimer.singleShot(2000, update_background)
                super(TableWidgetItem, self).setData(role, value)
    
    class App(QWidget):
        def __init__(self):
            super().__init__()
            self.initUI()
    
        def initUI(self):
            self.setGeometry(700, 100, 350, 380)
            self.createTable()
            self.button = QPushButton('Update Values', self)
            self.layout = QVBoxLayout()
            self.layout.addWidget(self.tableWidget)
            self.layout.addWidget(self.button)
            self.setLayout(self.layout)
            self.button.clicked.connect(self.populateTable)
            self.show()
    
        def createTable(self):
            self.tableWidget = QTableWidget()
            self.nrows=10
            self.ncols=3
            self.tableWidget.setRowCount(self.nrows)
            self.tableWidget.setColumnCount(self.ncols)
    
            for i in range(self.nrows):
                for j in range(self.ncols):
                    self.tableWidget.setItem(i, j, TableWidgetItem())
    
            self.tableWidget.move(0,0)
            self.tableWidget.doubleClicked.connect(self.populateTable)
            self.populateTable()
    
        @pyqtSlot()
        def populateTable(self):
            for i in range(self.nrows):
                for j in range(self.ncols):
                    self.tableWidget.item(i, j).setText('{}'.format(randint(0,9)))
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = App()
        sys.exit(app.exec_())
    

    【讨论】:

    • 非常感谢您提供的好方法和清晰的解释。正是我需要的,也会研究你提供的参考资料。干杯!
    猜你喜欢
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    相关资源
    最近更新 更多