I am learning PyQt4 (I am using version 4.4.4) and I'm pretty new to Python (Python 2.5). I have a GUI with a QListWidget and a QPushButton. I want a user to be able to click to select an entry in the list and then click the QPushButton and have the selected entry go away (be deleted from the QList). I've been banging my head against this problem for over a week and I would deeply appreciate some help.
Currently, my GUI comes up and I can select different list items (only one at a time right now), but when I click the QPushButton, nothing happens. The selection color goes from blue to grey, but the entry is not removed. No error is shown in Command Prompt (Windows 7).
I have defined a function, remove(),which I am using as the slot for the QPushButton. I believe the QPushButton.connect is defined correctly for a Qt Signal to Python Slot, based on what I've seen of answers to similar problems, but the items are not being deleted. However, the remove function is not even being triggered. I have a print statement within the function, but it is not being called when I click the QPushButton, which is how I know that the function is not being called.
Here is my most recent code: (I read a very rant-y post on meta-SO about big blocks of code, so I've cut this down to the bits I think are relevant: the list creation, the button creation and the remove function, which I'm trying to use as a slot. I've left in comments that indicate what the other sections are, so if you think I've left out something that could help, let me know and I'll add it back in)
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())
...
I tried to post an image, but I don't have enough reputation. If you think an image would be useful, let me know and I can send it to you.
You mixed the signals:
deleteButton.connect(deleteButton,QtCore.SIGNAL('itemClicked(clicked)'),lambda: self.remove)
deleteButton
is a QPushButton
, but itemClicked(clicked)
looks like the signal from QListWidget
with wrong signature. Since, QPushButton
doesn't have this signal, no connection is made. Qt doesn't raise errors for failed connections, but .connect
method has a bool
return value indicating success/failure of the attempted connection.
Also, lambda: self.remove
as a slot doesn't make sense. Slot should be a callable that is called upon signal emit. Sure, lambda
creates a function, but all you do is reference the method self.remove
. lambda
will be called, self.remove
not. Just self.remove
as a slot is enough.
You should use clicked()
signal (or clicked(bool)
, if you care about the checked
value) from button:
deleteButton.connect(deleteButton, QtCore.SIGNAL('clicked()'), self.remove)
Edit
Another problem: Your remove
method doesn't do what you want. removeItemWidget
doesn't remove the item, it removes the widget inside the item (if you set one). It's counterpart to setItemWidget
.
You should use takeItem
to remove items.
def remove(self):
self.qList.takeItem(self.qList.currentRow())