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)

deleteButtonQPushButton,但itemClicked(clicked) 看起来来自QListWidget 的信号签名错误。因为QPushButton 没有这个信号,所以没有建立连接。 Qt 不会为失败的连接引发错误,但 .connect 方法有一个 bool 返回值,指示尝试连接的成功/失败。

另外,lambda: self.remove 作为一个插槽没有意义。 Slot 应该是在信号发射时调用的可调用对象。当然,lambda 创建了一个函数,但您所做的只是引用方法self.removelambda 将被调用,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 捕获屏幕,除了特定的小部件?

PyQt4 - 从 QListWidget 中删除项目小部件

PyQt4关闭窗口

PyQt4 - 自定义小部件类结构?

PyQt4开关按钮ToggleButton

在多个小部件上显示相同的 QPushButton