PyQt4, как добавить пакет виджета (QPushButton) за один раз и позволить им выполнять на слоте - PullRequest
7 голосов
/ 21 января 2010

, если я хочу добавить 10 QPushButton одновременно:

NumCount=20
for i in range(NumCount):
  btn=QPushButton("%s %s" %("Button" i+1),self)
  btn.clicked.connect(self.btnclick)

def btnclick(self):
  # here is my question 
  # how to define which button clicked?
  # how to print btn.text?

как указано в def (btnclick).

Ответы [ 4 ]

3 голосов
/ 27 января 2010

Когда вы находитесь в слоте, вы можете использовать метод sender () (просто вызовите self.sender ()), и вы получите ссылку на объект, с которого был испущен сигнал. Здесь - документация об этом.

2 голосов
/ 19 февраля 2010

Я бы подкласс QPushButton и определить мой собственный отправитель и слот. QObject.sender() Метод заманчиво, но это дает мне нервное возбуждение.

class MyPushButton(QPushButton):
    def __init__(self, text = '', parent = None):
        QPushButton.__init__(self, text, parent)
        self.clicked.connect(self._handle_click)

    my_click = QtCore.pyqtSignal(QObject)

    def _handle_click(self):
        my_click.emit(self)

def btnclick(btn):
    print 'Handle button %s' % btn

for i in xrange(20):
    btn = MyPushButton('%s %s' % ('Button', i + 1), self)
    btn.my_click.connect(btnclick)

Немного более Pythonic способ сделать это может определить поведение в классе, например, так:

class MyPushButton(QPushButton):
    def __init__(self, button_number, parent = None):
        QPushButton.__init__(self, '%s %s' % ('Button', button_number), parent)
        self.button_number = button_number
        self.clicked.connect(self._handle_click)

     def _handle_click(self):
        print 'Handle button %s' % self

for i in xrange(20):
    btn = MyPushButton(i + 1, self)
1 голос
/ 19 февраля 2010

Как сказал gruszcsy, есть self. sender () (в QObject), чтобы получить эту точную информацию.

Существует также класс QSignalMapper , который обеспечивает высокоуровневое отображение от нескольких отправителей сигналов в один слот. Это помогает в основных случаях сопоставления сигнал / слот многие-к-одному.

Предложение Криса Б. об определении нового слота, который передает отправителя в качестве параметра, немного сложнее, но чище с точки зрения структуры программы и разделения между классами. Я склонен использовать этот метод, когда целевой слот находится в другом объекте. Для отображения внутри частного слота класса sender () является аккуратным и вполне подходящим, IMO.

0 голосов
/ 19 февраля 2010

Вот небольшое приложение, демонстрирующее одно из возможных решений:

from PyQt4.QtGui import QPushButton, QWidget
from PyQt4.QtGui import QVBoxLayout, QApplication

def smart_connect(btn, btn_click_slot):
    proxy_slot = lambda checked: btn_click_slot(btn)
    btn.clicked.connect(proxy_slot)

class MyWidget(QWidget):
    btn_count = 4
    def __init__(self):
        super(MyWidget, self).__init__()
        lt = QVBoxLayout(self)
        for i in range(self.btn_count):
            btn = QPushButton("Button %s"%(i+1))
            smart_connect(btn, self.btn_click)
            lt.addWidget(btn)
    def btn_click(self, btn):
        print "Button '%s' was clicked."%btn.text()

app = QApplication([])
wgt = MyWidget()
wgt.show()
app.exec_()

Пожалуйста, наслаждайтесь:)

...