PyQt4:使用 QPushButton 小部件从 QList 小部件中删除项目
Posted
技术标签:
【中文标题】PyQt4:使用 QPushButton 小部件从 QList 小部件中删除项目【英文标题】:PyQt4: Using a QPushButton widget to delete an item from QList widget 【发布时间】:2013-04-02 21:33:55 【问题描述】:我正在学习 PyQt4(我使用的是 4.4.4 版),而且我对 Python(Python 2.5)还很陌生。我有一个带有 QListWidget 和 QPushButton 的 GUI。我希望用户能够单击以选择列表中的条目,然后单击 QPushButton 并使所选条目消失(从 QList 中删除)。一个多星期以来,我一直在努力解决这个问题,我将非常感谢一些帮助。
目前,我的 GUI 出现了,我可以选择不同的列表项(现在一次只能选择一个),但是当我单击 QPushButton 时,什么也没有发生。选择颜色从蓝色变为灰色,但不会删除条目。命令提示符中未显示错误 (Windows 7)。
我已经定义了一个函数 remove(),我将它用作 QPushButton 的插槽。我相信 QPushButton.connect 是为 Qt Signal to Python Slot 正确定义的,基于我所看到的类似问题的答案,但这些项目没有被删除。但是,删除功能甚至没有被触发。我在函数中有一个打印语句,但是当我单击 QPushButton 时它没有被调用,这就是我知道该函数没有被调用的方式。
这是我最近的代码:(我在 meta-SO 上阅读了一篇关于大代码块的非常咆哮的帖子,因此我将其缩减为我认为相关的部分:列表创建、按钮创建和删除功能,我试图将其用作插槽。我在 cmets 中留下了指示其他部分的内容,所以如果您认为我遗漏了一些可以提供帮助的内容,请告诉我,我'将其添加回来)
class questionGUI(QtGui.QWidget):
#This class is the window of the gui.
def __init__(self):
super(questionGUI,self).__init__()
#Layout
grid = QtGui.QGridLayout()
grid.setSpacing(10)
#Labels Needed
...
#Question List
self.qList = QtGui.QListWidget()
#print self.qList
self.qList.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
entries = ['[Pick Image] <Default>','[Slider Question] <Default>', '[Comment Box] <Default>']
for i in entries:
item = QtGui.QListWidgetItem(i)
self.qList.addItem(item)
#Type select
...
#Text insert Needed
...
#Buttons Needed
deleteButton = QtGui.QPushButton('Delete Question')
deleteButton.connect(deleteButton,QtCore.SIGNAL('itemClicked(clicked)'),lambda: self.remove)
addQuestionButton = QtGui.QPushButton('Add Question')
...
doneButton = QtGui.QPushButton('Done')
...
#Parameters Needed
...
#Layout Placement and Window dimensions
...
def addQuestion(self):
...
def remove(self):
print 'remove triggered'
print self.qList.currentItem()
self.qList.removeItemWidget(self.qList.currentItem())
...
我尝试发布图片,但我没有足够的声誉。如果您认为某张图片有用,请告诉我,我可以将其发送给您。
【问题讨论】:
PyQt 4.4.4 真的很老了。有什么理由用这么古老的版本吗? 首先:我为一家国防承包商工作。我们的 IT 部门维护严格控制的“已批准”软件列表,该列表始终落后于多个版本。我仍在使用 Python 2.5。是的,这很愚蠢。其次:我也不是我自己计算机上的管理员,所以我不能只下载这个开源软件并使用它们来绕过 IT。第三,也是最重要的:这是更新旧的内部软件程序的项目的一部分,在 Py2.5 和 PyQt4.4.4 中,它有 1000 多行并且一直在使用。让它离线以在 Py3.0 和 PyQt5 中重写整个东西不是一种选择。 我明白了。版本与您的问题无关。它只是以“奇怪”的形式引起了我的注意。但是,如果它与一些遗留代码相关联,那就有意义了。 【参考方案1】:你混合了信号:
deleteButton.connect(deleteButton,QtCore.SIGNAL('itemClicked(clicked)'),lambda: self.remove)
deleteButton
是QPushButton
,但itemClicked(clicked)
看起来来自QListWidget
的信号签名错误。因为QPushButton
没有这个信号,所以没有建立连接。 Qt 不会为失败的连接引发错误,但 .connect
方法有一个 bool
返回值,指示尝试连接的成功/失败。
另外,lambda: self.remove
作为一个插槽没有意义。 Slot 应该是在信号发射时调用的可调用对象。当然,lambda
创建了一个函数,但您所做的只是引用方法self.remove
。 lambda
将被调用,self.remove
不会。只需self.remove
作为一个插槽就足够了。
您应该使用按钮中的clicked()
信号(或clicked(bool)
,如果您关心checked
值):
deleteButton.connect(deleteButton, QtCore.SIGNAL('clicked()'), self.remove)
编辑
另一个问题:您的 remove
方法不能满足您的要求。 removeItemWidget
不会删除item,它会删除inside 的小部件(如果您设置了)。它对应于setItemWidget
。
您应该使用takeItem
删除项目。
def remove(self):
self.qList.takeItem(self.qList.currentRow())
【讨论】:
这行得通!非常感谢你的帮助!我认为我基本上需要两个信号:单击列表以选择项目,然后单击按钮将其删除。 itemClicked 是一个 QListWidget 函数,我尝试使用这两个信号。我现在明白这是不必要的,因为单击列表条目会自动更新当前行或项目,因此不需要明确说明已单击项目。 @Avaris 请看问题***.com/questions/16221810/…。谢谢。以上是关于PyQt4:使用 QPushButton 小部件从 QList 小部件中删除项目的主要内容,如果未能解决你的问题,请参考以下文章
使用 PyQt4 或 PySide 捕获屏幕,除了特定的小部件?