2014-03-18 42 views
5

該代碼構建一個對話框,其中包含一個單獨的QListWidget和一個單獨的QPushButtonPyQt:如何獲得大部分QListWidget

單擊該按鈕可添加單個列表項。

右鍵單擊列表項會出現一個右鍵菜單,並帶有「刪除項」命令。

選擇「刪除項目」命令會從列表控件中刪除一個列表項目。

將是有趣的,看看下面的ListWidgets OPS中如何實現:

  1. 能夠上下(重新安排)移動列表項。
  2. 能夠多選和多刪除列表項目。
  3. 更好更強大的列表項排序。

例子:

import sys, os 
from PyQt4 import QtCore, QtGui  

class ThumbListWidget(QtGui.QListWidget): 
    def __init__(self, type, parent=None): 
     super(ThumbListWidget, self).__init__(parent) 
     self.setAcceptDrops(True) 
     self.setIconSize(QtCore.QSize(124, 124)) 

    def dragEnterEvent(self, event): 
     if event.mimeData().hasUrls: 
      event.accept() 
     else: 
      event.ignore() 

    def dragMoveEvent(self, event): 
     if event.mimeData().hasUrls: 
      event.setDropAction(QtCore.Qt.CopyAction) 
      event.accept() 
     else: 
      event.ignore() 

    def dropEvent(self, event): 
     if event.mimeData().hasUrls: 
      event.setDropAction(QtCore.Qt.CopyAction) 
      event.accept() 
      links = [] 
      for url in event.mimeData().urls(): 
       links.append(str(url.toLocalFile())) 
      self.emit(QtCore.SIGNAL("dropped"), links) 
     else: 
      event.ignore() 

class Dialog_01(QtGui.QMainWindow): 
    def __init__(self): 
     super(QtGui.QMainWindow,self).__init__() 
     self.listItems={} 

     myQWidget = QtGui.QWidget() 
     myBoxLayout = QtGui.QVBoxLayout() 
     myQWidget.setLayout(myBoxLayout) 
     self.setCentralWidget(myQWidget) 

     self.myListWidget = ThumbListWidget(self) 
     self.myListWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 
     self.myListWidget.connect(self.myListWidget, QtCore.SIGNAL("customContextMenuRequested(QPoint)"), self.listItemRightClicked) 

     myButton = QtGui.QPushButton("Add List Item") 

     myBoxLayout.addWidget(self.myListWidget) 
     myBoxLayout.addWidget(myButton) 
     myButton.clicked.connect(self.addListWidgetItem)     

    def addListWidgetItem(self): 
     listItemName='Item '+str(len(self.listItems.keys()))   
     self.listItems[listItemName]=None 
     self.rebuildListWidget() 

    def listItemRightClicked(self, QPos): 
     self.listMenu= QtGui.QMenu() 
     menu_item = self.listMenu.addAction("Remove Item") 
     if len(self.listItems.keys())==0: menu_item.setDisabled(True) 
     self.connect(menu_item, QtCore.SIGNAL("triggered()"), self.menuItemClicked) 

     parentPosition = self.myListWidget.mapToGlobal(QtCore.QPoint(0, 0))   
     self.listMenu.move(parentPosition + QPos) 

     self.listMenu.show() 

    def menuItemClicked(self): 
     if len(self.listItems.keys())==0: print 'return from menuItemClicked'; return 
     currentItemName=str(self.myListWidget.currentItem().text()) 
     self.listItems.pop(currentItemName, None) 
     self.rebuildListWidget() 

    def rebuildListWidget(self): 
     self.myListWidget.clear() 
     items=self.listItems.keys() 
     if len(items)>1: items.sort() 
     for listItemName in items: 
      listItem = QtGui.QListWidgetItem(listItemName, self.myListWidget) 
      self.listItems[listItemName]=listItem 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    dialog_1 = Dialog_01() 
    dialog_1.show() 
    dialog_1.resize(480,320) 
    sys.exit(app.exec_()) 
+1

根據我的經驗,當你必須處理插入,刪除,排序,排序之類的,你一般有使用'QListView'(基於視圖模型)比'QListWidget'(基於項)更好。 'QAbstractItemModel'具有排序,插入等所需的所有插槽。 – Hyperboreus

+0

關於項目3:「更好」和「更強大」是什麼意思? – ekhumoro

+0

現在,sort()以時尚的形式列出字符串,例如:'Item 2','Item 20','Item 3','Item 4'end等。這個簡單的字符串排序沒有任何邏輯。其次,在self.listItems字典中排序的listItem名稱和它們的QT對象將不允許創建兩個或多個具有相同名稱的列表項目,因爲它們被用作字典鍵。我想知道是否還有其他更好的「流行」方法可以做到這一點......因爲我在這裏使用它的方式都是從我的頭上開始的。 – alphanumeric

回答

17

列表的控件項目可以移動起來,並通過拖放下來,但它不是默認啓用的。要打開它,這樣做:

self.listWidget.setDragDropMode(QtGui.QAbstractItemView.InternalMove) 

多選是幾selection-modes可用之一。要打開它,請執行以下操作:

self.listWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) 

排序在默認情況下處於禁用狀態。要打開它,這樣做:

self.listWidget.setSortingEnabled(True) 

要重新排序列表中,執行下列操作之一:

self.listWidget.sortItems() # ascending by default 
    self.listWidget.sortItems(QtCore.Qt.DescendingOrder) 

排序是按字母順序和不區分大小寫的默認。如果你想自定義排序次序,子類QListWidgetItem和重新實現其小於操作:

class ListWidgetItem(QtGui.QListWidgetItem): 
    def __lt__(self, other): 
     return self.text() < other.text() # or whatever