1

我将 QListWidget 内的小部件设置为我自己的 ProductItemWidget 类,以便能够对列表中的项目进行更多自定义。这工作正常,但我无法让列表自动排序。我打电话

my_list.setSortingEnabled(True)

然后我尝试覆盖 ProductListItem 的“<”比较器,我专门创建它以便能够覆盖此函数。在比较器中,我尝试访问与被比较的两个项目相对应的小部件并调用它们的 getText() 函数。这里的问题是,__ lt __ 函数默认将第二个参数转换为 QListWidgetItem,所以在我的代码中,我为 self 获取 ProductListItem,但为 otherItem 获取 QListWidgetItem。otherItem 不允许我访问它对应的 ProductItemWidget,因为访问它的唯一方法是将 ProductListItem 传递给 QListWidget 的 itemWidget() 调用。这是我的代码:

class ProductListItem(QListWidgetItem):
    def __init__(self, parent=None):
        super(ProductListItem, self).__init__(parent)

    def __lt__(self, otherItem):

        this_item_widget = self.listWidget().itemWidget(self)
        other_item_widget = otherItem.listWidget().itemWidget(otherItem)

        return this_item_widget.getText() < other_item_widget.getText()

class ProductItemWidget(QWidget):
    def __init__(self, product_name, parent=None):
        super(ProductItemWidget, self).__init__(parent)
        self.label = QLabel(product_name)
        ... setup code ...

    def getText(self):
        return self.label.text()

有什么方法可以阻止对 __ lt __ 的调用将 otherItem 转换为 QListWidgetItem?

我已经被这个问题困扰了一段时间,所以任何提示都值得赞赏。我愿意改变我的整个方法。

4

1 回答 1

2

QListWidget 是“便利”类之一(如 QTreeWidget 和 QTableWidget)。只要您的要求非常简单,就可以使用它们。但是一旦你想要更复杂一点的东西,不灵活很快就会开始显现。

您可以通过使用 QStandardItemModel 切换到更通用的 QListView 类来相当容易地解决您的问题。这需要更多的工作来设置,但它会立即带来更多的灵活性。

这是基于您的示例代码的该方法的演示:

from PyQt4 import QtGui

class ProductListItem(QtGui.QStandardItem):
    def __lt__(self, other):
        listview = self.model().parent()
        this_widget = listview.indexWidget(self.index())
        other_widget = listview.indexWidget(other.index())
        return this_widget.getText() < other_widget.getText()

class ProductItemWidget(QtGui.QWidget):
    def __init__(self, product_name, parent=None):
        super(ProductItemWidget, self).__init__(parent)
        self.label = QtGui.QLabel(product_name, self)
        layout = QtGui.QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.label)

    def getText(self):
        return self.label.text()

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.list = QtGui.QListView(self)
        layout = QtGui.QHBoxLayout(self)
        layout.addWidget(self.list)
        # model must have the listview as parent
        model = QtGui.QStandardItemModel(self.list)
        self.list.setModel(model)
        for key in 'MHFCLNIBJDAEGK':
            item = ProductListItem()
            model.appendRow(item)
            widget = ProductItemWidget('Item %s' % key, self.list)
            self.list.setIndexWidget(item.index(), widget)
        model.sort(0)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.setGeometry(500, 300, 150, 300)
    window.show()
    sys.exit(app.exec_())
于 2013-11-15T04:15:43.803 回答