将信号连接到插槽会产生 (nullptr)::slot() 错误
Connecting a signal to slot yields (nullptr)::slot() error
我想将来自自定义 QWidget class (WidgetClass) 的信号连接到 DerivedController 的插槽。
我在实例化两个 classes.
后尝试连接信号
但是,我在 connect() 语句中收到以下错误:
QObject::connect: Cannot connect WidgetClass::mySignal(double) to (nullptr)::mySlot(double)
我不太清楚为什么会这样。如果我理解正确,您只能将信号连接到 classes 实例之间的槽。
下面是我正在编写的伪实现(它在 ipython 中产生相同的错误):
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QWidget
class BaseController():
def __init__(self, widget1, widget2):
self.widget1 = widget1
self.widget2 = widget2
#@pyqtSlot(float)
def mySlot(self, value):
print(f"BaseClass got {value}.")
class DerivedController(BaseController):
def __init__(self, widget1, widget2):
super().__init__(widget1, widget2)
@pyqtSlot(float)
def mySlot(self, value):
#super().mySlot(value)
print(f"Derived class got {value}!")
def _setupConnections(self):
self.widget1.mySignal.connect(
self.mySlot)
self.widget2.mySignal.connect(
self.mySlot)
class WidgetClass(QWidget):
mySignal = pyqtSignal(float)
def emitSignal(self):
self.mySignal.emit(1.8)
def myfunc():
w1 = WidgetClass()
w2 = WidgetClass()
controller = DerivedController(w1, w2)
controller._setupConnections()
controller.widget1.emitSignal()
def main():
app = QApplication(["test"])
return app.exec(myfunc())
if __name__ == "__main__":
main()
我发现以下部分是错误的:
self.widget1.mySignal.connect(
self.mySlot)
self.widget2.mySignal.connect(
self.mySlot)
应该重写为:
self.widget1.mySignal.connect(
DerivedController.mySlot)
self.widget2.mySignal.connect(
DerivedController.mySlot)
这似乎解决了问题。
我认为这是因为我们没有绑定到实例的插槽,而是 class 本身的插槽,就像声明为 class 定义的一部分的信号一样,而不是 class 实例化(我希望这是有道理的)。
OP提出的解决方案不正确,因为错误原因不同:
如果你继承自class P,那么你必须调用class P的构造函数,在你的情况下,继承自QObject的BaseController不会调用QObject的构造函数。
综合以上问题的报错信息不再获取,但还有其他问题:
一个函数的作用域是有限的,在该函数内创建的对象在函数执行时会被销毁,在这种情况下"controller"被销毁可能会导致问题。
另一方面,QApplication exec() 方法不应接收任何参数。
综合以上,解决方案是:
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QWidget
class BaseController(QObject):
def __init__(self, widget1, widget2):
<b>super().__init__()</b>
self.widget1 = widget1
self.widget2 = widget2
# @pyqtSlot(float)
def mySlot(self, value):
print(f"BaseClass got {value}.")
class DerivedController(BaseController):
def __init__(self, widget1, widget2):
super().__init__(widget1, widget2)
@pyqtSlot(float)
def mySlot(self, value):
# super().mySlot(value)
print(f"Derived class got {value}!")
def _setupConnections(self):
self.widget1.mySignal.connect(self.mySlot)
self.widget2.mySignal.connect(self.mySlot)
class WidgetClass(QWidget):
mySignal = pyqtSignal(float)
def emitSignal(self):
self.mySignal.emit(1.8)
def myfunc():
w1 = WidgetClass()
w2 = WidgetClass()
controller = DerivedController(w1, w2)
controller._setupConnections()
controller.widget1.emitSignal()
<b>return controller</b>
def main():
app = QApplication(["test"])
<b>controller = myfunc()
return app.exec()</b>
if __name__ == "__main__":
main()
另一方面,OP 在其回答中指出:我认为这是因为我们没有绑定到实例的插槽,而是 class 本身的插槽为false,对象之间有联系。
您在 BaseController
中忘记了 super().__init__()
调用
我想将来自自定义 QWidget class (WidgetClass) 的信号连接到 DerivedController 的插槽。 我在实例化两个 classes.
后尝试连接信号但是,我在 connect() 语句中收到以下错误:
QObject::connect: Cannot connect WidgetClass::mySignal(double) to (nullptr)::mySlot(double)
我不太清楚为什么会这样。如果我理解正确,您只能将信号连接到 classes 实例之间的槽。 下面是我正在编写的伪实现(它在 ipython 中产生相同的错误):
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QWidget
class BaseController():
def __init__(self, widget1, widget2):
self.widget1 = widget1
self.widget2 = widget2
#@pyqtSlot(float)
def mySlot(self, value):
print(f"BaseClass got {value}.")
class DerivedController(BaseController):
def __init__(self, widget1, widget2):
super().__init__(widget1, widget2)
@pyqtSlot(float)
def mySlot(self, value):
#super().mySlot(value)
print(f"Derived class got {value}!")
def _setupConnections(self):
self.widget1.mySignal.connect(
self.mySlot)
self.widget2.mySignal.connect(
self.mySlot)
class WidgetClass(QWidget):
mySignal = pyqtSignal(float)
def emitSignal(self):
self.mySignal.emit(1.8)
def myfunc():
w1 = WidgetClass()
w2 = WidgetClass()
controller = DerivedController(w1, w2)
controller._setupConnections()
controller.widget1.emitSignal()
def main():
app = QApplication(["test"])
return app.exec(myfunc())
if __name__ == "__main__":
main()
我发现以下部分是错误的:
self.widget1.mySignal.connect(
self.mySlot)
self.widget2.mySignal.connect(
self.mySlot)
应该重写为:
self.widget1.mySignal.connect(
DerivedController.mySlot)
self.widget2.mySignal.connect(
DerivedController.mySlot)
这似乎解决了问题。 我认为这是因为我们没有绑定到实例的插槽,而是 class 本身的插槽,就像声明为 class 定义的一部分的信号一样,而不是 class 实例化(我希望这是有道理的)。
OP提出的解决方案不正确,因为错误原因不同:
如果你继承自class P,那么你必须调用class P的构造函数,在你的情况下,继承自QObject的BaseController不会调用QObject的构造函数。
综合以上问题的报错信息不再获取,但还有其他问题:
一个函数的作用域是有限的,在该函数内创建的对象在函数执行时会被销毁,在这种情况下"controller"被销毁可能会导致问题。
另一方面,QApplication exec() 方法不应接收任何参数。
综合以上,解决方案是:
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
from PyQt5.QtWidgets import QApplication, QWidget
class BaseController(QObject):
def __init__(self, widget1, widget2):
<b>super().__init__()</b>
self.widget1 = widget1
self.widget2 = widget2
# @pyqtSlot(float)
def mySlot(self, value):
print(f"BaseClass got {value}.")
class DerivedController(BaseController):
def __init__(self, widget1, widget2):
super().__init__(widget1, widget2)
@pyqtSlot(float)
def mySlot(self, value):
# super().mySlot(value)
print(f"Derived class got {value}!")
def _setupConnections(self):
self.widget1.mySignal.connect(self.mySlot)
self.widget2.mySignal.connect(self.mySlot)
class WidgetClass(QWidget):
mySignal = pyqtSignal(float)
def emitSignal(self):
self.mySignal.emit(1.8)
def myfunc():
w1 = WidgetClass()
w2 = WidgetClass()
controller = DerivedController(w1, w2)
controller._setupConnections()
controller.widget1.emitSignal()
<b>return controller</b>
def main():
app = QApplication(["test"])
<b>controller = myfunc()
return app.exec()</b>
if __name__ == "__main__":
main()
另一方面,OP 在其回答中指出:我认为这是因为我们没有绑定到实例的插槽,而是 class 本身的插槽为false,对象之间有联系。
您在 BaseController
super().__init__()
调用