I have a large application with many qml components. When I close my application I get a 0xC0000005 exit code. Below is a toy example which generates such an exit code as well. In it, I'm able to resolve the issue by stopping the ongoing timer before closing. I want to know how I'd do this if I didn't have a reference to the timer.
main.py
from PyQt5 import QtCore
from PyQt5.QtCore import qInstallMessageHandler
from PyQt5.QtCore import QObject
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
import sys
def log(msg):
print(msg)
def qt_message_handler(mode, context, message):
modeMap = {QtCore.QtDebugMsg: 'DEBUG',
QtCore.QtInfoMsg: 'INFO',
QtCore.QtWarningMsg: "WARNING",
QtCore.QtCriticalMsg: "CRITICAL",
QtCore.QtFatalMsg: "FATAL"}
logMsg = f"QT_{modeMap.get(mode, 'xxx')}: {message}"
log(logMsg)
class Application(QObject):
def __init__(self):
super().__init__()
def run(self):
# set up
qInstallMessageHandler(qt_message_handler)
qml_src = QUrl.fromLocalFile('main.qml')
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(qml_src)
return app.exec_()
if __name__ == '__main__':
Application().run()
main.qml
import QtQuick 2.0
import QtQuick.Layouts 1.11
import QtQuick.Controls 1.4
ApplicationWindow {
id: root
color: randomColor()
width: 150
height: 150
visible: true
Rectangle {
anchors.fill: parent
color: root.color
}
Timer {
id: myTimer
interval: 500; running: true; repeat: true;
onTriggered: root.color = root.randomColor()
}
onClosing: {
print("closing")
// The following line stops the crash,
// todo: How could I close cleanly if I don't have a reference
// to deeply burried timers or other ongoing code?
// myTimer.stop()
}
function randomColor() {
var colors = ["red", "green", "blue",
"antiquewhite", "aqua", "aquamarine",
"blueviolet", "chartreuse", "cornflowerblue",
"deeppink", "darkorange", "indianred",
"mediumpurple", "plum", "moccasin",
"yellow", "silver", "tan"];
var choice = Math.floor(Math.random()*colors.length)
return colors[choice];
}
}
The problem is that you are eliminating the application from memory without other elements releasing the information, in this case "engine" is still freeing memory and for this you need the QXApplication.
Considering the above there are the following options:
class Application(QObject):
def run(self):
# set up
qInstallMessageHandler(qt_message_handler)
qml_src = QUrl.fromLocalFile("main.qml")
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(qml_src)
ret = app.exec_()
del engine
# or
# engine.deleteLater()
return ret
app = None
class Application(QObject):
def run(self):
# set up
qInstallMessageHandler(qt_message_handler)
qml_src = QUrl.fromLocalFile("main.qml")
global app
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load(qml_src)
return app.exec_()
User contributions licensed under CC BY-SA 3.0