Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为PySide QTreeWidget中的行设置背景_Python_Qt_Pyside_Qstyleditemdelegate - Fatal编程技术网

Python 为PySide QTreeWidget中的行设置背景

Python 为PySide QTreeWidget中的行设置背景,python,qt,pyside,qstyleditemdelegate,Python,Qt,Pyside,Qstyleditemdelegate,我从a的答案开始,但它似乎不起作用。所有行都呈现相同的颜色 我创建了一个主窗口类 import sys from PySide import QtCore, QtGui class MainWindow(QtGui.QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.settingsTree = SettingsTre

我从a的答案开始,但它似乎不起作用。所有行都呈现相同的颜色

我创建了一个主窗口类

import sys

from PySide import QtCore, QtGui

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.settingsTree = SettingsTree()
        self.setCentralWidget(self.settingsTree)

        self.locationDialog = None

        # self.autoRefreshAct.setChecked(True)
        # self.fallbacksAct.setChecked(True)

        self.setWindowTitle("Test")
        self.resize(500, 600)
        self.setTreeDataObject(ItemManifest())
        self.settingsTree.setItemDelegate(SelectionColorDelegate(self.settingsTree))

    def setTreeDataObject(self, treeData):
        self.settingsTree.setTreeDataObject(treeData)

        # self.refreshAct.setEnabled(True)
        # self.autoRefreshAct.setEnabled(True)
ItemManifest用于保存特定于列表项的数据(不确定这是Qt的工作方式)

这是我的实际树小部件,有三列:

class SettingsTree(QtGui.QTreeWidget):
    def __init__(self, parent=None):
        super(SettingsTree, self).__init__(parent)

        self.setHeaderLabels(("Name", "vid", "pid"))
        self.header().setResizeMode(0, QtGui.QHeaderView.Stretch)
        self.header().setResizeMode(2, QtGui.QHeaderView.Stretch)

        self.refreshTimer = QtCore.QTimer()
        self.refreshTimer.setInterval(2000)
        self.autoRefresh = False

        self.groupIcon = QtGui.QIcon()
        self.groupIcon.addPixmap(self.style().standardPixmap(QtGui.QStyle.SP_DirClosedIcon),
                QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.groupIcon.addPixmap(self.style().standardPixmap(QtGui.QStyle.SP_DirOpenIcon),
                QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.keyIcon = QtGui.QIcon()
        self.keyIcon.addPixmap(self.style().standardPixmap(QtGui.QStyle.SP_FileIcon))

        self.refreshTimer.timeout.connect(self.refresh)

    def setTreeDataObject(self, treeData):
        self.treeData = treeData
        self.clear()

        if self.treeData is not None:
            self.treeData.setParent(self)
            self.refresh()
            if self.autoRefresh:
                self.refreshTimer.start()
        else:
            self.refreshTimer.stop()

    def sizeHint(self):
        return QtCore.QSize(800, 600)

    def setAutoRefresh(self, autoRefresh):
        self.autoRefresh = autoRefresh

        if self.treeData is not None:
            if self.autoRefresh:
                self.refresh()
                self.refreshTimer.start()
            else:
                self.refreshTimer.stop()

    def refresh(self):
        if self.treeData is None:
            return

        # The signal might not be connected.
        # try:
        #     self.itemChanged.disconnect(self.updateSetting)
        # except:
        #     pass

        self.updateChildItems(None)

        # self.itemChanged.connect(self.updateSetting)

    def event(self, event):
        if event.type() == QtCore.QEvent.WindowActivate:
            if self.isActiveWindow() and self.autoRefresh:
                self.refresh()

        return super(SettingsTree, self).event(event)

    '''on change to settings update tree'''
    def updateChildItems(self, parent):
        dividerIndex = 0

        for printer in self.treeData.myList:
            childIndex = self.findChild(parent, printer['name'], 0)
            if childIndex == -1 or childIndex >= dividerIndex:
                if childIndex != -1:
                    child = self.childAt(parent, childIndex)
                    for i in range(child.childCount()):
                        self.deleteItem(child, i)
                    self.moveItemForward(parent, childIndex, dividerIndex)
                else:
                    child = self.createItem(printer['name'], parent, dividerIndex)
                child.setIcon(0, self.keyIcon)
                dividerIndex += 1
            else:
                child = self.childAt(parent, childIndex)

            child.setText(1, printer['vid'])
            child.setText(2, printer['pid'])

    def createItem(self, text, parent, index):
        after = None

        if index != 0:
            after = self.childAt(parent, index - 1)

        if parent is not None:
            item = QtGui.QTreeWidgetItem(parent, after)
        else:
            item = QtGui.QTreeWidgetItem(self, after)

        item.setText(0, text)
        item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
        return item

    def deleteItem(self, parent, index):
        if parent is not None:
            item = parent.takeChild(index)
        else:
            item = self.takeTopLevelItem(index)
        del item

    def childAt(self, parent, index):
        if parent is not None:
            return parent.child(index)
        else:
            return self.topLevelItem(index)

    def childCount(self, parent):
        if parent is not None:
            return parent.childCount()
        else:
            return self.topLevelItemCount()

    def findChild(self, parent, text, startIndex):
        for i in range(self.childCount(parent)):
            if self.childAt(parent, i).text(0) == text:
                return i
        return -1

    def moveItemForward(self, parent, oldIndex, newIndex):
        for int in range(oldIndex - newIndex):
            self.deleteItem(parent, newIndex)
创建颜色代理,用于将文本“a”行的背景色设置为绿色

class SelectionColorDelegate(QtGui.QStyledItemDelegate):
    def __init__(self, parent):
        super(SelectionColorDelegate, self).__init__(parent)

    def initStyleOption(self, option, index):
        # let the base class initStyleOption fill option with the default values
        super(SelectionColorDelegate,self).initStyleOption(option, index)
        # override what you need to change in option
        if index.data() == 'a':
            backColor = QtGui.QColor("green")
            option.palette.setColor(QtGui.QPalette.Base, backColor)
            option.backgroundBrush = backColor
让它发挥作用:

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())

我设置背景色的两次尝试似乎都不起作用。

在进一步了解Qt之后,我重构了代码,以使用模型/视图关系。该模型继承自QtCore.qabstractemodel,实现如下数据方法:

class MyTreeModel(QtCore.QAbstractItemModel):

    def data(self, index, role):
        if not index.isValid():
            return None

        item = index.internalPointer()

        if role == QtCore.Qt.BackgroundRole:
            if item.status.status == 'Not installed':
                return QtGui.QBrush(QtCore.Qt.lightGray)
            if item.status.head_test_failed:
                return QtGui.QBrush(QtCore.Qt.red)
            if item.status.status == 'failure':
                return QtGui.QBrush(QtCore.Qt.red)
            if item.status.status == 'running':
                return QtGui.QBrush(QtCore.Qt.green)
            return QtGui.QBrush(QtCore.Qt.transparent)

        if role != QtCore.Qt.DisplayRole:
            return None

        return item.data(index.column())
通过这种方式,我可以使用标准的TreeView(或任何其他视图)。
role==QtCore.Qt.BackgroundRole
告诉模型这是一个格式化请求。

可能会对您有所帮助。它是C++的,但在Qt中,这是一对一传递给PySt/Pyqt。我没有时间来测试你的代码和其他代码,但是有一些经过投票的答案。
class MyTreeModel(QtCore.QAbstractItemModel):

    def data(self, index, role):
        if not index.isValid():
            return None

        item = index.internalPointer()

        if role == QtCore.Qt.BackgroundRole:
            if item.status.status == 'Not installed':
                return QtGui.QBrush(QtCore.Qt.lightGray)
            if item.status.head_test_failed:
                return QtGui.QBrush(QtCore.Qt.red)
            if item.status.status == 'failure':
                return QtGui.QBrush(QtCore.Qt.red)
            if item.status.status == 'running':
                return QtGui.QBrush(QtCore.Qt.green)
            return QtGui.QBrush(QtCore.Qt.transparent)

        if role != QtCore.Qt.DisplayRole:
            return None

        return item.data(index.column())