Подтвердить что ты не робот

Как передать аргументы функциям нажатием кнопки в PyQt?

Я хочу передать аргументы функции, когда я нажимаю кнопку. Что мне следует добавить в эту строку button.connect(button, QtCore.SIGNAL('clicked()'), calluser(name)), чтобы передать значение функции:

def calluser(name):
    print name

def Qbutton():
    button = QtGui.QPushButton("button",widget)
    name = "user"
    button.setGeometry(100,100, 60, 35)
    button.connect(button, QtCore.SIGNAL('clicked()'), calluser(name))

Еще одна вещь: кнопки будут сгенерированы с использованием цикла for; поэтому значение name будет отличаться. Поэтому я хочу прикрепить каждое имя с помощью кнопки. Я сделал то же самое в Pytk, используя цикл for и вызывая функцию базы аргументов при нажатии.

4b9b3361

Ответ 1

Обычно графические интерфейсы создаются с использованием классов. Используя связанные методы как обратные вызовы (см. Ниже self.calluser), вы можете "передать" информацию обратному сообщению через атрибуты self (например, self.name):

Например, используя слегка измененный код из этот учебник:

import sys
import PyQt4.QtCore as QtCore
import PyQt4.QtGui as QtGui

class QButton(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.button = QtGui.QPushButton('Button', self)
        self.name='me'
        self.button.clicked.connect(self.calluser)
    def calluser(self):
        print(self.name)

def demo_QButton():
    app = QtGui.QApplication(sys.argv)
    tb = QButton()
    tb.show()
    app.exec_()

if __name__=='__main__':
    demo_QButton()

Поскольку callback per se всегда вызывается без дополнительных аргументов, когда вам нужно передать отдельную дополнительную информацию ко многим обратным вызовам, вам нужно сделать разные обратные вызовы для каждой кнопки.

Так как это может быть трудоемким (если сделано вручную), вместо этого используйте функцию factory. Ниже приведен пример. Функция factory является замыканием. Ему могут передаваться дополнительные аргументы, к которым внутренняя функция может обращаться при вызове:

class ButtonBlock(QtGui.QWidget):

    def __init__(self, *args):
        super(QtGui.QWidget, self).__init__()
        grid = QtGui.QGridLayout()
        names = ('One', 'Two', 'Three', 'Four', 'Five',
                 'Six', 'Seven', 'Eight', 'Nine', 'Ten')
        for i, name in enumerate(names):
            button = QtGui.QPushButton(name, self)
            button.clicked.connect(self.make_calluser(name))
            row, col = divmod(i, 5)
            grid.addWidget(button, row, col)
        self.setLayout(grid)

    def make_calluser(self, name):
        def calluser():
            print(name)
        return calluser

app = QtGui.QApplication(sys.argv)
tb = ButtonBlock()
tb.show()
app.exec_()

Ответ 2

Я попробовал эффективный способ сделать это, и это сработало хорошо для меня. Вы можете использовать код:

from functools import partial

def calluser(name):
    print name

def Qbutton():
    button = QtGui.QPushButton("button",widget)
    name = "user"
    button.setGeometry(100,100, 60, 35)
    button.clicked.connect(partial(calluser,name))

Ответ 3

Вот еще один способ. --- PARTIAL - я считаю это самым простым:

    widget = QWidget()
    widgetLayout = QVBoxLayout()

    for action in list:

        button = QPushButton("{action}".format(action=action['name']),self)
        button.clicked.connect(partial(self.action_selected,action=action['name']))
        widgetLayout.addWidget(button)

    widget.setLayout(widgetLayout)

def action_selected(self,action):
    print action

найдено: http://tech-artists.org/forum/showthread.php?3118-PyQt-Maya-How-to-pass-arguments-to-a-function-when-connecting-it-to-PyQt-button

Ответ 4

Приведенный ниже код иллюстрирует метод связывания данных с созданными кнопками. Например, вы можете изменить оператор self.keydata[b] = key для хранения кортежа данных в self.keydata[b] для использования при последующей обработке события кнопки.

Обратите внимание, что в следующем коде assets является ранее определенным словарем, содержащим заголовки для кнопок. В подпрограмме processButton(self) self.sender() равно записи в переменной класса buttons[].

class Tab5(QtGui.QWidget):
    buttons, keydata = {}, {}
    def __init__(self, fileInfo, parent=None):
        super(Tab5, self).__init__(parent)
        layout = QtGui.QVBoxLayout()

        for key in sorted(assets):
            b = self.buttons[key] = QtGui.QPushButton(assets[key], self)
            b.clicked.connect(self.processButton)
            layout.addWidget(b)
            print 'b[key]=',b, ' b-text=',assets[key]
            self.keydata[b] = key

        layout.addStretch(1)
        self.setLayout(layout)

    def processButton(self):
         print 'sender=',self.sender(), ' s-text=',self.sender().text(), ' data[.]=', self.keydata[self.sender()] 
         pass

Выход был следующим: где первые четыре строки были напечатаны во время цикла for, а последние четыре были напечатаны, когда четыре кнопки были нажаты в порядке.

b[key]= <PySide.QtGui.QPushButton object at 0x7f382f2ca830>  b-text= K1
b[key]= <PySide.QtGui.QPushButton object at 0x7f382f2ca908>  b-text= K2
b[key]= <PySide.QtGui.QPushButton object at 0x7f382f2ca950>  b-text= K3
b[key]= <PySide.QtGui.QPushButton object at 0x7f382f2ca998>  b-text= K4
sender= <PySide.QtGui.QPushButton object at 0x7f382f2ca830>  s-text= K1  data[.]= L1
sender= <PySide.QtGui.QPushButton object at 0x7f382f2ca908>  s-text= K2  data[.]= L2
sender= <PySide.QtGui.QPushButton object at 0x7f382f2ca950>  s-text= K3  data[.]= L3
sender= <PySide.QtGui.QPushButton object at 0x7f382f2ca998>  s-text= K4  data[.]= L4

Ответ 5

В Python экземпляры экземпляров вызываются. Вы можете просто использовать экземпляр класса как функцию. Этот класс может содержать все, что вы хотите. (В некоторых языках или фреймах вызываемый объект называется функтором или объектом функции.)

class CallUser:
    def __init__(self, name):
        self.name = name
    def __call__(self):
        print(self.name)

def Qbutton():
    button = QtGui.QPushButton("button",widget)
    name = "user"
    button.setGeometry(100,100, 60, 35)
    button.clicked.connect(CallUser(name))
    # Object of type CallUser will work as a function!

Ответ 6

Вы можете просто написать

name = "user"
button.clicked.connect(lambda: calluser(name))