带有自定义项目的QTreeView [英] QTreeView with custom items

查看:287
本文介绍了带有自定义项目的QTreeView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用PySide编写我的第一个Qt应用程序,但是在创建自定义树视图时遇到了一些麻烦.我想在一列中列出我自己的数据. 每个项目必须具有带工具提示的文本,不同的文本颜色,不同的背景颜色,带有操作的图标和工具提示.

I'm writing my first Qt application with PySide and am having some trouble creating a custom tree view. I'd like to list my own data in one column. Each item must have text with tooltip, different text color, different background color, icons with actions and tooltip.

默认树起作用. 我有视图:class TreeView(PySide.QtGui.QTreeView): 和型号:class TreeModel(PySide.QtCore.QAbstractItemModel):

The default tree works. I have view: class TreeView(PySide.QtGui.QTreeView): and model: class TreeModel(PySide.QtCore.QAbstractItemModel):

如何为项目添加不同的图标?

How can I add different icons to my items?

这是我的例子:

import sys
from PySide import QtGui, QtCore


#-------------------------------------------------------------------------------
# my test data
class MyData():
    def __init__(self, txt, parent=None):
        self.txt = txt
        self.parent = parent
        self.child = []
        self.icon = None
        self.index = None

    #---------------------------------------------------------------------------
    def position(self):
        position = 0
        if self.parent is not None:
            count = 0
            children = self.parent.child
            for child in children:
                if child == self:
                    position = count
                    break
                count += 1
        return position

    #---------------------------------------------------------------------------
    # test initialization
    @staticmethod
    def init():
        root = MyData("root")
        for i in range(0, 2):
            child1 = MyData("child %i" % (i), root)
            root.child.append(child1)
            for x in range(0, 2):
                child2 = MyData("child %i %i" % (i, x), child1)
                child1.child.append(child2)

        return root


#-------------------------------------------------------------------------------
class TreeModel(QtCore.QAbstractItemModel):

    #---------------------------------------------------------------------------
    def __init__(self, tree):
        super(TreeModel, self).__init__()
        self.__tree = tree
        self.__current = tree

    #---------------------------------------------------------------------------
    def flags(self, index):
        flag = QtCore.Qt.ItemIsEnabled
        if index.isValid():
            flag |= QtCore.Qt.ItemIsSelectable \
                 | QtCore.Qt.ItemIsUserCheckable \
                 | QtCore.Qt.ItemIsEditable \
                 | QtCore.Qt.ItemIsDragEnabled \
                 | QtCore.Qt.ItemIsDropEnabled
        return flag

    #---------------------------------------------------------------------------
    def index(self, row, column, parent=QtCore.QModelIndex()):
        node = QtCore.QModelIndex()
        if parent.isValid():
            nodeS = parent.internalPointer()
            nodeX = nodeS.child[row]
            node = self.__createIndex(row, column, nodeX)
        else:
            node = self.__createIndex(row, column, self.__tree)
        return node

    #---------------------------------------------------------------------------
    def parent(self, index):
        node = QtCore.QModelIndex()
        if index.isValid():
            nodeS = index.internalPointer()
            parent = nodeS.parent
            if parent is not None:
                node = self.__createIndex(parent.position(), 0, parent)
        return node

    #---------------------------------------------------------------------------
    def rowCount(self, index=QtCore.QModelIndex()):
        count = 1
        node = index.internalPointer()
        if node is not None:
            count = len(node.child)
        return count

    #---------------------------------------------------------------------------
    def columnCount(self, index=QtCore.QModelIndex()):
        return 1

    #---------------------------------------------------------------------------
    def data(self, index, role=QtCore.Qt.DisplayRole):
        data = None
        if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole:
            node = index.internalPointer()
            data = node.txt

        if role == QtCore.Qt.ToolTipRole:
            node = index.internalPointer()
            data = "ToolTip " + node.txt

        if role == QtCore.Qt.DecorationRole:
            data = QtGui.QIcon("icon.png")
        return data

    #---------------------------------------------------------------------------
    def setData(self, index, value, role=QtCore.Qt.DisplayRole):
        result = True
        if role == QtCore.Qt.EditRole and value != "":
            node = index.internalPointer()
            node.text = value
            result = True
        return result

    #---------------------------------------------------------------------------
    def __createIndex(self, row, column, node):
        if node.index == None:
            index = self.createIndex(row, column, node)
            node.index = index
            icon = QtGui.QIcon("icon.png")
            b = self.setData(index, icon, QtCore.Qt.DecorationRole)
            b = self.setData(index, "ToolTip "+node.txt, QtCore.Qt.ToolTipRole)
        return node.index



#-------------------------------------------------------------------------------
class TreeView(QtGui.QTreeView):
    #---------------------------------------------------------------------------
    def __init__(self, model, parent=None):
        super(TreeView, self).__init__(parent)
        self.__model = model
        self.setModel(model)


        self.setCurrentIndex(self.__model.index(0, 0))
        return




#-------------------------------------------------------------------------------
class MyTree(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyTree, self).__init__(parent)

        data = MyData.init()
        treeModel = TreeModel(data)
        treeView = TreeView(treeModel)

        self.setCentralWidget(treeView)


#-------------------------------------------------------------------------------
def main():
    app = QtGui.QApplication(sys.argv)
    form = MyTree()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

推荐答案

我使用自己的QWidget

I use my own QWidget

import sys
from PySide import QtGui, QtCore


#-------------------------------------------------------------------------------
# my test data
class Icon():
    def __init__(self, icon, tooltip):
        self.pixmap = QtGui.QPixmap(icon)
        self.tooltip = tooltip

#-------------------------------------------------------------------------------
# my test data
class MyData():
    def __init__(self, txt, parent=None):
        self.txt = txt
        self.tooltip = None
        self.parent = parent
        self.child = []
        self.icon = []
        self.index = None
        self.widget = None

    #---------------------------------------------------------------------------
    def position(self):
        position = 0
        if self.parent is not None:
            count = 0
            children = self.parent.child
            for child in children:
                if child == self:
                    position = count
                    break
                count += 1
        return position

    #---------------------------------------------------------------------------
    # test initialization
    @staticmethod
    def init():
        root = MyData("root")
        root.icon.append(Icon("icon.png", "ToolTip icon.png"))
        root.tooltip = "root tooltip"
        for i in range(0, 2):
            child1 = MyData("child %i" % (i), root)
            child1.icon.append(Icon("icon1.png", "ToolTip icon1.png"))
            child1.tooltip = "child1 tooltip"
            root.child.append(child1)
            for x in range(0, 2):
                child2 = MyData("child %i %i" % (i, x), child1)
                child2.icon.append(Icon("icon1.png", "ToolTip icon1.png"))
                child2.icon.append(Icon("icon2.png", "ToolTip icon2.png"))
                child2.tooltip = "child2 tooltip"
                child1.child.append(child2)

        return root

#-------------------------------------------------------------------------------
class TreeViewModel(QtCore.QAbstractItemModel):
    #---------------------------------------------------------------------------
    def __init__(self, tree):
        super(TreeViewModel, self).__init__()
        self.__tree = tree
        self.__current = tree
        self.__view = None

    #---------------------------------------------------------------------------
    def flags(self, index):
        flag = QtCore.Qt.ItemIsEnabled
        if index.isValid():
            flag |= QtCore.Qt.ItemIsSelectable \
                 | QtCore.Qt.ItemIsUserCheckable \
                 | QtCore.Qt.ItemIsEditable \
                 | QtCore.Qt.ItemIsDragEnabled \
                 | QtCore.Qt.ItemIsDropEnabled
        return flag

    #---------------------------------------------------------------------------
    def index(self, row, column, parent=QtCore.QModelIndex()):
        node = QtCore.QModelIndex()
        if parent.isValid():
            nodeS = parent.internalPointer()
            nodeX = nodeS.child[row]
            node = self.__createIndex(row, column, nodeX)
        else:
            node = self.__createIndex(row, column, self.__tree)
        return node

    #---------------------------------------------------------------------------
    def parent(self, index):
        node = QtCore.QModelIndex()
        if index.isValid():
            nodeS = index.internalPointer()
            parent = nodeS.parent
            if parent is not None:
                node = self.__createIndex(parent.position(), 0, parent)
        return node

    #---------------------------------------------------------------------------
    def rowCount(self, index=QtCore.QModelIndex()):
        count = 1
        node = index.internalPointer()
        if node is not None:
            count = len(node.child)
        return count

    #---------------------------------------------------------------------------
    def columnCount(self, index=QtCore.QModelIndex()):
        return 1

    #---------------------------------------------------------------------------
    def data(self, index, role=QtCore.Qt.DisplayRole):
        data = None
        return data

    #---------------------------------------------------------------------------
    def setView(self, view):
        self.__view = view

    #---------------------------------------------------------------------------
    def __createIndex(self, row, column, node):
        if node.index == None:
            index = self.createIndex(row, column, node)
            node.index = index
        if node.widget is None:
            node.widget = Widget(node)
            self.__view.setIndexWidget(index, node.widget)
        return node.index


#-------------------------------------------------------------------------------
class TreeView(QtGui.QTreeView):
    #---------------------------------------------------------------------------
    def __init__(self, model, parent=None):
        super(TreeView, self).__init__(parent)
        self.setModel(model)
        model.setView(self)
        root = model.index(0, 0)
        self.setCurrentIndex(root)
        self.setHeaderHidden(True)

    #---------------------------------------------------------------------------
    def keyPressEvent(self, event):
        k = event.key()
        if k == QtCore.Qt.Key_F2:
            self.__editMode()

        super(TreeView, self).keyPressEvent(event)

    #---------------------------------------------------------------------------
    def __editMode(self):
        index = self.currentIndex()
        node = index.internalPointer()
        node.widget.editMode(True, True)


#-------------------------------------------------------------------------------
class Label(QtGui.QLabel):
    #---------------------------------------------------------------------------
    def __init__(self, parent, text):
        super(Label, self).__init__(text)
        self.__parent = parent

    #---------------------------------------------------------------------------
    def mouseDoubleClickEvent(self, event):
        #print("mouseDoubleClickEvent")
        if self.__parent is not None:
            self.__parent.editMode(True, True)
        else:
            super(Label, self).mouseDoubleClickEvent(event)


#-------------------------------------------------------------------------------
class LineEdit(QtGui.QLineEdit):
    #---------------------------------------------------------------------------
    def __init__(self, parent, text):
        super(LineEdit, self).__init__(text)
        self.__parent = parent
        self.editingFinished.connect(self.__editingFinished)

    #---------------------------------------------------------------------------
    def keyPressEvent(self, event):
        k = event.key()
        if k == QtCore.Qt.Key_Escape:
            print("ESC 2")
            self.__editingFinished(False)
        super(LineEdit, self).keyPressEvent(event)

    #---------------------------------------------------------------------------
    def __editingFinished(self, bCopy=True):
        print("editingFinished")
        self.__parent.editMode(False, bCopy)

#-------------------------------------------------------------------------------
class Widget(QtGui.QWidget):
    #---------------------------------------------------------------------------
    def __init__(self, node):
        super(Widget, self).__init__()
        self.autoFillBackground()
        self.__node = node
        self.__bEditMode = False
        self.__txt = None
        self.__create(self.__node, self.__bEditMode)

    #---------------------------------------------------------------------------
    def __create(self, node, bEditMode):
        layout = QtGui.QHBoxLayout()
        for icon in node.icon:
            label = Label(None, node.txt)
            label.setPixmap(icon.pixmap)
            label.setToolTip("label tooltip %s %s" % (node.txt, icon.tooltip))
            layout.addWidget(label)

        self.__changeTxt(layout, node, bEditMode, False)
        self.setLayout(layout)

    #---------------------------------------------------------------------------
    def __changeTxt(self, layout, node, bEditMode, bCopy):
        if self.__txt is not None:
            if bCopy:
                node.txt = self.__txt.text()
            if isinstance(self.__txt, LineEdit):
                self.__txt.deselect()
            self.__txt.hide()
            layout.removeWidget(self.__txt)
            self.__txt = None

        if bEditMode:
            self.__txt = LineEdit(self, node.txt)
            self.__txt.setFrame(False)
            self.__txt.selectAll()
            QtCore.QTimer.singleShot(0, self.__txt, QtCore.SLOT('setFocus()'));
        else:
            self.__txt = Label(self, node.txt)
        self.__txt.setToolTip("Text tooltip %s %s" % (node.txt, node.tooltip))
        layout.addWidget(self.__txt, 1)

    #---------------------------------------------------------------------------
    def editMode(self, bEditMode, bCopy):
        if self.__bEditMode != bEditMode:
            self.__bEditMode = bEditMode
            layout = self.layout()
            self.__changeTxt(layout, self.__node, bEditMode, bCopy)

#-------------------------------------------------------------------------------
class MyTree(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MyTree, self).__init__(parent)

        data = MyData.init()
        frame = QtGui.QFrame();
        frame.setLayout( QtGui.QHBoxLayout() );

        treeViewModel = TreeViewModel(data)
        treeView = TreeView(treeViewModel)
        frame.layout().addWidget( treeView );

        self.setCentralWidget(frame)

#-------------------------------------------------------------------------------
def main():
    app = QtGui.QApplication(sys.argv)
    form = MyTree()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

这篇关于带有自定义项目的QTreeView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆