美文网首页PySide2 Tutorial
PySide2学习记录(十七):自定义简单的Delegate

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

作者: 3ni | 来源:发表于2018-12-23 15:42 被阅读0次

    Python版本3.7
    PySide2 Version: 5.14.1
    官方文档:https://doc.qt.io/qtforpython/PySide2/QtWidgets/QItemDelegate.html
    参考文章:https://qimo601.iteye.com/blog/1536444

    代码

    from PySide2.QtWidgets import QApplication, QWidget, QListView, QVBoxLayout
    from PySide2.QtCore import QStringListModel
    
    
    app = QApplication()
    window = QWidget()
    window.setFixedSize(400, 300)
    
    # 生成一个view
    listview = QListView(window)
    # 生成一个model
    model = QStringListModel()
    
    # model添加数据
    model.setStringList(['1', '2', '3', '4', '5'])
    
    # view设置model
    listview.setModel(model)
    
    layout = QVBoxLayout(window)
    layout.addWidget(listview)
    
    window.setLayout(layout)
    window.show()
    app.exec_()
    
    

    效果图:

    图1

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

    from PySide2.QtWidgets import QApplication, QWidget, QSpinBox, QListView, QVBoxLayout, QItemDelegate
    from PySide2.QtCore import QStringListModel
    
    
    class MyDelegate(QItemDelegate):
        def __init__(self, parent=None):
            super().__init__(parent)
    
        def createEditor(self, parent, option, index):
            spinbox = 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 = QApplication()
    window = QWidget()
    window.setFixedSize(400, 300)
    
    mydelegate = MyDelegate()
    
    listview = QListView(window)
    mymodel = QStringListModel()
    
    listview.setModel(mymodel)
    # 设置我们自己的delegate
    listview.setItemDelegate(mydelegate)
    
    mymodel.setStringList(['1', '2', '3', '4', '5'])
    
    layout = QVBoxLayout(window)
    layout.addWidget(listview)
    
    window.setLayout(layout)
    window.show()
    app.exec_()
    
    

    效果图:

    图2

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

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

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

    createEditor(parent, option, index)
    parentQWidget类型,用于指定编辑器的父类(可以将上面代码中的spinbox = QtWidgets.QSpinBox(parent)改为spinbox = QtWidgets.QSpinBox()看看效果)。
    optionQStyleOptionViewItem类型。
    indexQModelIndex类型。
    这个函数主要用于生成一个我们想要的编辑器,然后返回这个对象。上面代码中生成了一个QSpinBox对象spinbox,用于调节指定的数字,范围在0到100之间。

    setEditorData(editor, index)
    editorQWidget类型,在程序运行中,会传递上面createEditor中我们产生的那个对象,即spinbox对象。
    indexQModelIndex类型。
    这个函数主要用于从model中取出数据,然后把数据传递给编辑器,进而显示在视图上。

    setModelData(editor, model, index)
    editor为QWidget类型,同上。
    model即我们在view中设置的model,类型QAbstractItemModel
    indexQModelIndex类型。
    这个函数主要用于从编辑器中取出数据,放入到model里面,实现数据的更新。

    updateEditorGeometry(editor, option, index)
    editorQWidget类型,同上。
    optionQStyleOptionViewItem类型。
    indexQModelIndex类型。
    这个函数用于更新编辑器位置大小,使编辑器好像嵌入到格子里面。

    友情链接:
    QItemDelegate

    相关文章

      网友评论

        本文标题:PySide2学习记录(十七):自定义简单的Delegate

        本文链接:https://www.haomeiwen.com/subject/tifnkqtx.html