PySide2学习记录(十九):自定义简单的Delegate

Python2.7 或 Python3.7
PySide2 Version: 5.11.2
官方文档:http://doc.qt.io/qtforpython/index.html
参考文章:https://qimo601.iteye.com/blog/1536444

代码

# -*- coding:utf-8 -*-
from PySide2 import QtGui, QtWidgets, QtCore
import sys


app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setFixedSize(400, 300)

# 生成一个view
listview = QtWidgets.QListView(window)
# 生成一个model
model = QtCore.QStringListModel()

# model添加数据
model.setStringList(['1', '2', '3', '4', '5'])

# view设置model
listview.setModel(model)

layout = QtWidgets.QVBoxLayout(window)
layout.addWidget(listview)

window.setLayout(layout)
window.show()
sys.exit(app.exec_())

效果图:

PySide2学习记录(十九):自定义简单的Delegate_第1张图片
图1

当双击某一项时,就变成了可编辑状态,可以随意编辑。之前说过,数据是放在model里面的,当我们双击某一项时,程序偷偷创建了一个delegate,delegate里面有一个编辑框,编辑完成时,delegate会把数据从编辑框中取出放入到model,然后修改视图里面的数据,从而完成数据的传递和更新,这里的代码没有创建delegate对象,所以程序偷偷帮我们创建了一个。下面来自定义一个delegate,来更好地理解Model/View Programming。

from PySide2 import QtGui, QtWidgets, QtCore
import sys


class MyDelegate(QtWidgets.QItemDelegate):
    def __init__(self, parent=None):
        QtWidgets.QItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        spinbox = QtWidgets.QSpinBox(parent)
        spinbox.setMinimum(0)
        spinbox.setMaximum(100)
        return spinbox

    def setEditorData(self, editor, index):
        value = index.model().data(index)
        editor.setValue(int(value))

    def setModelData(self, editor, model, index):
        value = editor.value()
        model.setData(index, int(value))

    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)


app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setFixedSize(400, 300)

mydelegate = MyDelegate()

listview = QtWidgets.QListView(window)
mymodel = QtCore.QStringListModel()

listview.setModel(mymodel)
# 设置我们自己的delegate
listview.setItemDelegate(mydelegate)

mymodel.setStringList(['1', '2', '3', '4', '5'])

layout = QtWidgets.QVBoxLayout(window)
layout.addWidget(listview)

window.setLayout(layout)
window.show()
sys.exit(app.exec_())

效果图:

图2

在介绍代码之前还需要理解几个类。
第一个是QStyleOptionViewItem类(点击可访问官方文档)
从名字可以看出是用于设置有关于一些视图中每一项的风格方面的类,比如linux中的窗口和windows中窗口风格就不一样,如果想自定义风格的item需要用到这个类(推荐看文档更能理解)。

第二个是QModelIndex类(点击可访问官方文档)
这个是用于检索model数据的类。

要自定义delegate首先继承QtWidgets.QItemDelegate这个类(继承QtWidgets.QStyledItemDelegate类也是没有问题的,区别是后一个会自动和整个程序的样式尽量保持一致),然后要分别实现的以下四个函数:
createEditor(parent, option, index)

  • parent为QWidget类型,用于指定编辑器的父类(可以将上面代码中的spinbox = QtWidgets.QSpinBox(parent)改为spinbox = QtWidgets.QSpinBox()看看效果)。
  • option为QStyleOptionViewItem类型。
  • index为QModelIndex类型。

这个函数主要用于生成一个我们想要的编辑器,然后返回这个对象。上面代码中生成了一个QSpinBox对象spinbox,用于调节指定的数字,范围在0到100之间。

setEditorData(editor, index)

  • editor为QWidget类型,在程序运行中,会传递上面createEditor中我们产生的那个对象,即spinbox对象。
  • index为QModelIndex类型。

这个函数主要用于从model中取出数据,然后把数据传递给编辑器,进而显示在视图上。

setModelData(editor, model, index)

  • editor为QWidget类型,同上。
  • model即我们在view中设置的model,类型QAbstractItemModel。
  • index为QModelIndex类型。

这个函数主要用于从编辑器中取出数据,放入到model里面,实现数据的更新。

updateEditorGeometry(editor, option, index)

  • editor为QWidget类型,同上。
  • option为QStyleOptionViewItem类型。
  • index为QModelIndex类型。

这个函数用于更新编辑器位置大小,使编辑器好像嵌入到格子里面。

你可能感兴趣的:(PySide2学习记录(十九):自定义简单的Delegate)