Sygnały i sloty PyQt4

Piszę moją pierwszą aplikację Pythona z PyQt4. Mam MainWindow i klasę Dialog, która jest częścią klasy MainWindow:

self.loginDialog = LoginDialog();
Używam slotów i sygnałów. Oto połączenie wykonane w MainWindow:
QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa(str)"), self.login)

I staram się emitować sygnał wewnątrz klasy Dialog (jestem pewien, że jest emitowany):

self.emit(QtCore.SIGNAL("aa"), "jacek")

Niestety, slot nie jest wywoływany. Próbowałem również bez argumentów, różne style emitowania sygnału. Brak błędów, brak ostrzeżeń w kodzie. Co może być problem?

Author: Jacek, 2010-01-12

7 answers

Nie używasz tego samego sygnału podczas emitowania i łączenia.

QtCore.SIGNAL("aa(str)") to nie to samo co QtCore.SIGNAL("aa"). Sygnały muszą mieć ten sam podpis. Przy okazji, jeśli definiujesz własne sygnały, Nie Definiuj parametrów. Wystarczy napisać SIGNAL ('aa'), bo definiowanie parametrĂłw to rzecz z C++ i Pythonowa wersja Qt tego nie potrzebuje.

Więc powinno wyglądać tak:

QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa"), self.login)

I jeśli przekazujesz jakiekolwiek parametry w emit, twoja metoda logowania musi je zaakceptować. Sprawdź, czy to pomaga: -)

 12
Author: gruszczy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-12 11:44:46

Istnieje kilka pojęć do wyjaśnienia

[QT signal & slot] VS [Python signal & slot]

Wszystkie predefiniowane sygnały i sloty dostarczane przez pyqt są implementowane przez kod QT w c++. Gdy chcesz mieć niestandardowy sygnał i gniazdo w Pythonie, jest to sygnał i gniazdo Pythona. Stąd istnieją cztery przypadki emitowania sygnału do gniazda:

  • z sygnału QT do gniazda QT
  • z sygnału QT do gniazda Pythona
  • od sygnału Pythona do QT slot
  • z sygnału Pythona do gniazda Pythona

Poniższy kod pokazuje, jak połączyć te cztery różne scnarios

    import sys
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *

    class Foo(QtCore.QObject):

        def __init__(self, parent=None):
            super(Foo, self).__init__(parent)
            dial = QDial()
            self.spinbox = QSpinbox()

            # --------------------------------------
            # QT signal & QT slot
            # --------------------------------------

            # option 1: more efficient 
            self.connect(self.spinbox, SIGNAL("valueChanged(int)"), 
                dial, SLOT("setValue(int)"))
            # option 2:
            self.connect(self.spinbox, SIGNAL("valueChanged(int)"), 
                dial.setValue)


            # --------------------------------------
            # QT signal & Python slot
            # --------------------------------------

            self.connect(self.spinbox, SIGNAL("valueChanged(int)"), 
                self.myValChanged)


            # --------------------------------------
            # Python signal & Qt slot
            # --------------------------------------

            # connect option 1: more efficient
            self.connect(self, SIGNAL("mysignal"), dial, 
                SLOT("setValue(int)"))

            # connect option 2:
            self.connect(self, SIGNAL("mysignal"), dial.setValue)

            # emit
            param = 100
            self.emit(SIGNAL("mysignal"), param)


            # --------------------------------------
            # Python signal & Python slot
            # --------------------------------------

            # connect
            self.connect(self, SIGNAL("mysignal"), self.myValChanged)

            # emit
            param = 100
            self.emit(SIGNAL("mysignal"), param)


    def myValChanged(self):
        print "New spin val entered {0}".format(self.spinbox.value())

Wniosek jest --

Sygnatura sygnału Pythona odróżnia się od sygnału QT tym, że nie ma nawiasu i może być przekazywana dowolnemu typowi danych Pythona, gdy go emitujesz. Sygnał Pythona jest tworzony podczas jego emisji.

Dla szczeliny istnieją trzy formy podpisów.

  • S.connect(w, SIGNALSIGNATURE ("signalSignature"), functionName)
  • S.connect(w, SIGNAL ("signalSignature"), instancja.methodName)
  • W tym celu należy skontaktować się z Działem obsługi klienta pod adresem .]}

Liczba 1 i 2 są dostępne dla gniazd Pythona, natomiast liczba 2 i 3 są dostępne dla gniazd QT. Jest oczywiste, że oprócz predefiniowanego gniazda QT, każda funkcja / metody wywołujące Pythona jest qulified jako gniazdo Pythona.

Te punkty zostały przedstawione w artykule Summerfielda o sygnałach i sloty .

[Old style QT signal & slot] VS [new style qt singal & slot]

Cóż, cały Powyższy opis opiera się na starym stylu sygnału i gniazda pyqt. Jak zasugerował @Idan K, istnieje alternatywny nowy styl do robienia rzeczy, szczególnie dla sygnału Pythona. Zobacz tutaj aby uzyskać więcej.

 26
Author: rodney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-26 18:27:37

Sprawdziłem Twój kod i wygląda na to, że problem tkwi w sposobie łączenia sygnału

  1. Emitujesz sygnał w klasie Ui_Dialog

    Self.emit (QtCore.SIGNAL ("aa ()"))

  2. Można połączyć się z sygnałem w Ui_MainWindow metody setupUi przez wywołanie

    QtCore.QObject.connect(self.loginDialog.ui, QtCore.SIGNAL ("aa ()"), self.login)

Uwaga pierwszy parametr zostaje zmieniony na self.loginDialog.ui ; Twój oryginalne połączenie połączeniowe używało self.loginDialog, który jest typu LoginDialog, podczas gdy sygnał jest emitowany przez klasę Ui_Dialog, która jest własnością Ui LoginDialog. Po tej zmianie metoda logowania Ui_MainWindow została wywołana

Mam nadzieję, że to pomoże, pozdrawiam

 3
Author: serge_gubenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-18 03:45:01

To co zasugerował @ bialix powinno zadziałać, ale spróbuj alternatywnego sposobu łączenia:

class Foo(QtCore.QObject):
    mysignal = QtCore.pyqtSignal(str, name='mysignal')

    def connect_to_signal(self):
        # you can use this syntax instead of the 'old' one
        self.mysignal.connect(self.myslot)

        # but this will also work
        self.connect(self, QtCore.SIGNAL('mysignal(QString)'), self.myslot) 

        self.mysignal.emit("hello")

    def myslot(self, param):
        print "received %s" % param

Aby uzyskać bardziej szczegółowe wyjaśnienie, jak działają sygnały / Sloty W PyQt, proponuję przejrzeć jego dokumentację, a konkretnie tę sekcję.

 3
Author: Idan K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-26 20:05:11

Jak zauważył gruszczy musisz użyć tego samego QtCore.SIGNAL ('xxx') do podłączenia sygnału i jego emisji. Myślę również, że powinieneś użyć typów Qt w liście argumentów funkcji sygnału. Np.:

QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa(QString&)"), self.login)

A następnie emitować z:

self.emit(QtCore.SIGNAL("aa(QString&)"), "jacek")

Czasami sensowne jest zdefiniowanie sygnału tylko raz jako zmiennej globalnej i użycie go gdzie indziej:

MYSIGNAL = QtCore.SIGNAL("aa(QString&)")
...
QtCore.QObject.connect(self.loginDialog, MYSIGNAL, self.login)
...
self.emit(MYSIGNAL, "jacek")
 1
Author: bialix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-12 12:23:07

Nie używałem PyQT4, ale spójrz na tutaj .

 0
Author: erelender,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-12 10:33:38

Wygląda na to, że przegapisz część "SLOT" w połączeniu.

Oto przykład:

QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("NotifyMySignal(int)"), QtCore.SLOT("onNotifyMySignal(int)"));

Then

self.emit(QtCore.SIGNAL('NotifyMySignal(1)'));
Mam nadzieję, że to pomoże !
 0
Author: Andy M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-12 12:25:16