Исправить подсветку выбранного элемента в QTreeWidget - PullRequest
1 голос
/ 12 июля 2019

У меня есть QTreeWidget, в котором есть значения, которые я хочу только показать определенное количество десятичных знаков, но сохранить точность для целей расчета.У меня это работает правильно, но выделение выделенных элементов испорчено и показывает белый цвет вокруг нарисованной ячейки.

Как я могу исправить выделение так, чтобы оно было сплошным синим для всей строки?

class InitialDelegate(QtWidgets.QItemDelegate):
    'Changes number of decimal places in gas analysis self.chosen table'
    def __init__(self, decimals, parent=None):
        super().__init__(parent)
        self.nDecimals = decimals
    def paint(self, painter, option, index):
        if index.column() == 1:
            value = index.model().data(index, QtCore.Qt.DisplayRole)
            try:
                number = float(value)
                painter.drawText(option.rect, QtCore.Qt.AlignCenter , "{:.{}f}".format(number, self.nDecimals))
            except:
                QtWidgets.QItemDelegate.paint(self, painter, option, index)
        else:
            QtWidgets.QItemDelegate.paint(self, painter, option, index)

Вот что он производит:

enter image description here

1 Ответ

2 голосов
/ 12 июля 2019

У меня есть 2 наблюдения в его реализации:

  • Если вы хотите изменить только формат отображаемого текста, вам не следует переопределять метод paint(), поскольку он не только рисует текст, но и фон, значки, и т. д. Метод drawDisplay() должен быть переопределен.

  • Если вы собираетесь применить изменение только к столбцу, лучше назначить делегата, используя setItemDelegateForColumn() метод

Учитывая вышеизложенное, решение будет таким:

from PyQt5 import QtCore, QtGui, QtWidgets


class InitialDelegate(QtWidgets.QItemDelegate):
    "Changes number of decimal places in gas analysis self.chosen table"

    def __init__(self, decimals, parent=None):
        super().__init__(parent)
        self.nDecimals = decimals

    def drawDisplay(self, painter, option, rect, text):
        option.displayAlignment = QtCore.Qt.AlignCenter
        try:
            number = float(text)
            text = "{:.{}f}".format(number, self.nDecimals)
        except:
            pass
        super().drawDisplay(painter, option, rect, text)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = QtWidgets.QTreeWidget(columnCount=3)
    delegate = InitialDelegate(2, w)
    w.setItemDelegateForColumn(1, delegate) # <---
    w.setHeaderLabels(["Gas Component", "Molecular Weight", "Mol%"])
    it = QtWidgets.QTreeWidgetItem(["Hexane", "86.1777", ""])
    w.addTopLevelItem(it)
    w.show()
    sys.exit(app.exec_())

Plus:

Если вы хотите сделать то же самое, но с использованием QStyledItemDelegate, тогда решение переопределено initStyleOption():

class InitialDelegate(QtWidgets.QStyledItemDelegate):
    "Changes number of decimal places in gas analysis self.chosen table"

    def __init__(self, decimals, parent=None):
        super().__init__(parent)
        self.nDecimals = decimals

    def initStyleOption(self, option, index):
        super().initStyleOption(option, index)
        option.displayAlignment = QtCore.Qt.AlignCenter
        try:
            text = index.model().data(index, QtCore.Qt.DisplayRole)
            number = float(text)
            option.text = "{:.{}f}".format(number, self.nDecimals)
        except:
            pass
...