Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQt4-使用QItemDelegate在QListView中显示小部件_Python_Qt_Delegates_Pyqt4_Model View - Fatal编程技术网

Python PyQt4-使用QItemDelegate在QListView中显示小部件

Python PyQt4-使用QItemDelegate在QListView中显示小部件,python,qt,delegates,pyqt4,model-view,Python,Qt,Delegates,Pyqt4,Model View,我想要一个显示自定义小部件的QListView。我想最好的方法是使用QItemDelegate。不幸的是,我不太了解如何正确地将其子类化,以及如何实现paint()方法,这似乎是最重要的方法。我找不到任何关于使用委托创建另一个小部件的信息 我已经尝试过在没有委托的情况下实现类似的东西,但效果不是很好,因为QListView不应该显示小部件 import sys from PyQt4 import QtCore from PyQt4 import QtGui class Model(QtCore

我想要一个显示自定义小部件的
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_())

那么,我需要如何实现一个委托才能完成我想做的事情呢?

下面是一个
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)

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

一个包含三列的表格小部件怎么样,一列用于复选框,一列用于按钮,一列用于标签?我喜欢尽量避开代表。好吧,这是个好主意,我还没想过。但是当我这样做的时候,我仍然可以使用模型吗?模型将在table小部件中,您不必对任何东西进行子类化。你为什么需要这个模型?它怎么会在小部件中?事实上,我并不真的需要它,我只是认为它会更好,因为这样我可以使用模型中的数据并在其他地方显示。表小部件、列表小部件和树小部件都是方便类,在同一个小部件中具有模型+视图。您仍然可以将您的小部件保存在某个列表中:有一个“insert widget”方法附加到列表和表小部件。