2013-11-15 55 views
1

我將QListWidget中的小部件設置爲我自己的ProductItemWidget類,以便能夠對列表中的項目進行更多自定義。這工作正常,但我無法獲得列表自動排序。我叫我可以重寫QListWidgetItem的__lt__比較器的輸入嗎? (PyQt)

my_list.setSortingEnabled(True) 

,然後我嘗試覆蓋ProductListItem,這是我專門創建能夠覆蓋此功能的「<」比較。在比較器中,我嘗試訪問與被比較的兩個項目相對應的小部件,並調用它們的getText()函數。這裏的問題是,__ lt __函數默認將第二個參數強制轉換爲QListWidgetItem,所以在我的代碼中,我爲Product獲得了ProductListItem,但是我得到了QListWidgetItem for otherItem。 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?

我一直堅持這個問題一段時間,所以任何提示都表示讚賞。我願意改變我的整個方法。

回答

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_()) 
相關問題