干净地停止QML应用程序,而无需引用重复计时器

问题描述 投票:0回答:1

问题

我有一个包含许多qml组件的大型应用程序。当我关闭应用程序时,我得到一个0xC0000005退出代码。下面是一个玩具示例,它也会生成此类退出代码。在其中,我可以通过在关闭前停止正在进行的计时器来解决此问题。我想知道如果我没有引用了计时器,该怎么办。

代码

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];
   }
}

python pyqt qml pyqt5
1个回答
0
投票

问题是您正在从内存中删除应用程序,而没有其他元素释放信息,在这种情况下,“引擎”仍在释放内存,为此您需要QXApplication。

考虑以上所述,有以下选项:

  • 删除QXApplication之前删除QQmlApplicationEngine:
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
  • 使用全局变量在运行方法之外延长了QXApplication的寿命:
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_()
© www.soinside.com 2019 - 2024. All rights reserved.