Передача аргументов с сигналами Newstyle в PyQT - PullRequest
0 голосов
/ 28 сентября 2010

У меня были некоторые проблемы с набором динамически создаваемых кнопок в PyQT.

Я использую список для создания кнопок, соответствующих различным значениям. Поскольку каждая кнопка отличается, мне нужно, чтобы они передавали аргумент функции «Нажатие кнопки», идентифицируя себя отдельно, чтобы я мог выполнять с ними различные действия. Вот то, что я имею до сих пор:

for x in self.buttons:
    name = str(x)
    button = QtGui.QPushButton(Frame)
    button.setText(name)
    cp_result = self.changeProject(name)
    if cp_result is None:
        print 'changeProject(%s) is None!', name
    else:
        print 'changeProject(%s) is OK (%r)', name, cp_result
        #button.clicked.connect(cp_result)
    setattr(self, "btn_%s" % name, button)
    self.btnList.append(button)

def changeProject(self, name):
    for x in self.btnList:
        if x.isDown:
            #Change UI Frame to blahblah
    return 'A String'

Работая с Алексом, это последний код, проверяющий возвращаемое значение в changeProject, которое явно не может быть строкой, но мне все еще нужно определить, какая кнопка нажата между автоматически сгенерированными кнопками.

Текущая ошибка: TypeError: connect() slot argument should be a callable or a signal, not 'str'

Ответы [ 6 ]

1 голос
/ 28 сентября 2010

В сообщении об ошибке говорится, что self.changeProject("%s") для одного из значений, которое вы подставляете для этого %s, возвращает None. Предположительно, вы хотели, чтобы этот метод возвратил что-то другое?

Невозможно помочь вам с задачей дальнейшей отладки changeProject, конечно, не увидев код для нее. Однако, вы можете, например, разделить вызов на что-то вроде (как только вы избавитесь от этой тонны руководителей согласно совету lazy1):

cp_result = self.changeProject(name)
if cp_result is None:
    logging.error('changeProject(%s) is None!', name)
else:
    logging.info('changeProject(%s) is OK (%r)', name, cp_result)
    button.clicked.connect(cp_result)

Таким образом, вместо бесполезной попытки «подключиться к None», вы увидите все имена, вызывающие неожиданное возвращаемое значение в журнале ошибок, а затем сможете продолжить отладку на основе этой информации. Однако, скорее всего, ваша ошибка может стать очевидной, если взглянуть на источник changeProject.

Редактировать : аргумент connect, конечно, исходит от changeProject (а не от другого connect! -) - исправлен фрагмент соответственно.

1 голос
/ 28 сентября 2010

Вы можете динамически добавлять атрибуты к объектам, используя setattr

for x in buttons:
    name = str(x)
    button = QtGui.QPushButton(Frame)
    button.setText(name)
    button.clicked.connect(self.changeProject(name))
    setattr(self, "btn_%s" % name, button)
0 голосов
/ 18 ноября 2011

Я хотел бы это сделать и упомянуть другую стратегию / хак, которую я только что использовал, чтобы решить эту стратегию. Это довольно специфическая стратегия, которая не всегда будет работать, но то, что я решил сделать для более поздней реализации этого вида установки, установило кнопки как проверяемые.

Это оказалось путем наименьшего сопротивления, так как тогда я мог перебирать макет и просто проверять, какая кнопка верна для .isChecked (). Нет необходимости в SignalMapping или дополнительных атрибутах.

0 голосов
/ 04 марта 2011

QSignalMapper - это общепринятый способ сделать это с помощью Qt, но я обнаружил, что с PyQt это несколько обременительно, поскольку есть несколько более простых доступных опций. Возможно, проще всего: 1) пометить каждую кнопку уникальным идентификатором, чтобы вы могли различить их (или просто использовать текст кнопки), затем 2) использовать QObject.sender (), чтобы определить, какая кнопка испустила сигнал. Например:

for x in self.buttons:
    name = str(x)
    button = QtGui.QPushButton(Frame)
    button.setText(name)
    button.uniqueId = name  ## make this whatever you want..
    button.clicked.connect(buttonClicked)

def buttonClicked():
    button = QObject.sender()
    uid = button.uniqueId  ## got your ID back
0 голосов
/ 01 октября 2010

Спасибо за помощь.Я наткнулся на QSignalMapper, и это оказалось именно то, что мне нужно.

http://pysnippet.blogspot.com/2010/06/qsignalmapper-at-your-service.html

0 голосов
/ 28 сентября 2010

Я думаю, что вы запускаете 'exec' слишком много, IMO.Ваша проблема в том, что вы пытаетесь подключиться к .clicked () QPushButton, который действительно является сигналом.Вы действительно должны передать аргумент здесь exec 'self.btn_%s.clicked.connect(self.changeProject("%s"))' % (x, x)Потому что если вы не можете подключить его так:self.connect(self.btn_%s, SIGNAL('clicked()'), self.changeProject)Если вам нужно узнать, какая кнопка нажата, вы можете пройти по списку, чтобы найти, какая кнопка нажата:for x in buttons:<br /> if x.isDown(): (function)

Вы также можете использовать pyqtSignal.

...