pythonqtpyside2qobjectqmetaobject

PySide2 crashes while accessing QObject::property()


So I am not sure this is a bug or something but I have spent quite sometime to figure this out but couldn't. The problem happens when accessing calling QObject::property() function. Here is a minimal reproducible example:

import sys

from PySide2 import QtCore
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import Qt, QCoreApplication, QObject, Slot
from PySide2.QtQml import QQmlApplicationEngine, QQmlContext



class MyItem(QObject):
    def __init__(self):
        super(MyItem, self).__init__()
        self.name = "John"
        self.age = 22

    @QtCore.Property(QtCore.QObject, constant=True)
    def getName(self):
        return self.name

    @QtCore.Property(QtCore.QObject, constant=True)
    def getAge(self):
        return self.age

if __name__ == '__main__':
    app = QApplication(sys.argv)
    provider = MyModelProvider()
    item = MyItem()
    print(item.property("getName")) # the program crashes here
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

    engine = QQmlApplicationEngine()
    engine.rootContext().setContextProperty('provider', provider)
    engine.load('qml/main.qml')
    sys.exit(app.exec_())

The program always crashes with the following output:

Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

Solution

  • Your code fails because the variable that returns getName is not a QObject but a str, similarly to getAge that returns an int, so the solution is to set the correct signature

    import sys
    
    from PySide2.QtCore import Property, QObject, QCoreApplication
    
    
    class MyItem(QObject):
        def __init__(self, parent=None):
            super(MyItem, self).__init__(parent)
            self.name = "John"
            self.age = 22
    
        @Property(str, constant=True)
        def getName(self):
            return self.name
    
        @Property(int, constant=True)
        def getAge(self):
            return self.age
    
    
    if __name__ == "__main__":
        app = QCoreApplication(sys.argv)
        item = MyItem()
        print(item.property("getName"))
        print(item.property("getAge"))
    

    Output:

    John
    22