Добавьте QML (QQuickView) в существующий пользовательский интерфейс.

В настоящее время я разрабатываю класс Qt, который необходимо интегрировать в проект C++ Visual Studio.

Проект Qt — Приложение Qt Widgets. Сборка на Qt Creator 3.2.1 (с открытым исходным кодом), основанная на Qt 5.3.2. Используя Visual Studio 2013 Professional, установил надстройку Qt.

Я пробовал решения со всего Интернета или из других сообщений Stack, но безуспешно. Я не вижу свой пост как дубликат, так как другие посты не решили мою проблему.

Мне удалось запустить QML из кода, но он запускается в другом окне. На первом рисунке окно QML (холст Qt) показано поверх пользовательского интерфейса моей программы.

QML в отдельном окне

Мне нужно интегрировать QML в пользовательский интерфейс моей программы. Я могу использовать QGraphicsView, если это поможет.

ProgramUi

Простой пример QML. canvas.qml

import QtQuick 2.0
Rectangle {
    id: rectangle
    color: "red"
    width: 600
    height: 600 
}

person Alexandru Vasiliu    schedule 29.05.2015    source источник
comment
Как вы загружаете этот файл QML? Вы используете QQuickWidget?   -  person peppe    schedule 29.05.2015
comment
да. Я использую QQuickWidget.   -  person Alexandru Vasiliu    schedule 04.06.2015


Ответы (1)


Пожалуйста, взгляните на часть реализации MVC в моем проекте. Вот класс для визуализации кода QML в Qt5.6. Надеюсь, поможет.

QmlViewBase::QmlViewBase( QWindow* parent, const std::string& qmlFilePath)
{
    this->m_pEngine = QQmlEnginePtr( new QQmlEngine() );
    this->m_pView = QQuickViewPtr ( new QQuickView( this->m_pEngine.get(), parent ));
    this->m_pView->setResizeMode( QQuickView::SizeRootObjectToView );
    this->m_pView->setSource( QUrl( qmlFilePath.c_str() ));
    this->m_pView->setVisible( false );
    this->m_pView->setMinimumSize(QSize(640, 480));
}

QmlViewBase::~QmlViewBase()
{
    try {
        this->m_pView.reset();
    }catch(...) {

    }
}

void QmlViewBase::show()
{
    this->m_pView->show();
}

void QmlViewBase::hide()
{
    this->m_pView->hide();
}

bool QmlViewBase::isVisible()
{
    return this->m_pView->isVisible();
}

bool QmlViewBase::close()
{
    return this->m_pView->close();
}

QObject * const QmlViewBase::getSlotsSignalsObject() const
{
    return reinterpret_cast<QObject* const >( this->m_pView->rootObject() );
}

Для управления контроллерами у меня есть класс директора Gui со следующей реализацией:

#ifndef de91_a97_4a2d_b906_01070cbfdd47
#define de91_a97_4a2d_b906_01070cbfdd47

#include "gui_director.h"
#include "utility/event_handler/event_handler.h"
#include "utility/exceptions.h"
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <map>
#include <QApplication>

template<typename ControllerId>
class GuiDirectorImpl : public GuiDirector<ControllerId>,
                        public EventHandler<
                              Event<ModelToUIParameters, ServerToClientEventType> >
{
public:
   typedef boost::shared_ptr<GuiDirectorImpl<ControllerId> > pointer;
   typedef boost::weak_ptr<GuiDirectorImpl<ControllerId> > weak_pointer;

public:
   virtual ~GuiDirectorImpl()
   {
   }
   ;
   GuiDirectorImpl(QApplication *app)
   {
      m_app = app;
      m_currentActiveController.reset();
   }

   virtual void addController(ControllerId controllerId,
                              Controller::pointer controller)
   {
      if (isControllerExist( controllerId )) {
         BOOST_THROW_EXCEPTION( argument_error()
                                << error_description( "controller with such id already added" ) );
      }

      m_idToController[controllerId] = controller;
   }

   virtual void setActive(ControllerId controllerId)
   {
      if (!isControllerExist( controllerId )) {
         BOOST_THROW_EXCEPTION( argument_error()
                                << error_description( "controller with such id doesn't exeist" ) );
      }

      Controller::pointer oldController = m_currentActiveController;

      m_currentActiveController = m_idToController[controllerId];
      if(NULL != oldController)
      {
          oldController->prepareViewToHide();
      }
      m_currentActiveController->prepareViewToShow();

      m_currentActiveController->startShowView();

      if (NULL != oldController) {
         oldController->stopShowView();
      }
   }

   virtual void handleEvent(Event<ModelToUIParameters, ServerToClientEventType>::pointer event_)
   {
      if (NULL == m_currentActiveController) {
         BOOST_THROW_EXCEPTION( error()
                                << error_description( "no active controller, cant handle event" ) );
      }

      m_currentActiveController->handleEvent( event_ );
   }

   virtual void quit()
   {
      m_app->quit();
   }

private:
   bool isControllerExist(ControllerId controllerId)
   {
      typename std::map<ControllerId, Controller::pointer>::const_iterator iter = m_idToController.find( controllerId );

      if (m_idToController.end() == iter) {
         return false;
      }

      return true;
   }

private:
   QApplication *m_app;
   Controller::pointer m_currentActiveController;
   typename std::map<ControllerId, Controller::pointer> m_idToController;
};

#endif /* de91_a97_4a2d_b906_01070cbfdd47 */
person Dmitry    schedule 06.05.2016
comment
Мне нравится ваш подход, я думаю, что то, что Qt называет MVC, - это скорее структура MVC для элементов управления, а не общая структура для создания больших приложений. Как вы справляетесь с переключением между представлениями? - person Marcello; 25.05.2016
comment
Ну, у меня есть так называемый класс GUI-директора. Я приложу это к своему ответу. - person Dmitry; 25.05.2016