2013-04-02 8 views
0

Я изучаю PyQt4 (я использую версию 4.4.4), и я довольно новичок в Python (Python 2.5). У меня есть графический интерфейс с QListWidget и QPushButton. Я хочу, чтобы пользователь мог щелкнуть, чтобы выбрать запись в списке, а затем нажать кнопку QPushButton и удалить выбранную запись (удалить из QList). Я уже несколько недель ударяю головой об этой проблеме, и я бы очень признателен за помощь.PyQt4: Использование виджета QPushButton для удаления элемента из виджета QList

В настоящее время появляется мой графический интерфейс, и я могу выбрать разные элементы списка (только по одному за раз прямо сейчас), но когда я нажимаю QPushButton, ничего не происходит. Цвет выделения идет от синего до серого, но запись не удаляется. В командной строке не отображается ошибка (Windows 7).

Я определил функцию, remove(), которую я использую в качестве слота для QPushButton. Я считаю, что QPushButton.connect правильно определена для Qt Signal to Python Slot, основываясь на том, что я видел в ответах на подобные проблемы, но элементы не удаляются. Однако функция удаления даже не запускается. У меня есть инструкция print внутри функции, но она не вызывается, когда я нажимаю QPushButton, и я знаю, что функция не вызывается.

Вот мой последний код: (Я прочитал сообщение rant-y о мета-SO о больших блоках кода, поэтому я сократил это до битов, которые, на мой взгляд, актуальны: создание списка, создание кнопки и функция удаления, которую я пытаюсь использовать в качестве слота. Я оставил в комментариях, которые указывают, что представляют собой другие разделы, поэтому, если вы считаете, что я упустил что-то, что могло бы помочь, сообщите мне и Я добавлю его обратно)

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()) 

... 

Я попытался опубликовать изображение, но у меня недостаточно репутации. Если вы думаете, что изображение будет полезно, сообщите мне, и я могу отправить его вам.

+0

PyQt 4.4.4 действительно старый. Есть ли причина использовать такую ​​древнюю версию? – Avaris

+0

Во-первых: Я работаю в качестве оборонного подрядчика. Наш отдел ИТ. поддерживает строго контролируемый список «одобренных» программ, который всегда имеет ряд версий. Я все еще работаю с Python 2.5. Да, это глупо. Во-вторых: я также не являюсь администратором на своем собственном компьютере, поэтому я не могу просто загрузить это программное обеспечение с открытым исходным кодом и использовать их, чтобы обойти ИТ. В-третьих, и самое главное: это часть проекта по обновлению старой внутренней программы в Py2.5 и PyQt4.4.4, которая длится 1000 строк и постоянно используется. Не в сети, чтобы переписать все это в Py3.0, а PyQt5 не вариант. – SatelliteEyes

+0

Я вижу. Версия не связана с вашей проблемой. Это просто показалось мне «странным». Но если это связано с каким-то устаревшим кодом, это имеет смысл. – Avaris

ответ

1

Вы смешали сигналы:

deleteButton.connect(deleteButton,QtCore.SIGNAL('itemClicked(clicked)'),lambda: self.remove) 

deleteButton является QPushButton, но itemClicked(clicked)выглядит сигнал от QListWidget с неправильной подписью. Так как QPushButton не имеет этого сигнала, соединение не производится. Qt не вызывает ошибок для неудачных подключений, но метод .connect имеет возвращаемое значение bool, указывающее на успешность/неудачу попытки подключения.

Также lambda: self.remove как слот не имеет смысла. Слот должен быть вызываемым, вызываемым при испускании сигнала. Конечно, lambda создает функцию, но все, что вы делаете, это ссылка метод self.remove. lambda будет называться, self.remove нет. Просто self.remove в качестве слота достаточно.

Вы должны использовать clicked() сигнал (или clicked(bool), если вы заботитесь о значении checked) от кнопки:

deleteButton.connect(deleteButton, QtCore.SIGNAL('clicked()'), self.remove) 

Edit

Еще одна проблема: Ваш метод remove не делает то, что вы хотеть. removeItemWidget не удаляет вещь, он удаляет виджет внутри предмета (если вы его установили). Это аналог setItemWidget.

Чтобы удалить предметы, необходимо устранить ошибки takeItem.

def remove(self): 
    self.qList.takeItem(self.qList.currentRow()) 
+0

Это работает! Большое вам спасибо за вашу помощь! Я думал, что мне по существу нужны два сигнала: щелкните по списку, чтобы выбрать элемент, и нажмите кнопку, чтобы удалить его. itemClicked - это функция QListWidget, и это была моя попытка использовать оба этих сигнала. Теперь я понимаю, что это необязательно, так как нажатие на запись списка автоматически обновляет текущую строку или элемент, поэтому явно не нужно указывать, что элемент был нажат. – SatelliteEyes

+0

@Avaris посмотрите на вопрос http://stackoverflow.com/questions/16221810/how-to-handle-mouse-events-in-qt. Благодарю. – Alex