QTreeView的使用(三)

QTreeView的系类文章如下,可根据熟练程度自行食用
QTreeView的使用(一)
QTreeView的使用(二)
本章主要讲述的是自定义每一个树节点以及实现搜索高亮
PS.本文主要是依据 QTreeView的使用(二)上的代码改过来的!

写作思路

1、QItemDelegate与QAbstractItemModel的关系
2、QItemDelegate绘制自定义图案
3、完善之前的搜索栏,实现输入后高亮!
4、响应自定义图像

1、QItemDelegate与QAbstractItemModel的关系

Qt的QItemDelegate官方API
下面来简单说明一下各个函数的作用:
首先说一下下面几个函数
在这里插入图片描述
这几个函数的名字是不是很眼熟!回到我这篇看看!
QTreeView的使用(二)
在继承自QAbstractItemModel的模型类中,data()函数里,也就是下面这几个role,对应的分别就是上面这几个函数,我们可以通过上述这三个函数的painter,随意绘制想要的样式

def data(self, index, role):
        if not index.isValid():
            return QVariant
        item = index.internalPointer()
        if role == Qt.DecorationRole:
            if len(item.childItems) != 0:
                return QIcon("floder.svg")
            else:
                return QIcon("node.svg")
        if role == Qt.CheckStateRole:
            if item.isShow is True:
                return Qt.Checked
            else:
                return Qt.Unchecked
        if role == Qt.DisplayRole:
            return item.data(index.column())

另外,还有下面这个函数,他对应的就是节点的初始绘制
在这里插入图片描述
我以paint函数为例子,画一个如下样式的节点QTreeView的使用(三)_第1张图片

    def paint(self, painter, option, index):
        super(ItemDelegate, self).paint(painter, option, index)
        radio = 1
        top = option.rect.top() + radio
        left = option.rect.left() + radio
        width = option.rect.width() - 2 * radio
        height = option.rect.height() - 2 * radio

        bar = QStyleOptionProgressBar()
        bar.rect.setRect(left, top, width, height)
        bar.state = QStyle.State_Enabled
        bar.progress = 80
        bar.minimum = 0
        bar.maximum = 100
        bar.textVisible = True
        bar.text = str(bar.progress)
        bar.textAlignment = Qt.AlignCenter

        pbar = QProgressBar()
        QApplication.style().drawControl(QStyle.CE_ProgressBar, bar, painter, pbar)

简单说明一下几个关键点:
1、绘制例如上述这类的控件图案的时候,首先我们要找到控件对应的Style,官方给的有如下这些中的部分,可以自行尝试,博主仅仅试过ProgressBar和Button
在这里插入图片描述
2、设置对应Style 的一些常用参数,如上面的progress、text等等
3、找到Qt给定的控件原型,如上面的QProgressBar
4、利用QApplication.style().drawControl()将控件绘制出来!这里需要注意的是 QStyle.CE_ProgressBar 这个参数是要随不同的Style变更参数,不同Style对应什么参数自行查看QStyle官方API
绘制不同控件的方式大体就如上啦!!!!!!!!!!!!!!

2、QItemDelegate绘制自定义图案

如果我们不想画Qt自带的控件,想绘制自定义的控件要怎么办呢!!下面就来讲述自己绘制图像,我会以一个选中后显示文字为例子讲述
实现的效果如下
QTreeView的使用(三)_第2张图片
代码如下

    def drawDisplay(self, painter, option, rect, text):
        if (int(option.state) & QStyle.State_Selected) != 0:
            titleWidth = fm.width(text)
            top = rect.top() + 4
            left = rect.left() + titleWidth + self.textInterval
            width = fm.width(self.enterContent)
            if left < self.parent().rect().width() - width:
                left = self.parent().rect().width() - width - self.scrollWidth
            height = rect.height()
            font = QFont(QFont("仿宋", 8))
            painter.setFont(font)
            painter.setPen(self.enterColor)
            textRect = QRect(left, top, width, height)
            painter.drawText(textRect, 0, self.enterContent)

简单讲述一下实现的方式,概括起来两个点:1、选定绘制的rect 2、绘制对应的图案
以上面为例,我只是简单的绘制了一串文字,其中要说明一下,为了实现选中才显示,代码中用到了一个比较关键的代码:
if (int(option.state) & QStyle.State_Selected) != 0
用这句可以判断当前节点是否被选中

3、完善之前的搜索栏,实现输入后高亮!

未加高亮前的效果
QTreeView的使用(三)_第3张图片
加高亮之后的效果
QTreeView的使用(三)_第4张图片

  color = QColor(0x05, 0x83, 0xe7, 0x99)
  painter.setPen(color)
  painter.setBrush(color)
  painter.drawRect(textRect)

实现的方式也很简单,同样是在drawDisplay这个方法里面,找到你搜索的文字,然后在那个地方画一个框!代码中的textRect就是你所搜索的文字的rect

4、响应自定义图像

在上面绘制的控件中,你会发现其实他是不响应点击事件的,具体原因没有去深究,那么此时我们该如何让其响应呢
QItemDelegate里有一个方法
在这里插入图片描述
这个方法会在我们编辑每个节点的时候,都会回调该方法,因此我们可以利用rect的特性,来实现点击回调!具体实现如下

    def editorEvent(self, event, model, option, index):
        if textRect.contains(event.pos()):
            if event.button() == Qt.LeftButton and event.type() == QEvent.MouseButtonPress:
                pass
                #TODO
                return super(ItemDelegate, self).editorEvent(event, model, option, index)
            else:
                return super(ItemDelegate, self).editorEvent(event, model, option, index)
        else:
            return super(ItemDelegate, self).editorEvent(event, model, option, index)

textRect其实就是我们上面绘制的我显示出来啦 的rect,这时我们就可以在TODO里面添加任意我们想回调的方法!

结语

应该还会有一篇关于QTreeView的使用,也是最后一篇!等我学会了就来!

你可能感兴趣的:(QT,pyqt5,treeview,python)