Почему не выводится карта в диалоге?

151
25 декабря 2019, 23:00

У меня программа зависает когда я пытаюсь вывести окно 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]
}
Answer 1

Обратите внимание на тельце вот этого метода-слота:

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(), завершение работы которого происходит при получении соответствующего сообщения, поэтому там этот код работает.

  1. Чтобы заработало как надо, надо вместо вызова 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) оконный контейнер

  1. Либо создать локальный цикл сообытий при помощи класса QEventLoop.
Answer 2

У меня получился такой код :

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();
    }
READ ALSO
Примитивное окно загрузки приложения

Примитивное окно загрузки приложения

Посоветуйте библиотеку для создания примитивного окна загрузки приложения

137
Возвращаемое значение функций

Возвращаемое значение функций

Не могли бы вы подсказать, можно ли задать функции возвращаемое значение по-умолчанию еще при ее объявлении

123
Количество слов в предложении

Количество слов в предложении

Не могу разобраться с цикломМне надо узнать количество слов в предложении, а получается количество символов без пробелов

143
Запись Разных Типов структур в файл

Запись Разных Типов структур в файл

Заранее скажу что предподователь про ifstream ничего не говорил и это начнется с ооп, а на базе учат всему, но не тому что нужно

132