问题
I want to have a tablewidget that will color some of the rows based on certain conditions and threshold. For example, if the data in one column reaches over 20, it will color the row where that 20 was. What i have only searches through the Qtablewidgetitem and it does not do what I want it to do.
def setmydata(self):
for n, key in enumerate(self.data):
for m, item in enumerate(self.data[key]):
newitem = QtGui.QTableWidgetItem(item)
c = newitem.column() + 2
print c
for items in item:
if newitem.text() >= '20' or newitem.text() == 'WARNING':
newitem.setBackground(QtGui.QBrush(QtCore.Qt.yellow))
else:
pass
self.setItem(m, n, newitem)
回答1:
If your cells contain integers, you should try:
int(newitem.text()) >= 20
回答2:
For an existing table, with data, where you want to iterate over a specific column, you would do something like this:
def process_column(table, processCol=0):
for row in xrange(table.rowCount()):
item = table.item(row, processCol)
text = str(item.text())
if (text.isdigit() and int(text) >= 20) or text == 'WARNING':
item.setBackground(QtGui.QBrush(QtCore.Qt.yellow))
Or to set the whole row color, you would need to loop over the columns to get each row item when there is a match:
def process_column(table, processCol=0):
colCount = table.rowCount()
for row in xrange(table.rowCount()):
item = table.item(row, processCol)
text = str(item.text())
if (text.isdigit() and int(text) >= 20) or text == 'WARNING':
for col in xrange(colCount):
item = table.item(row, col)
item.setBackground(QtGui.QBrush(QtCore.Qt.yellow))
As the other questions have also pointed out, you need to compare int to int, instead of string comparisons. What I have done here is first checked that the cell was actually an int first to make it save. Because if your cell was actually "WARNING", then converting it to an int first would crash.
No matter what, you will need a reference to the QTableWidget
, even if the function is in a different class. That means you will need to set up your signal with a reference to the table ahead of time, if that other class never specifically will know about it. An example of this would be to use a partial
callback that binds the table into it:
from functools import partial
class Foo:
def __init__(self):
self.the_table = QTableWidget()
# create a callback with the table bound as first arg
callback = partial(process_column, self.the_table)
# set some signal that emits a column number
self.process_column_signal.connect(callback)
def some_method(self):
# process column 0
self.process_column_signal.emit(0)
# will get called by process_column_signal with the table
def process_column(table, processCol):
...
回答3:
Joaquin's point is that you are comparing a string (newitem.text()) with another string ('20'). This is an alphabetical comparison -- '3' > '200'
, for example, even though the number 3 < the number 200. The rules you are describing are comparisons between numbers, so you need to convert newitem.text() to a number.
Note that even if you are entering "numbers" into the widget, they are stored and retrieved as strings. int(newitem.text())
turns it back into a number.
来源:https://stackoverflow.com/questions/11956803/retrieving-data-from-columns-qtablewidget