QTreeView的系类文章如下,可根据熟练程度自行食用
QTreeView的使用(一)
QTreeView的使用(二)
本章主要讲述的是自定义每一个树节点以及实现搜索高亮
PS.本文主要是依据 QTreeView的使用(二)上的代码改过来的!
1、QItemDelegate与QAbstractItemModel的关系
2、QItemDelegate绘制自定义图案
3、完善之前的搜索栏,实现输入后高亮!
4、响应自定义图像
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函数为例子,画一个如下样式的节点
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
绘制不同控件的方式大体就如上啦!!!!!!!!!!!!!!
如果我们不想画Qt自带的控件,想绘制自定义的控件要怎么办呢!!下面就来讲述自己绘制图像,我会以一个选中后显示文字为例子讲述
实现的效果如下
代码如下
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
用这句可以判断当前节点是否被选中
color = QColor(0x05, 0x83, 0xe7, 0x99)
painter.setPen(color)
painter.setBrush(color)
painter.drawRect(textRect)
实现的方式也很简单,同样是在drawDisplay这个方法里面,找到你搜索的文字,然后在那个地方画一个框!代码中的textRect就是你所搜索的文字的rect
在上面绘制的控件中,你会发现其实他是不响应点击事件的,具体原因没有去深究,那么此时我们该如何让其响应呢
在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的使用,也是最后一篇!等我学会了就来!