问题描述
代码构建了一个带有单个 QListWidget 和单个 QPushButton 的对话框.
The code builds a dialog box with a single QListWidget and a single QPushButton.
单击该按钮会添加一个列表项.
Clicking the button adds a single List Item.
右键单击列表项会弹出一个右键菜单,其中包含删除项"命令.
Right-click on a List Item brings up a right-click menu with "Remove Item" command available.
选择移除项目"命令会从列表小部件中移除一个列表项目.
Choosing "Remove Item" command removes a List Item from List Widget.
看看如何实现以下 ListWidgets 操作会很有趣:
Would be interesting to see how the following ListWidgets ops could be implemented:
- 能够上下移动列表项(重新排列).
- 能够多选和多删除列表项.
- 更好更健壮的列表项排序.
示例:
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_())
推荐答案
List-widget项目可以通过拖放上下移动,但默认不启用.要打开它,请执行以下操作:
List-widget items can be moved up and down via drag and drop, but it is not enabled by default. To switch it on, do this:
self.listWidget.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
多重选择是几个可用的选择模式之一.要打开它,请执行以下操作:
Multiple-selection is one of several selection-modes available. To switch it on, do this:
self.listWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
默认情况下禁用排序.要打开它,请执行以下操作:
Sorting is disabled by default. To switch it on, do this:
self.listWidget.setSortingEnabled(True)
要重新排序列表,请执行以下操作之一:
To re-sort the list, do one of these:
self.listWidget.sortItems() # ascending by default self.listWidget.sortItems(QtCore.Qt.DescendingOrder)
默认情况下,排序是按字母顺序和不区分大小写的.如果您想要自定义排序顺序,请继承 QListWidgetItem 并重新实现其小于运算符:
Sorting is alphabetical and case-insensitive by default. If you want a custom sort-order, subclass QListWidgetItem and re-implement its less-than operator:
class ListWidgetItem(QtGui.QListWidgetItem): def __lt__(self, other): return self.text() < other.text() # or whatever