【问题标题】:Add QML(QQuickView) to existing UI将 QML(QQuickView) 添加到现有 UI
【发布时间】:2015-05-29 15:19:09
【问题描述】:

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

Qt 项目 - Qt 小部件应用程序。基于 Qt Creator 3.2.1 构建 (开源),基于 Qt 5.3.2。使用 Visual Studio 2013 专业,已安装 Qt 插件。

我尝试了来自互联网各地或其他 Stack 帖子的解决方案,但没有成功。我没有看到我的帖子重复,因为其他帖子没有解决我的问题。

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

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

简单的 QML 示例。 canvas.qml

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

【问题讨论】:

  • 你是如何加载 QML 文件的?你在用 QQuickWidget 吗?
  • 是的。我正在使用 QQuickWidget。

标签: qt qml qtquick2 qquickview


【解决方案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() );
}

为了管理控制器,我有具有以下实现的 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 */

【讨论】:

  • 我喜欢你的方法,我认为 Qt 所谓的“MVC”更像是一个用于控件的 MVC 框架,而不是用于构建大型应用程序的通用框架。你如何处理视图之间的切换?
  • 好吧,我有所谓的GUI导向器类。我会把它放在我的答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多