PyQt4: Использование виджета QPushButton для удаления элемента из виджета QList

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

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

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

Вот мой самый последний код: (Я прочитал очень напыщенный пост на meta-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())

...

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


person SatelliteEyes    schedule 02.04.2013    source источник
comment
PyQt 4.4.4 действительно старый. Есть ли смысл использовать такую ​​древнюю версию?   -  person Avaris    schedule 03.04.2013
comment
Во-первых: я работаю на подрядчика защиты. Наш ИТ-отдел. ведет строго контролируемый список «одобренного» программного обеспечения, за которым всегда стоит несколько версий. Я все еще работаю с Python 2.5. Да это тупо. Во-вторых: я также не являюсь администратором на своем компьютере, поэтому я не могу просто загрузить это программное обеспечение с открытым исходным кодом и использовать его, чтобы обойти ИТ. В-третьих, что наиболее важно: это часть проекта по обновлению старой внутренней программы на Py2.5 и PyQt4.4.4, которая состоит из 1000 строк и постоянно используется. Вывести его в автономный режим для перезаписи всего этого в Py3.0 и PyQt5 не вариант.   -  person SatelliteEyes    schedule 04.04.2013
comment
Я понимаю. Версия не связана с вашей проблемой. Это просто показалось мне странным. Но если это связано с каким-то унаследованным кодом, это имеет смысл.   -  person Avaris    schedule 04.04.2013


Ответы (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)

Изменить

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

Вы должны использовать takeItem для удаления элементов.

def remove(self):
    self.qList.takeItem(self.qList.currentRow())
person Avaris    schedule 04.04.2013
comment
Это работает! Большое вам спасибо за вашу помощь! Я думал, что мне, по сути, нужны два сигнала: щелчок по списку, чтобы выбрать элемент, и щелчок по кнопке, чтобы удалить его. itemClicked - это функция QListWidget, и это была моя попытка использовать оба этих сигнала. Теперь я понимаю, что в этом нет необходимости, поскольку щелчок по записи в списке автоматически обновляет текущую строку или элемент, поэтому явное указание на щелчок по элементу не требуется. - person SatelliteEyes; 04.04.2013
comment
@Avaris, пожалуйста, посмотрите вопрос stackoverflow .com / questions / 16221810 /. Спасибо. - person Alex; 26.04.2013