Search code examples
pythonqmlpyside2

PySide How to see QML errors in python console?


I have the following code:

if __name__ == '__main__':
    os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    engine.load('./QML/main.qml')

    if not engine.rootObjects():
        sys.exit(-1)

    sys.exit(app.exec_())

As you can see, if `engine.load' fails all I'll see is a '-1' exit code, without any elaboration on why it failed and what the error happened. How can I print the QML error in the python console?

There was a walkaround for this with when using QQuickView instead of QQmlApplicationEngine and is described in this post, however, I wonder if the something similar can be achieved for QQmlApplicationEngine?


Solution

  • If you want to know the error message when using QQmlApplicationEngine you should use the warnings signal but it does not seem to work, so a workaround is to use qInstallMessageHandler to get the messages that Qt gives.

    import os
    import sys
    from PySide2 import QtCore, QtGui, QtQml
    
    def qt_message_handler(mode, context, message):
        if mode == QtCore.QtInfoMsg:
            mode = 'Info'
        elif mode == QtCore.QtWarningMsg:
            mode = 'Warning'
        elif mode == QtCore.QtCriticalMsg:
            mode = 'critical'
        elif mode == QtCore.QtFatalMsg:
            mode = 'fatal'
        else:
            mode = 'Debug'
        print("%s: %s (%s:%d, %s)" % (mode, message, context.file, context.line, context.file))
    
    
    if __name__ == '__main__':
        os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
        QtCore.qInstallMessageHandler(qt_message_handler)
        app = QtGui.QGuiApplication(sys.argv)
        engine = QtQml.QQmlApplicationEngine()
        qml_filename = os.path.join(os.path.dirname(__file__), 'QML/main.qml')
        engine.load(QtCore.QUrl.fromLocalFile(qml_filename))
        if not engine.rootObjects():
            sys.exit(-1)
        sys.exit(app.exec_())