Получение данных из столбцов qtablewidget

Я хочу иметь табличный виджет, который будет окрашивать некоторые строки в зависимости от определенных условий и порога. Например, если данные в одном столбце превышают 20, они окрашивают строку, в которой было это 20. То, что у меня есть, только ищет через Qtablewidgetitem и не делает то, что я хочу.

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)

person Community    schedule 14.08.2012    source источник
comment
newitem.text() ›= '20' вы сравниваете не числа, а только строки   -  person joaquin    schedule 14.08.2012


Ответы (3)


Если ваши ячейки содержат целые числа, вы должны попробовать:

int(newitem.text()) >= 20
person joaquin    schedule 14.08.2012
comment
Но в другом столбце есть целые числа с другим масштабом (например, я хочу, чтобы они были окрашены, когда целые числа превышают девять). - person ; 14.08.2012
comment
Однако в таблице есть как целые числа, так и строки, хотя лучше всего было бы просто искать по столбцам и выполнять newitem.text с выбранным столбцом. - person ; 14.08.2012

Для существующей таблицы с данными, где вы хотите выполнить итерацию по определенному столбцу, вы должны сделать что-то вроде этого:

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

Или, чтобы установить цвет всей строки, вам нужно будет перебрать столбцы, чтобы получить каждый элемент строки, когда есть совпадение:

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

Как указывалось и в других вопросах, вам нужно сравнивать int с int вместо сравнения строк. Что я сделал здесь, так это сначала проверил, что ячейка на самом деле была int, чтобы сохранить ее. Потому что, если ваша ячейка на самом деле была «ПРЕДУПРЕЖДЕНИЕ», то сначала преобразование ее в int приведет к сбою.

В любом случае вам понадобится ссылка на QTableWidget, даже если функция находится в другом классе. Это означает, что вам нужно будет заранее настроить свой сигнал со ссылкой на таблицу, если этот другой класс никогда конкретно не узнает об этом. Примером этого может быть использование обратного вызова partial, который привязывает к нему таблицу:

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):
    ...
person jdi    schedule 15.08.2012
comment
Хорошо, все работает, кроме случаев, когда предполагается установить фон строки, он говорит AttributeError: 'QString' object has no attribute 'setBackground'. Спасибо! - person ; 17.08.2012
comment
Ха. Упс. Это была опечатка. Предполагалось, что это будет item.setBackground, а не текстовое значение. Исправлено. - person jdi; 17.08.2012
comment
Эй, а можно как-нибудь раскрасить весь ряд? - person ; 17.08.2012

Суть Хоакина в том, что вы сравниваете строку (newitem.text()) с другой строкой ('20'). Это алфавитное сравнение — например, '3' > '200', хотя число 3 ‹ число 200. Правила, которые вы описываете, представляют собой сравнение между числами, поэтому вам нужно преобразовать newitem.text() в число.

Обратите внимание, что даже если вы вводите «числа» в виджет, они сохраняются и извлекаются в виде строк. int(newitem.text()) превращает его обратно в число.

person ChrisB    schedule 14.08.2012
comment
Да, но мой вопрос в том, как я могу получить данные из отдельных столбцов, а затем обработать данные? - person ; 14.08.2012
comment
Что data вы имеете в виду? QTableWidgetItems внутри QTableWidget? Текст внутри QTableWidgetItem? Пользовательские данные, которые вы сохранили в QTableWidgetItem через setData? - person ChrisB; 14.08.2012
comment
Текст внутри QTableWidgetitem, например, если бы у меня было 3 столбца, a b c, я хочу выбрать a и его данные и обработать их, затем b, затем c. - person ; 14.08.2012
comment
Вы используете QTableWidgetItem.text() так же, как в вашем примере. Используйте QTableWidget.item(i, j).text(), чтобы получить текст, хранящийся в строке i, столбце j в таблице. Используйте int(), чтобы превратить его в число. Повторяйте по мере необходимости, чтобы захватить то, что вам нужно. riverbankcomputing.co.uk/static/Docs/PyQt4/html/ - person ChrisB; 15.08.2012
comment
Я не могу использовать это, так как мой qtablewidget находится в другом классе. И когда я пытаюсь вызвать qtablewidget в другом классе, он говорит, что у класса нет атрибута qtablewidget - person ; 15.08.2012