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<Qt::WindowType>)
的 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 导致启动时崩溃的主要内容,如果未能解决你的问题,请参考以下文章
@ant-design/charts 的 Next.js 问题,错误
Kafka 与 Confluent Kubernetes Helm Charts = Schema Registry WakeupException