亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將信號連接到插槽會產生 (nullptr)::slot() 錯誤

將信號連接到插槽會產生 (nullptr)::slot() 錯誤

暮色呼如 2023-01-04 11:31:56
我想將來自自定義 QWidget 類 (WidgetClass) 的信號連接到 DerivedController 的插槽。我在實例化兩個類后嘗試連接信號。但是,我在 connect() 語句中收到以下錯誤:QObject::connect: Cannot connect WidgetClass::mySignal(double) to (nullptr)::mySlot(double)我不太清楚為什么會這樣。如果我理解正確,您只能將信號連接到類實例之間的插槽。下面是我正在編寫的偽實現(它在 ipython 中產生相同的錯誤):from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObjectfrom PyQt5.QtWidgets import QApplication, QWidgetclass 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()
查看完整描述

3 回答

?
HUX布斯

TA貢獻1876條經驗 獲得超6個贊

OP提出的解決方案是不正確的,因為錯誤的原因是不同的:

如果您從類 P 繼承,那么您必須調用類 P 的構造函數,在您的情況下,從 QObject 繼承的 BaseController 不會調用 QObject 的構造函數。

綜合以上,題目的報錯信息不再獲取,但還有其他問題:

  • 一個函數的作用域是有限的,在該函數內創建的對象在函數執行時被銷毀,在這種情況下“控制器”被銷毀,可能會導致問題。

  • 另一方面,QApplication exec() 方法不應接收任何參數。

綜合以上,解決辦法是:

from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject

from PyQt5.QtWidgets import QApplication, QWidget



class BaseController(QObject):

    def __init__(self, widget1, widget2):

        super().__init__()

        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()


    return controller



def main():

    app = QApplication(["test"])

    controller = myfunc()

    return app.exec()



if __name__ == "__main__":

    main()

另一方面,OP 在其回答中指出:我認為這是因為我們沒有綁定到實例的插槽,但類本身的插槽是假的,連接是對象之間的。


查看完整回答
反對 回復 2023-01-04
?
墨色風雨

TA貢獻1853條經驗 獲得超6個贊

你忘了super().__init__()打進來的電話BaseController



查看完整回答
反對 回復 2023-01-04
?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

我發現以下部分是錯誤的:

self.widget1.mySignal.connect(
    self.mySlot)
self.widget2.mySignal.connect(
    self.mySlot)

并且應該這樣重寫:

self.widget1.mySignal.connect(
    DerivedController.mySlot)
self.widget2.mySignal.connect(
    DerivedController.mySlot)

這似乎解決了這個問題。我認為這是因為我們沒有綁定到實例的插槽,而是綁定到類本身的插槽,就像聲明為類定義的一部分的信號一樣,而不是類實例化(我希望這是有道理的)。


查看完整回答
反對 回復 2023-01-04
  • 3 回答
  • 0 關注
  • 163 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號