【发布时间】:2014-04-24 16:53:20
【问题描述】:
代码构建了一个带有单个 QListWidget 和单个 QPushButton 的对话框。
单击按钮会添加一个列表项。
右键单击列表项会弹出一个右键菜单,其中包含可用的“删除项”命令。
选择“移除项目”命令会从列表小部件中移除一个列表项目。
看看如何实现以下 ListWidgets 操作会很有趣:
- 能够上下移动列表项(重新排列)。
- 能够多选和多删除列表项。
- 更好更健壮的列表项排序。
示例:
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_())
【问题讨论】:
-
根据我的经验,当您必须处理插入、删除、排序、排序等操作时,使用
QListView(基于视图模型)通常比QListWidget(基于项目)。QAbstractItemModel拥有排序、插入等所需的所有插槽。 -
关于第 3 项:“更好”和“更健壮”是什么意思?
-
就像现在一样,sort() 以时尚的方式列出字符串,例如:'Item 2'、'Item 20'、'Item 3'、'Item 4' end 等。后面没有逻辑这个简单的字符串排序。其次,在 self.listItems 字典中排序的 listItem 名称及其 QT 对象不允许创建两个或多个具有相同名称的列表项,因为它们用作字典键。我想知道是否还有其他更好更“流行”的方式来做到这一点......因为我在这里使用它的方式完全是我的想法。
-
排序是按字母顺序排列且不区分大小写,这似乎是一个合理(且合乎逻辑)的默认设置。我不明白您示例中
listItemsdict 或rebuildListWidget方法的目的,这两者似乎都是多余的。 -
看看如何以不同的方式完成会很有趣!发布吧!
标签: python drag-and-drop pyqt pyqt4 qlistwidget