2010-01-21 10 views

Odpowiedz

3

Gdy jesteś w gnieździe, możesz użyć metody sender() (wystarczy wywołać self.sender()), a otrzymasz referencję do obiektu, z którego został wyemitowany sygnał. Here jest dokumentacja na ten temat.

2

Poddałbym się podklasie QPushButton i zdefiniowałam własnego nadawcę i gniazdo. Metoda QObject.sender() jest kusząca, ale daje mi hebebie-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) 

Nieco bardziej pythonowy sposób w ten sposób mógł zdefiniować zachowanie w klasie, tak jak poniżej:

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) 
+0

Poważnie, nie ma nic złego z nadawcą(). Użyłem go całkiem sporo i działa dobrze. Należy jednak zachować ostrożność. Zwykle używam twojej metody podczas sygnalizowania zewnętrznie (tj. Do innych obiektów), ale nadawcy() podczas trasowania sygnałów wewnątrz klasy. – Macke

+0

Nie może być nic złego w .sender(), ale jak mówi dokumentacja, to "narusza obiektową zasadę modułowości". Co prawda nie byłaby to śmierć nikogo. Mogę być kuszony, by użyć go jako "szybkiej i brudnej" poprawki. Ale Python sprawia, że ​​tak łatwo zrobić to lepiej i czystsze, prawdopodobnie lepiej jest zrobić to dobrze, na dłuższą metę. –

+0

+1 Subklasowanie jest złe, zasady funkcji zewnętrznych rządzą :)) – mlvljr

1

Jak gruszcsy powiedział, nie ja. sender() (w QObject), aby uzyskać dokładne informacje.

Istnieje również klasa QSignalMapper, która zapewnia mapowanie wyższego poziomu od kilku nadajników sygnału do jednego gniazda. Pomaga w podstawowych przypadkach mapowania wiele/jeden sygnał/gniazdo.

Sugestia Chrisa B o zdefiniowaniu nowego slotu, który transmituje nadawcę jako parametr, jest nieco bardziej skomplikowana, ale czystsza pod względem struktury programu i rozdziału klas. Używam tej metody, gdy docelowy bok znajduje się w innym obiekcie. Do odwzorowania w prywatnym automacie klasy, sender() jest zarówno czysty, jak i całkiem odpowiedni, IMO.

0

Oto mała aplikacja wykazując jedno możliwe rozwiązanie:

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

Proszę cieszyć :)