1

QListWidget 内のウィジェットを独自の ProductItemWidget クラスに設定して、リスト内の項目をさらにカスタマイズできるようにしています。これは正常に機能しますが、リストを自動的に並べ替えることができません。電話する

my_list.setSortingEnabled(True)

次に、この関数を上書きできるように特別に作成した、ProductListItem の "<" コンパレーターを上書きしようとしました。コンパレーターでは、比較される 2 つのアイテムに対応するウィジェットにアクセスし、それらの getText() 関数を呼び出します。ここでの問題は、__ lt __ 関数がデフォルトで 2 番目の引数を QListWidgetItem にキャストするため、コードでは自分自身の 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 は「便利な」クラスの 1 つです (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 に答える