[英]PyQt4 signals and slots
我正在用PyQt4編寫我的第一個Python應用程序。 我有一個MainWindow和一個Dialog類,它是MainWindow類的一部分:
self.loginDialog = LoginDialog();
我使用插槽和信號。 這是MainWindow中的連接:
QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa(str)"), self.login)
我嘗試在Dialog類中發出信號(我確定它已發出):
self.emit(QtCore.SIGNAL("aa"), "jacek")
不幸的是,沒有調用插槽。 我嘗試了沒有任何參數,不同風格的發射信號。 代碼中沒有錯誤,沒有警告。 可能是什么問題?
有一些概念需要澄清
[QT信號和插槽] VS [Python信號和插槽]
pyqt提供的所有預定義信號和插槽均由QT的c ++代碼實現。 每當你想在Python中擁有一個自定義信號和插槽時,它就是一個python信號和插槽。 因此,有四種情況可以向插槽發送信號:
下面的代碼顯示了如何連接這四種不同的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())
結論是 -
Python信號的信號簽名與QT信號的信號簽名不同,因為它沒有括號,並且在發出時可以傳遞任何python數據類型。 發出Python信號時會創建它。
對於插槽,有三種形式的簽名。
1號和2號可用於Python插槽,而2號和3號可用於QT插槽。 很明顯,除了QT預定義槽之外,任何python可調用函數/方法都被稱為Python槽。
這些觀點是在Summerfield關於信號和插槽的文章中提出的 。
[舊式qt信號和插槽] VS [新款qt信號和插槽]
好吧,上面的所有描述都基於舊式pyqt信號和插槽。 正如@Idan K建議的那樣,有一種新的方式可以做到這一點,特別是對於Python信號。 請參閱此處了解更多信息。
發射和連接時,不要使用相同的信號。
QtCore.SIGNAL("aa(str)")
與QtCore.SIGNAL("aa")
。 信號必須具有相同的簽名。 順便說一句,如果您要定義自己的信號,請不要定義參數。 只寫SIGNAL('aa'),因為定義參數是來自C ++的東西,而Qt的Python版本不需要這個。
所以看起來應該是這樣的:
QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa"), self.login)
如果你在emit中傳遞任何參數,你的登錄方法必須接受這些參數。 檢查,如果這有幫助:-)
@bialix建議應該有用,但嘗試另一種連接方式:
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
有關信號/插槽如何在PyQt中工作的更詳細說明,我建議通過它的文檔,特別是本節 。
我檢查了你的代碼,看起來問題就在於你如何連接你的信號
你在Ui_Dialog類中發出信號
self.emit(QtCore.SIGNAL( “AA()”))
你通過調用連接到Ui_MainWindow的setupUi方法中的信號
QtCore.QObject.connect(self.loginDialog.ui,QtCore.SIGNAL(“aa()”),self.login)
注意第一個參數改為self.loginDialog.ui ; 你的原始連接調用是使用了LoginDialog類型的self.loginDialog,而信號是由Ui_Dialog類發出的,它是LoginDialog的ui屬性。 在此更改之后調用Ui_MainWindow的登錄方法
希望這有幫助,問候
正如gruszczy所指出的,你必須使用相同的QtCore.SIGNAL('xxx')連接信號並發出它。 另外我認為你應該在信號函數的參數列表中使用Qt類型。 例如:
QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("aa(QString&)"), self.login)
然后發出:
self.emit(QtCore.SIGNAL("aa(QString&)"), "jacek")
有時僅將信號定義為全局變量並在其他地方使用它是有意義的:
MYSIGNAL = QtCore.SIGNAL("aa(QString&)")
...
QtCore.QObject.connect(self.loginDialog, MYSIGNAL, self.login)
...
self.emit(MYSIGNAL, "jacek")
我沒有使用過PyQT4,但請看一下這里 。
看起來你錯過了通話中的“SLOT”部分。
這是一個例子:
QtCore.QObject.connect(self.loginDialog, QtCore.SIGNAL("NotifyMySignal(int)"), QtCore.SLOT("onNotifyMySignal(int)"));
然后
self.emit(QtCore.SIGNAL('NotifyMySignal(1)'));
希望這可以幫助 !
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.