QML Charts 导致启动时崩溃

2022-01-19 00:00:00 python python-3.x pyside2 qml qtcharts

问题描述

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

I'm trying to make an application that uses QML QCharts to visualize data. The program is crashing at startup before a window even appears. I tried on both macOS and Windows 10 with the same results. I have included a minimally working example below.

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),程序将运行良好.我认为图表有问题.

If you replace the ChartView object in main.qml with something else (like a Rectangle), the program will run just fine. I believe there is an issue with the charts.

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

This is the error message I get: 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


解决方案

Qt Charts 需要创建一个 QApplication,因为在 stacktrace 中可以看到,QChart 是需要一个 QGraphicsItem 的:QtCharts::QChart::QChart(QGraphicsItem*, QFlags<Qt::WindowType>),所以解决方法是替换QGuiApplication:

Qt Charts needs a QApplication to be created since, as seen in stacktrace, QChart is required that requires a QGraphicsItem: QtCharts::QChart::QChart(QGraphicsItem*, QFlags<Qt::WindowType>), so the solution is to replace the 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_())

相关文章