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?
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: -)
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.
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
-
Emitujesz sygnał w klasie Ui_Dialog
Self.emit (QtCore.SIGNAL ("aa ()"))
-
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
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ę.
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")
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 .
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 !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