У меня есть qquickwidget внутри Qwidget, и я добавляю этот виджет в Qmdiarea. Я пытаюсь вызвать функцию QML (plusbtn ()) из C ++, используя qmetaobject :: invokemethod . Тем не менее, мое приложение вылетает, когда я пытаюсь вызвать метод. Этот сбой происходит только тогда, когда окно добавляется в Qmdiarea. Когда я удаляю виджет из Qmdiarea, все работает нормально. < /P>
Вот мой упрощенный код: < /p>
qml (map.qml):
Код: Выделить всё
import QtQuick
import QtLocation
import QtPositioning
Rectangle {
id: rectangle
Plugin {
id: mapPlugin
name: "osm"
}
Map {
id: mapView
anchors.fill: parent
plugin: mapPlugin
zoomLevel: 15
minimumZoomLevel: 2
activeMapType: supportedMapTypes[0]
}
function plusBtn() {
if (mapView.zoomLevel < mapView.maximumZoomLevel) {
mapView.zoomLevel = Math.round(mapView.zoomLevel + 1);
}
}
}
Код: Выделить всё
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class QmlWindow : public QWidget
{
public:
QmlWindow(QWidget* parent = nullptr)
: QWidget(parent)
{
QVBoxLayout* layout = new QVBoxLayout(this);
// Create and initialize the QQuickWidget
quickWidget = new QQuickWidget(this);
quickWidget->setSource(QUrl(QStringLiteral("qrc:/Map.qml")));
quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
auto rootObj = quickWidget->rootObject();
// Create a button to invoke the QML method
QPushButton* button = new QPushButton("Call QML Method");
connect(button, &QPushButton::pressed, this, [=]() {
if (!rootObj) {
qWarning() addWidget(quickWidget);
layout->addWidget(button);
setLayout(layout);
}
private:
QQuickWidget* quickWidget;
};
class MainWindow1 : public QMainWindow
{
public:
MainWindow1(QWidget* parent = nullptr)
: QMainWindow(parent)
{
mdiArea = new QMdiArea(this);
setCentralWidget(mdiArea);
QPushButton* openWindowBtn = new QPushButton("Open QML Window", this);
connect(openWindowBtn, &QPushButton::clicked, this, &MainWindow1::openQmlWindow);
setMenuWidget(openWindowBtn);
}
private:
void openQmlWindow()
{
QmlWindow* window = new QmlWindow();
QMdiSubWindow* subWindow = mdiArea->addSubWindow(window);
window->show();
}
QMdiArea* mdiArea;
};
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow1 mainWindow;
mainWindow.show();
return app.exec();
}
< /code>
Сбой возникает, когда я пытаюсь вызвать Plusbtn () после добавления окна в Qmdiarea. Иногда приложение сбивается с сбоем с ошибкой сегментации, а в других случаях я получаю сообщение: qmetaobject :: invokemethod: нет такого метода qquickpinchhandler :: plusbtn () Что я попробовал: Я проверил, что QquickWidget правильно инициализирован, и SetSource (qurl ("qrc: /map.qml")) загружает QML -файл без проблем. Файл QML загружается правильно, rootobject () не является nullptr, а метод плюсбл () существует в объекте QML. Сбой возникает только тогда, когда виджет добавляется в Qmdiarea - если бы я вызовал Plusbtn () перед добавлением, он работает нормально, но как только виджет находится внутри Qmdiarea, вызов Plusbtn () иногда вызывает ошибку сегментации.
вывод отладки перед сбоем:
Код: Выделить всё
auto rootObj = ui->quickWidget->rootObject();
if (!rootObj) {
qWarning() metaObject()->methodCount(); ++i) {
qDebug() method(i).methodSignature();
}
Код: Выделить всё
Root object type: Map_QMLTYPE_0
Method: "plusBtn()"
Подробнее здесь: https://stackoverflow.com/questions/794 ... vokemethod
Мобильная версия