In PySide6, why assignment before super().__init__() might lead to abnormal result?
-
Class A is derived from QObject, and class B is derived from A. In the GUI, when the OK button is clicked, the method B.log() is invoked, and it prints 'Hi' in the console. Here is the code:
import sys from PySide6.QtCore import QObject, QTimer, QUrl, Slot from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QmlElement, QQmlApplicationEngine QML_IMPORT_NAME = 'PyLib' QML_IMPORT_MAJOR_VERSION = 1 class A(QObject): def __init__(self): super().__init__() @QmlElement class B(A): def __init__(self): super().__init__() @Slot() def log(self): print('Hi') def main(): app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() engine.load(QUrl('main.qml')) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec()) if __name__ == '__main__': main()
main.qml
import QtQuick import QtQuick.Controls import PyLib ApplicationWindow { height: 100 width: 100 visible: true Button { text: "OK" onClicked: b.log() } B { id: b } }
Then I find something I cannot explain:
- If I set an instance variable to a QTimer object before super().init() in the init() method of class B, i.e.,
@QmlElement class B(A): def __init__(self): self.t = QTimer() super().__init__() @Slot() def log(self): print('Hi')
when the OK button is clicked, no 'Hi' is printed. However, if I set the instance variable to an int or a string, e.g.,
@QmlElement class B(A): def __init__(self): self.t = 1 super().__init__() @Slot() def log(self): print('Hi')
when the OK button is clicked, 'Hi' is printed.
- If a QTimer object is assigned to a local variable instead of an instance variable, i.e.,
@QmlElement class B(A): def __init__(self): t = QTimer() super().__init__() @Slot() def log(self): print('Hi')
the GUI window won't be shown.
It seems super().init() must be called first in the initialization method, otherwise it might lead to abnormal result. Is that true?
-
Class A is derived from QObject, and class B is derived from A. In the GUI, when the OK button is clicked, the method B.log() is invoked, and it prints 'Hi' in the console. Here is the code:
import sys from PySide6.QtCore import QObject, QTimer, QUrl, Slot from PySide6.QtGui import QGuiApplication from PySide6.QtQml import QmlElement, QQmlApplicationEngine QML_IMPORT_NAME = 'PyLib' QML_IMPORT_MAJOR_VERSION = 1 class A(QObject): def __init__(self): super().__init__() @QmlElement class B(A): def __init__(self): super().__init__() @Slot() def log(self): print('Hi') def main(): app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() engine.load(QUrl('main.qml')) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec()) if __name__ == '__main__': main()
main.qml
import QtQuick import QtQuick.Controls import PyLib ApplicationWindow { height: 100 width: 100 visible: true Button { text: "OK" onClicked: b.log() } B { id: b } }
Then I find something I cannot explain:
- If I set an instance variable to a QTimer object before super().init() in the init() method of class B, i.e.,
@QmlElement class B(A): def __init__(self): self.t = QTimer() super().__init__() @Slot() def log(self): print('Hi')
when the OK button is clicked, no 'Hi' is printed. However, if I set the instance variable to an int or a string, e.g.,
@QmlElement class B(A): def __init__(self): self.t = 1 super().__init__() @Slot() def log(self): print('Hi')
when the OK button is clicked, 'Hi' is printed.
- If a QTimer object is assigned to a local variable instead of an instance variable, i.e.,
@QmlElement class B(A): def __init__(self): t = QTimer() super().__init__() @Slot() def log(self): print('Hi')
the GUI window won't be shown.
It seems super().init() must be called first in the initialization method, otherwise it might lead to abnormal result. Is that true?
@isaacchangwang said in In PySide6, why assignment before super().__init__() might lead to abnormal result?:
It seems super().init() must be called first in the initialization method, otherwise it might lead to abnormal result. Is that true?
I would always expect to have to call the base
super().__init__()
as the first statement in any derived class, whether Qt/QObject
or not. Putting aQObject
/QTimer
into a derived class as a member before it has been initialised does not sound like a good idea.