【问题标题】:PyQt4 - Using a QItemDelegate to display widget in a QListViewPyQt4 - 使用 QItemDelegate 在 QListView 中显示小部件
【发布时间】:2015-12-08 13:54:02
【问题描述】:

我想要一个显示自定义小部件的QListView。我想最好的方法是QItemDelegate。不幸的是,我不太明白如何正确地对其进行子类化以及如何实现paint() 方法,这似乎是最重要的方法。我找不到任何关于使用委托创建另一个小部件的信息。

我已经尝试在没有委托的情况下实现类似的东西,但效果不佳,因为QListView 不应该显示小部件。

import sys
from PyQt4 import QtCore
from PyQt4 import QtGui

class Model(QtCore.QAbstractListModel):

    def __init__(self, parent=None):
        super(QtCore.QAbstractListModel, self).__init__(parent)
        self._widgets = []


    def headerData(self, section, orientation, role):
        """ Returns header for columns """
        return "Header"


    def rowCount(self, parentIndex=QtCore.QModelIndex()):
        """ Returns number of interfaces """
        return len(self._widgets)


    def data(self, index, role):
        """ Returns the data to be displayed """
        if role == QtCore.Qt.DisplayRole:
            row = index.row()
            return self._widgets[row]


    def insertRow(self, widget, parentIndex=QtCore.QModelIndex()):
        """ Inserts a row into the model """
        self.beginInsertRows(parentIndex, 0, 1)
        self._widgets.append(widget)
        self.endInsertRows()


class Widget(QtGui.QWidget):

    def __init__(self, parent=None, name="None"):
        super(QtGui.QWidget, self).__init__(parent)
        self.layout = QtGui.QHBoxLayout()
        self.setLayout(self.layout)
        self.checkbox = QtGui.QCheckBox()
        self.button = QtGui.QPushButton(self)
        self.label = QtGui.QLabel(self)
        self.label.setText(name)
        self.layout.addWidget(self.checkbox)
        self.layout.addWidget(self.button)
        self.layout.addWidget(self.label)

class Window(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(QtGui.QMainWindow, self).__init__(parent)
        self.view = QtGui.QListView(self)
        self.model = Model()
        self.view.setModel(self.model)
        self.setCentralWidget(self.view)

        self.model.insertRow(
            widget=Widget(self)
        )
        self.model.insertRow(
            widget=Widget(self)
        )
        self.model.insertRow(
            widget=Widget(self)
        )
        self.model.insertRow(
            widget=Widget(self)
        )

        self.show()


app = QtGui.QApplication(sys.argv)
window = Window()
sys.exit(app.exec_())

那么,我需要如何实现委托才能做我想做的事?

【问题讨论】:

  • 有 3 列的表格小部件怎么样,一列用于复选框,一列用于按钮,一列用于标签?我喜欢尽可能避免代表。
  • 嗯,这是个好主意,还没有考虑过。但是我仍然可以在这样做时使用模型吗?
  • 模型将在表格小部件内,您不必对任何东西进行子类化。为什么需要模型?
  • 小部件里怎么会有?其实我真的不需要它,我只是觉得它会更好,因为这样我可以使用模型内部的数据并显示在其他地方,也是。
  • 表格小部件、列表小部件和树小部件是与模型+视图在同一个小部件内的便利类。您仍然可以将您的小部件保存在某个列表中:有一个“插入小部件”方法,该方法附加到列表和表格小部件。

标签: python qt delegates pyqt4 model-view


【解决方案1】:

这是QTableWidget 的示例,每行都有一个按钮和文本。我定义了一个add_item 方法来一次添加一整行:插入一个新行,在第 0 列中放置一个按钮,在第 1 列中放置一个常规项。

import sys
from PyQt4 import QtGui,QtCore

class myTable(QtGui.QTableWidget):      
    def __init__(self,parent=None):
        super(myTable,self).__init__(parent)
        self.setColumnCount(2)

    def add_item(self,name):
        #new row
        row=self.rowCount()
        self.insertRow(row)

        #button in column 0
        button=QtGui.QPushButton(name)
        button.setProperty("name",name)
        button.clicked.connect(self.on_click)
        self.setCellWidget(row,0,button)

        #text in column 1
        self.setItem(row,1,QtGui.QTableWidgetItem(name))

    def on_click(self):
        # find the item with the same name to get the row
        text=self.sender().property("name")
        item=self.findItems(text,QtCore.Qt.MatchExactly)[0]
        print("Button click at row:",item.row())

if __name__=='__main__':
    app = QtGui.QApplication(sys.argv)      
    widget = myTable()
    widget.add_item("kitten")
    widget.add_item("unicorn")
    widget.show()
    sys.exit(app.exec_())

奖励:如何知道用户点击了哪个按钮?按钮没有 row 属性,但我们可以在实例化按钮时创建一个,如下所示:

button.setProperty("row",row)

问题是,如果您对表格进行排序或删除一行,行号将不再匹配。因此,我们设置了一个“名称”属性,与第 1 列中项目的文本相同。然后我们可以使用findItems 来获取行(参见on_click)。

【讨论】:

    猜你喜欢
    • 2011-01-01
    • 2011-08-25
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 1970-01-01
    相关资源
    最近更新 更多