PyQt: Come ottenere la maggior parte di QListWidget

Codice costruisce una finestra di dialogo con un singolo QListWidget e una singola QPushButton.

Clic sul pulsante aggiunge un singolo Elemento della Lista.

Fare clic su una Voce dell’Elenco apre un menu di right-click con “elimina Voce” comando disponibili.

Scegliendo “Rimuovi Voce” comando rimuove un Elemento di una Lista, dalla Lista dei Widget.

Sarebbe interessante vedere come il seguente ListWidgets ops potrebbe essere implementato:

  1. Possibilità di spostare gli elementi di una lista in su e in giù (ri-organizzare).
  2. Essere in grado di multi-selezionare e multi-eliminare gli elementi dell’elenco.
  3. Una migliore e più robusto elenco elementi di ordinamento.

Esempio:

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_())
  • Nella mia esperienza, quando è necessario gestire l’inserimento, la cancellazione, ordinamento, ordinamento e simili, si hanno generalmente un tempo migliore utilizzo QListView (view-model-based) che QListWidget (item-based). QAbstractItemModel ha tutti gli slot necessari per la selezione, inserimento, etc.
  • Sul punto 3: che cosa significa “migliore” e “più robusto” significa?
  • Come è ora, sort() liste di stringhe di moda come “Elemento 2′, ‘Voce 20’, ‘Articolo 3’, ‘Articolo 4’ fine etc. Non c’è logica dietro a questa semplice stringa di ordinamento. In secondo luogo, il listItem nomi e le loro QT ordinamento degli Oggetti in sé.listItems dizionario che non consentono a due o più Elementi di una Lista con lo stesso nome per essere creato in quanto questi sono utilizzati come chiavi del dizionario. Mi chiedo se ci sono altri meglio più ‘popolare’, modi per farlo… visto il modo che ho usato qui è tutto dalla mia testa.
  • L’ordinamento è alfabetico e case-insensitive, che sembra ragionevole (e logico) di default. Non capisco lo scopo del listItems dict o il rebuildListWidget metodo nel tuo esempio, entrambi sembrano ridondanti.
  • Sarebbe interessante vedere come questo potrebbe essere fatto in modo diverso! Post-it!
  • Tutta questa roba è già inclusa nel QListWidget API: basta accenderlo (vedi la mia risposta).

InformationsquelleAutor alphanumeric | 2014-03-18



One Reply
  1. 21

    Elenco-widget elementi possono essere spostati su e giù tramite drag and drop, ma non è abilitato per impostazione predefinita. Per accenderlo, fare questo:

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

    Selezione multipla è una delle più selezione-modalità di disponibili. Per accenderlo, fare questo:

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

    Ordinamento è disattivata per impostazione predefinita. Per accenderlo, fare questo:

        self.listWidget.setSortingEnabled(True)

    Di ri-ordinare l’elenco, fare uno di questi:

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

    L’ordinamento è alfabetico e minuscole, per impostazione predefinita. Se vuoi personalizzare l’ordinamento, sottoclasse QListWidgetItem e re-implementare il suo operatore minore di:

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

Lascia un commento