自定义信号的声明
Declaration of the custom Signals
在 Qt 中,我们可以通过将它们设为静态变量来创建自定义信号。然后我们使用 self.signame
代替 classname.signame
。
这样就在 class.
中创建了一个实例变量
我想知道这个模式之外的理论。
这是我尝试过的一些伪代码,这些伪代码记录在大多数来源中:
from PyQt5 import QtWidgets,QtCore
class test(QtWidgets.QApplication):
sig=QtCore.pyqtSignal([bool])
def __init__(self):
super().__init__([])
# self.sig=QtCore.pyqtSignal([bool]) #1
self.window=QtWidgets.QWidget()
self.sig.connect(lambda x=True:print('Hello World'))
self.bt=QtWidgets.QPushButton(self.window,text='test',clicked=self.sig)
self.window.setLayout(QtWidgets.QVBoxLayout())
self.window.layout().addWidget(self.bt)
self.window.show()
test().exec()
当我尝试访问信号 test.sig
而不是 self.sig
时,
from PyQt5 import QtWidgets,QtCore
class test(QtWidgets.QApplication):
def __init__(self):
super().__init__([])
self.sig=QtCore.pyqtSignal([bool])
self.window=QtWidgets.QWidget()
self.sig.connect(lambda x=True:print('Hello World'))
self.bt=QtWidgets.QPushButton(self.window,text='test',clicked=self.sig)
self.window.setLayout(QtWidgets.QVBoxLayout())
self.window.layout().addWidget(self.bt)
self.window.show()
test().exec()
我收到这个错误:
test.sig.connect(lambda x=True:print('Hello World'))
AttributeError: 'PyQt5.QtCore.pyqtSignal' object has no attribute 'connect'
当我试图将信号作为实例变量而不是静态变量时,我得到了那个错误(取消注释伪代码中的#1)
我得到了同样的错误(和以前一样)。
请问这背后的原因
来源:PyQt5
需要注意的是,pyqtSignal 被声明为 class 的属性,但它与 the docs:
中指示的连接中使用的对象不同
A signal (specifically an unbound signal) is a class attribute. When a
signal is referenced as an attribute of an instance of the class then
PyQt5 automatically binds the instance to the signal in order to
create a bound signal. This is the same mechanism that Python itself
uses to create bound methods from class functions.
A bound signal has connect(), disconnect() and emit() methods that
implement the associated functionality. It also has a signal attribute
that is the signature of the signal that would be returned by Qt’s
SIGNAL() macro.
换句话说,sig = QtCore.pyqtSignal([bool])
是一个未绑定的信号,但 self.sig
是绑定的信号,可以用以下几行来验证:
from PyQt5 import QtWidgets, QtCore
class test(QtWidgets.QApplication):
sig = QtCore.pyqtSignal([bool])
print(type(sig))
def __init__(self):
super().__init__([])
self.window = QtWidgets.QWidget()
print(type(self.sig))
self.sig.connect(lambda x=True: print("Hello World"))
self.bt = QtWidgets.QPushButton(self.window, text="test", clicked=self.sig)
self.window.setLayout(QtWidgets.QVBoxLayout())
self.window.layout().addWidget(self.bt)
self.window.show()
test().exec()
输出
<class 'PyQt5.QtCore.pyqtSignal'>
<class 'PyQt5.QtCore.pyqtBoundSignal'>
总之,class“sig”的属性是一个没有连接方法的pyqtSignal,用于构造属性“self.x”,它是一个pyqtBoundSignal确实有连接方法。
在 Qt 中,我们可以通过将它们设为静态变量来创建自定义信号。然后我们使用 self.signame
代替 classname.signame
。
这样就在 class.
我想知道这个模式之外的理论。
这是我尝试过的一些伪代码,这些伪代码记录在大多数来源中:
from PyQt5 import QtWidgets,QtCore
class test(QtWidgets.QApplication):
sig=QtCore.pyqtSignal([bool])
def __init__(self):
super().__init__([])
# self.sig=QtCore.pyqtSignal([bool]) #1
self.window=QtWidgets.QWidget()
self.sig.connect(lambda x=True:print('Hello World'))
self.bt=QtWidgets.QPushButton(self.window,text='test',clicked=self.sig)
self.window.setLayout(QtWidgets.QVBoxLayout())
self.window.layout().addWidget(self.bt)
self.window.show()
test().exec()
当我尝试访问信号 test.sig
而不是 self.sig
时,
from PyQt5 import QtWidgets,QtCore
class test(QtWidgets.QApplication):
def __init__(self):
super().__init__([])
self.sig=QtCore.pyqtSignal([bool])
self.window=QtWidgets.QWidget()
self.sig.connect(lambda x=True:print('Hello World'))
self.bt=QtWidgets.QPushButton(self.window,text='test',clicked=self.sig)
self.window.setLayout(QtWidgets.QVBoxLayout())
self.window.layout().addWidget(self.bt)
self.window.show()
test().exec()
我收到这个错误:
test.sig.connect(lambda x=True:print('Hello World'))
AttributeError: 'PyQt5.QtCore.pyqtSignal' object has no attribute 'connect'
当我试图将信号作为实例变量而不是静态变量时,我得到了那个错误(取消注释伪代码中的#1)
我得到了同样的错误(和以前一样)。
请问这背后的原因
来源:PyQt5
需要注意的是,pyqtSignal 被声明为 class 的属性,但它与 the docs:
中指示的连接中使用的对象不同A signal (specifically an unbound signal) is a class attribute. When a signal is referenced as an attribute of an instance of the class then PyQt5 automatically binds the instance to the signal in order to create a bound signal. This is the same mechanism that Python itself uses to create bound methods from class functions.
A bound signal has connect(), disconnect() and emit() methods that implement the associated functionality. It also has a signal attribute that is the signature of the signal that would be returned by Qt’s SIGNAL() macro.
换句话说,sig = QtCore.pyqtSignal([bool])
是一个未绑定的信号,但 self.sig
是绑定的信号,可以用以下几行来验证:
from PyQt5 import QtWidgets, QtCore
class test(QtWidgets.QApplication):
sig = QtCore.pyqtSignal([bool])
print(type(sig))
def __init__(self):
super().__init__([])
self.window = QtWidgets.QWidget()
print(type(self.sig))
self.sig.connect(lambda x=True: print("Hello World"))
self.bt = QtWidgets.QPushButton(self.window, text="test", clicked=self.sig)
self.window.setLayout(QtWidgets.QVBoxLayout())
self.window.layout().addWidget(self.bt)
self.window.show()
test().exec()
输出
<class 'PyQt5.QtCore.pyqtSignal'>
<class 'PyQt5.QtCore.pyqtBoundSignal'>
总之,class“sig”的属性是一个没有连接方法的pyqtSignal,用于构造属性“self.x”,它是一个pyqtBoundSignal确实有连接方法。