PyQt4, How to add widget package (QPushButton) at a time and allows them to run on SLOT

if I want to add 10 QPushButton at a time:

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? 

as stated in def (btnclick).

+7
python signals pyqt sender
source share
4 answers

When you are in the slot, you can use the sender () method (just call self.sender ()), and you will get a link to the object from which the signal was issued. There is documentation about this here.

+3
source share

I would subclass QPushButton and define my own sender and slot. The QObject.sender() method is tempting, but it gives me heebie-jeebies.

 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) 

A slightly more Pythonic way of doing this can determine the behavior inside the class, for example:

 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) 
+2
source share

As gruszcsy said, I myself am sender () (in a QObject) to get the exact information.

There is also a QSignalMapper class that provides higher-level mapping from multiple signal senders to a single slot. This helps for basic multicast signal / slot mappings.

Chris B’s suggestion of defining a new slot that passes the sender as a parameter is a bit more complicated, but cleaner in terms of program structure and separation between classes. I try to use this method when the target slot is in another object. For matching inside a private class slot, sender () is neat and quite suitable, IMO.

+1
source share

Here is a small application demonstrating one possible solution:

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

Please enjoy :)

0
source share

All Articles