У меня программа зависает когда я пытаюсь вывести окно qml. ArcGis я установил. Как вывести окно карт? Копировал код с этого репозитория
Мой код:
addmodeldialog.cpp
void addModelDialog::on_pushButton_3_clicked()
{
DisplayMap::init();
// Initialize application view
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
// Add the import Path
view.engine()->addImportPath(QDir(QCoreApplication::applicationDirPath()).filePath("qml"));
QString arcGISRuntimeImportPath = QUOTE(ARCGIS_RUNTIME_IMPORT_PATH);
QString arcGISToolkitImportPath = QUOTE(ARCGIS_TOOLKIT_IMPORT_PATH);
#if defined(LINUX_PLATFORM_REPLACEMENT)
// on some linux platforms the string 'linux' is replaced with 1
// fix the replacement paths which were created
QString replaceString = QUOTE(LINUX_PLATFORM_REPLACEMENT);
arcGISRuntimeImportPath = arcGISRuntimeImportPath.replace(replaceString, "linux", Qt::CaseSensitive);
arcGISToolkitImportPath = arcGISToolkitImportPath.replace(replaceString, "linux", Qt::CaseSensitive);
#endif
// Add the Runtime and Extras path
view.engine()->addImportPath(arcGISRuntimeImportPath);
// Add the Toolkit path
view.engine()->addImportPath(arcGISToolkitImportPath);
// Set the source
view.setSource(QUrl("qrc:/Samples/Analysis/ViewshedGeoElement/DisplayMap.qml"));
view.show();
QWidget *container = QWidget::createWindowContainer(&view);
QDialog dialog;
QHBoxLayout layout;
dialog.setWindowFlags(Qt::FramelessWindowHint);
dialog.setAttribute(Qt::WA_TranslucentBackground);
layout.addWidget(container);
dialog.setLayout(&layout);
dialog.show();
}
DisplayMap.h
#ifndef DISPLAY_MAP_H
#define DISPLAY_MAP_H
namespace Esri
{
namespace ArcGISRuntime
{
class Map;
class MapQuickView;
}
}
#include <QQuickItem>
class DisplayMap : public QQuickItem
{
Q_OBJECT
public:
explicit DisplayMap(QQuickItem* parent = nullptr);
~DisplayMap();
void componentComplete() Q_DECL_OVERRIDE;
static void init();
private:
Esri::ArcGISRuntime::Map* m_map = nullptr;
Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr;
};
#endif // DISPLAY_MAP_H
DisplayMap.cpp
#include "DisplayMap.h"
#include "Map.h"
#include "MapQuickView.h"
#include "Basemap.h"
using namespace Esri::ArcGISRuntime;
DisplayMap::DisplayMap(QQuickItem* parent) :
QQuickItem(parent)
{
}
DisplayMap::~DisplayMap() = default;
void DisplayMap::init()
{
qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView");
qmlRegisterType<DisplayMap>("Esri.Samples", 1, 0, "DisplayMapSample");
}
void DisplayMap::componentComplete()
{
QQuickItem::componentComplete();
//! [MapQuickView API Snippet]
// find QML MapView component
m_mapView = findChild<MapQuickView*>("mapView");
// create a new basemap instance
Basemap* basemap = Basemap::imageryWithLabels(this);
// create a new map instance
m_map = new Map(basemap, this);
// set map on the map view
m_mapView->setMap(m_map);
//! [MapQuickView API Snippet]
}
DisplayMap.qml
import QtQuick 2.6
import QtQuick.Controls 1.4
import Esri.Samples 1.0
import Esri.ArcGISExtras 1.1
DisplayMapSample {
width: 800
height: 600
//! [add a mapView component]
MapView {
anchors.fill: parent
objectName: "mapView"
}
//! [add a mapView component]
}
Обратите внимание на тельце вот этого метода-слота:
void addModelDialog::on_pushButton_3_clicked()
{
DisplayMap::init();
//...
// Initialize application view
QQuickView view;
// ...
QWidget *container = QWidget::createWindowContainer(&view);
QDialog dialog;
//...
dialog.show();
}
Все эти объекты создаются в стековой (локальной) памяти метода и как только метод завершает свою работу эти объекты уничтожаются (в том числе container потому что его parent "тянет" его за собой). Поэтому у вас все зависает.
В репозитории, вы скопировали этот код из метода main.cpp, который создает локальную переменную приложения a с главным циклом событий программы a.exec(), завершение работы которого происходит при получении соответствующего сообщения, поэтому там этот код работает.
dialog.show() сделать вызов dialog.exec(), которое не завершит свою работу пока пользователь явно не закроет диалоговое окно.Уточнение. Если вы оставите вызов dialog.setWindowFlags(Qt::FramelessWindowHint);, то работать не будет. Поменяйте эту строчку на такую dialog.setWindowFlags( dialog.windowFlags() | Qt::FramelessWindowHint);
Уточнение 2 надо убрать view.show(). Вот что написано в документации:
Creating a native window for the window container also allows for proper stacking and clipping. This must be done before showing the window container
перевод: Создание окна для оконного контейнера приводит к правильному конструированию стека и обрезке (окна). Это должно быть выполнено до того как будет показан (show) оконный контейнер
QEventLoop.У меня получился такой код :
void addModelDialog::on_pushButton_3_clicked()
{
DisplayMap::init();
// Initialize application view
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
// Add the import Path
view.engine()->addImportPath(QDir(QCoreApplication::applicationDirPath()).filePath("qml"));
QString arcGISRuntimeImportPath = QUOTE(ARCGIS_RUNTIME_IMPORT_PATH);
QString arcGISToolkitImportPath = QUOTE(ARCGIS_TOOLKIT_IMPORT_PATH);
// Add the Runtime and Extras path
view.engine()->addImportPath(arcGISRuntimeImportPath);
// Add the Toolkit path
view.engine()->addImportPath(arcGISToolkitImportPath);
// Set the source
view.setSource(QUrl("qrc:/Samples/Analysis/ViewshedGeoElement/DisplayMap.qml"));
QWidget *container = QWidget::createWindowContainer(&view);
QDialog dialog;
QHBoxLayout layout;
layout.addWidget(container);
setMinimumSize(800,800);
dialog.setLayout(&layout);
dialog.exec();
QEventLoop loop;
loop.exec();
}
Продвижение своими сайтами как стратегия роста и независимости