QML Charts 导致启动时崩溃

Posted

技术标签:

【中文标题】QML Charts 导致启动时崩溃【英文标题】:QML Charts causes crash on startup 【发布时间】:2019-08-15 19:11:29 【问题描述】:

我正在尝试制作一个使用 QML QCharts 来可视化数据的应用程序。该程序在启动时甚至在窗口出现之前就崩溃了。我在 macOS 和 Windows 10 上都进行了尝试,结果相同。我在下面包含了一个最低限度的工作示例。

main.py:

import sys

from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QUrl

import qml_rc

if __name__ == "__main__":
    app = QGuiApplication(sys.argv)

    engine = QQmlApplicationEngine()
    engine.load(QUrl("qrc:/main.qml"))

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

    sys.exit(app.exec_())

main.qml:

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtCharts 2.13

ApplicationWindow 
    visible: true

    // Example taken from: https://doc.qt.io/qt-5/qtcharts-qmlchart-example.html
    ChartView 
        id: chart
        title: "Top-5 car brand shares in Finland"
        anchors.fill: parent
        legend.alignment: Qt.AlignBottom
        antialiasing: true

        PieSeries 
            id: pieSeries
            PieSlice  label: "Volkswagen"; value: 13.5 
            PieSlice  label: "Toyota"; value: 10.9 
            PieSlice  label: "Ford"; value: 8.6 
            PieSlice  label: "Skoda"; value: 8.2 
            PieSlice  label: "Volvo"; value: 6.8 
        
    

    Component.onCompleted: 
        // You can also manipulate slices dynamically, like append a slice or set a slice exploded
        othersSlice = pieSeries.append("Others", 52.0);
        pieSeries.find("Volkswagen").exploded = true;
    

Pipfile:

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[packages]
PySide2 = "==5.13.0"

[requires]
python_version = "3.7"

qml.qrc:

<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
    </qresource>
</RCC>

我如何运行程序:

pipenv install -dev
pipenv run pyside2-rcc -o qml_rc.py qml.qrc
pipenv run python main.py

如果将main.qml 中的ChartView 对象替换为其他对象(如Rectangle),程序将运行良好。我认为图表有问题。

这是我收到的错误消息:22432 Segmentation fault: 11 pipenv run python main.py

这是部分堆栈跟踪:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   QtWidgets                       0x000000010a8a79cb QWidgetTextControl::QWidgetTextControl(QObject*) + 139
1   QtWidgets                       0x000000010a9d2486 0x10a6b3000 + 3273862
2   QtWidgets                       0x000000010a9d2dbd QGraphicsTextItem::document() const + 13
3   QtCharts                        0x000000010e3e5f56 QtCharts::ChartTitle::ChartTitle(QGraphicsItem*) + 54
4   QtCharts                        0x000000010e3d98ed QtCharts::ChartPresenter::setTitleFont(QFont const&) + 61
5   QtCharts                        0x000000010e3db0d6 QtCharts::ChartThemeManager::decorateChart(QtCharts::QChart*, QtCharts::ChartTheme*) const + 214
6   QtCharts                        0x000000010e3dae11 QtCharts::ChartThemeManager::setTheme(QtCharts::QChart::ChartTheme) + 337
7   QtCharts                        0x000000010e3e0b8e QtCharts::QChart::QChart(QGraphicsItem*, QFlags<Qt::WindowType>) + 126
8   libqtchartsqml2.dylib           0x000000010e3728fe QtCharts::DeclarativeChart::initChart(QtCharts::QChart::ChartType) + 142
9   libqtchartsqml2.dylib           0x000000010e368e50 0x10e34d000 + 114256
10  QtQml                           0x0000000106ff815a QQmlType::create(QObject**, void**, unsigned long) const + 90
11  QtQml                           0x000000010705c628 QQmlObjectCreator::createInstance(int, QObject*, bool) + 568
12  QtQml                           0x000000010705e90d QQmlObjectCreator::setPropertyBinding(QQmlPropertyData const*, QV4::CompiledData::Binding const*) + 989
13  QtQml                           0x000000010705dfcd QQmlObjectCreator::setupBindings(bool) + 1485
14  QtQml                           0x000000010706290a QQmlObjectCreator::populateInstance(int, QObject*, QObject*, QQmlPropertyData const*) + 538
15  QtQml                           0x000000010705d2aa QQmlObjectCreator::createInstance(int, QObject*, bool) + 3770
16  QtQml                           0x000000010705c18b QQmlObjectCreator::create(int, QObject*, QQmlInstantiationInterrupt*) + 699
17  QtQml                           0x0000000106fe74ec QQmlComponentPrivate::beginCreate(QQmlContextData*) + 396
18  QtQml                           0x0000000106fe7301 QQmlComponent::create(QQmlContext*) + 97
19  QtQml                           0x0000000107053ee7 QQmlApplicationEnginePrivate::finishLoad(QQmlComponent*) + 87
20  QtQml                           0x0000000107054572 QQmlApplicationEngine::load(QUrl const&) + 34
21  QtQml.abi3.so                   0x0000000107bc9c52 Sbk_QQmlApplicationEngineFunc_load(_object*, _object*) + 370
22  org.python.python               0x0000000105344696 _PyMethodDef_RawFastCallKeywords + 591
23  org.python.python               0x0000000105343bd3 _PyCFunction_FastCallKeywords + 44
24  org.python.python               0x00000001053d95f0 call_function + 636
25  org.python.python               0x00000001053d2231 _PyEval_EvalFrameDefault + 7016
26  org.python.python               0x00000001053d9ef7 _PyEval_EvalCodeWithName + 1835
27  org.python.python               0x00000001053d0626 PyEval_EvalCode + 51
28  org.python.python               0x00000001053ff2a5 run_mod + 54
29  org.python.python               0x00000001053fe2c0 PyRun_FileExFlags + 164
30  org.python.python               0x00000001053fd97a PyRun_SimpleFileExFlags + 266
31  org.python.python               0x00000001054166a2 pymain_main + 5614
32  org.python.python               0x0000000105416ca4 _Py_UnixMain + 56
33  libdyld.dylib                   0x00007fff6cf023d5 start + 1

Thread 1:
0   libsystem_pthread.dylib         0x00007fff6d0f53f0 start_wqthread + 0

Thread 2:
0   libsystem_pthread.dylib         0x00007fff6d0f53f0 start_wqthread + 0

Thread 3:
0   libsystem_pthread.dylib         0x00007fff6d0f53f0 start_wqthread + 0

Thread 4:: QQmlThread
0   libsystem_kernel.dylib          0x00007fff6d03f36e poll + 10
1   QtCore                          0x0000000106a41810 qt_safe_poll(pollfd*, unsigned int, timespec const*) + 608
2   QtCore                          0x0000000106a4306a QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 858
3   QtCore                          0x00000001069e696f QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 431
4   QtCore                          0x000000010682230c QThread::exec() + 140
5   QtQml                           0x0000000107077529 0x106dfa000 + 2610473
6   QtCore                          0x0000000106823283 0x106801000 + 139907
7   libsystem_pthread.dylib         0x00007fff6d0f62eb _pthread_body + 126
8   libsystem_pthread.dylib         0x00007fff6d0f9249 _pthread_start + 66
9   libsystem_pthread.dylib         0x00007fff6d0f540d thread_start + 13

【问题讨论】:

【参考方案1】:

Qt Charts 需要创建一个 QApplication,因为如 stacktrace 中所见,需要一个 QGraphicsItem:QtCharts::QChart::QChart(QGraphicsItem*, QFlags&lt;Qt::WindowType&gt;) 的 QChart,因此解决方案是替换 QGuiApplication:

import sys

from PySide2.QtWidgets import QApplication # <---
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QUrl

import qml_rc

if __name__ == "__main__":
    app = QApplication(sys.argv) # <---

    engine = QQmlApplicationEngine()
    engine.load(QUrl("qrc:/main.qml"))

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

    sys.exit(app.exec_())

【讨论】:

在 C++ 版本的 Qt 中相同 为什么?如果 QGuiApplication 不适用于所有组件,为什么还要使用它?那么为什么不是所有的 QT 示例和教程都使用 QApplication 呢?或者如果我们使用QApplication,会不会出现其他问题? @Bersan 继承顺序是QCoreApplication、QGuiApplication、QApplication,即QGuiApplication相对于QApplication来说是极简的。通常只有 QWidgets(和 QGraphicsXItems)应该使用 QApplication。

以上是关于QML Charts 导致启动时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

QML 使用 ChartView 崩溃问题

@ant-design/charts 的 Next.js 问题,错误

QtQuick:未安装模块

Qt中的Qt Charts

high charts黑屏显示或者不显示

Kafka 与 Confluent Kubernetes Helm Charts = Schema Registry WakeupException