将 QML(QQuickView) 添加到现有 UI

Ale*_*liu 5 qt qml qtquick2 qquickview

目前,我正在开发一个需要集成到 C++ Visual Studio 项目中的 Qt 类。

Qt 项目 - Qt Widgets 应用程序。在 Qt Creator 3.2.1(开源)上构建,基于 Qt 5.3.2。使用 Visual Studio 2013 Professional 安装 Qt Addin。

我尝试了互联网上或其他 Stack 帖子中的解决方案,但没有成功。我不认为我的帖子重复,因为其他帖子没有解决我的问题。

我能够从代码运行 QML,但它在不同的窗口上启动。在第一张图片中,QML 窗口(Qt 画布)显示在我的程序 UI 上。

单独窗口上的 QML

我需要将 QML 集成到我的程序 UI 中。如果有帮助的话我可以使用QGraphicsView

程序Ui

简单的 QML 示例。canvas.qml

import QtQuick 2.0
Rectangle {
    id: rectangle
    color: "red"
    width: 600
    height: 600 
}
Run Code Online (Sandbox Code Playgroud)

Dmi*_*try 1

请看一下我的项目中 MVC 实现的一部分。这是一个在 Qt5.6 中可视化 QML 代码的类。希望能帮助到你。

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() );
}
Run Code Online (Sandbox Code Playgroud)

为了管理控制器,我有 Guidirector 类,其实现如下:

#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 */
Run Code Online (Sandbox Code Playgroud)