2013-11-15 5 views
1

QListWidget 내부의 위젯을 내 자신의 ProductItemWidget 클래스로 설정하여 목록의 항목에 대해 더 많은 사용자 정의를 할 수 있습니다. 이 잘 작동하지만 목록을 자동으로 정렬 얻을 수 없습니다. 나는QListWidgetItem의 __lt__ 비교기에 대한 입력을 무시할 수 있습니까? (PyQt)

my_list.setSortingEnabled(True) 

를 호출 한 후 나는이 기능을 덮어 쓸 수 있도록 특별히 만든 ProductListItem의 "<"비교를 덮어하려고합니다. 비교기에서 비교되는 두 항목에 해당하는 위젯에 액세스하여 getText() 함수를 호출합니다. 여기에있는 문제는 기본적으로 __ lt __ 함수가 두 번째 인수를 QListWidgetItem으로 캐스팅하므로 내 코드에서 self에 대한 ProductListItem을 얻지 만 otherItem에 대해 QListWidgetItem을 얻습니다. otherItem은 해당 항목에 액세스 할 수있는 유일한 방법은 ProductListItem을 QListWidget의 itemWidget() 호출에 전달하는 것이므로 해당 항목에 해당하는 ProductItemWidget에 액세스 할 수 없습니다.

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() 

otherItem이 QListWidgetItem 캐스팅에서 __ LT __에 대한 호출을 방지 할 수있는 방법이있다 : 여기 내 코드는?

나는 잠시 동안이 문제에 갇혀 있었기 때문에 어떤 조언을 부탁드립니다. 나는 나의 모든 접근 방식을 기꺼이 바꿀 용의가있다.

답변

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_()) 
: 여기

는 샘플 코드를 기반으로하는 접근 방식의 데모입니다