2017-10-03 2 views
1

Ich habe ein Problem beim Festlegen der Hintergrundfarbe eines QWidgetItem basierend auf einem geänderten Wert.PyQt - Blink Hintergrundfarbe basierend auf Wertaktualisierung

Ich habe die folgende Einrichtung, die einfach Zufallszahlen in einem QTableWidget basierend auf einem Klick einer Schaltfläche generiert.

Ich möchte es machen, dass der Hintergrund einer Zelle ändert sich basierend, ob der neue Wert höher oder niedriger als der alte Wert ist. Wenn zum Beispiel der neue Wert höher ist, blinken Sie für eine Sekunde (oder eine halbe Sekunde) blau oder wenn der neue Wert niedriger ist, um für einige Zeit gelb zu blinken.

Ich bin ziemlich verloren, wo in diesem Prozess zu starten.

Vielen Dank

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_()) 

Antwort

1

Es gibt wahrscheinlich viele verschiedene Wege, dies zu implementieren. Eine Möglichkeit besteht darin, eine Unterklasse von QTableWidgetItem zu erstellen und die -Methode zu überschreiben. Dadurch können Sie überwachen, welche Werte sich für eine bestimmte item data role ändern. (Wenn Sie ein Signal wie QTableWidgem.itemChanged() verwendet haben, wäre dies nicht möglich, weil es Ihnen die Rolle nicht gibt).

Die einzige Sache, die dabei zu beachten ist, ist, dass sie nur Änderungen überwachen kann nach das Element wurde in die Tabelle aufgenommen. Daher müssen Sie zuerst leere Elemente hinzufügen und anschließend alle Werte aktualisieren.

Der Mechanismus zum Ändern der Hintergrundfarbe ist viel einfacher, da es nur eine single-shot timer erfordert.

Hier ist eine Demo von all oben auf dem Beispiel basiert:

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_()) 
+0

Vielen Dank für die schöne Methode und klare Erklärung. Genau das, was ich gebraucht habe und werde auch die Referenzen studieren, die du gegeben hast. Prost! –

Verwandte Themen