User Tools

Site Tools


dev_guide:adduiproxy

定制界面布局

XT框架中界面布局的定制通过继承UIProxy实现。

应用界面依赖于应用文档,因此应用界面的注册是通过调用XDocument提供的静态函数完成:

static bool bRegisterTestUI = LOCAL_NAMESPACE::XDocument::registerUIProxy(DocumentTestID, CreateTestProxy, DestroyTestProxy);

其中DocumentTestID是注册应用文档时生成的整型ID标识,后面的两个参数分别为Proxy的构造接口和析构接口,在接口中调用具体的构造函数与析构函数(所有的界面代理均需重新实现这两个接口):

bool CreateTestProxy(MainFrame* frame, XDocument * doc,UIProxy ** proxy)
{
  TestProxy * t = new TestProxy(frame,doc);
  if (t == 0)
  {
    return false;
  }
  *proxy = t;
  return true;
}
void DestroyTestProxy(UIProxy * proxy)
{
  delete static_cast<TestProxy *>(proxy);
}

在界面代理的构造函数,根据应用的需要添加视图、定制窗口布局和创建对象树模型,其中对象树模型根据Qt库中QTreeView控件的MVC设计思路而来,用于向XTreeView提供数据(XTreeView从QTreeView继承实现,可参看相关文档):

TestProxy::TestProxy(MainFrame * frame,XDocument * doc):UIProxy(frame,doc)
{  
  //创建对象树Model,按照QTreeView控件的MVC机制
  m_pDocTreeMdl = new TestTreeModel(m_pDoc, m_pFrame); 
  //添加新的视图
  m_pCurrentDocView = new TestView(m_pFrame, m_pDoc); 
  m_pDocViews->push_back(m_pCurrentDocView);
  //定制窗口
  m_pCmdDock = new QDockWidget(QString().fromLocal8Bit("设置"), m_pFrame);
  m_pCmdDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
  m_pCmdDock->setAllowedAreas(Qt::AllDockWidgetAreas);
}

在启动与应用文档适配的应用界面之前,应重新实现activate函数以正确的激活对应的界面代理,在此函数中主要对界面窗口重新布局,设置该应用界面特有的属性,如程序名称、三维视图背景色等等,并恢复之前的界面状态(在多个应用来回切换的情况下), 如视图视角等等:

void TestProxy::activate()
{
  UIProxy::activate();
  //设置功能对话框样式
  auto cmdWnd = static_cast<XCommandWnd*>(m_pFrame->getCommandWindow());
  cmdWnd->setStyleSheet(QString("background-color:#F8F8F8; "));
  //设置程序名称
  m_pFrame->setWindowTitle(QString().fromLocal8Bit("静力分析前处理"));
  //恢复视图视角
  if (m_pDoc->getViewData()->getVisualAngle()->isValid())getRender()->loadVisualAngle(m_pDoc->getViewData()->getVisualAngle());
  //设置视图背景色
  XPreference::getInstance()->setVariable(_RENDER_BACKGROUND_TOP_COLOR, "216,216,255", "ui");
  XPreference::getInstance()->setVariable(_RENDER_BACKGROUND_BOTTOM_COLOR, "128,128,192", "ui");
  getRender()->updateColorSetting();
  getRender()->refresh();
  //布局子窗口
  auto treeDock = m_pFrame->getDock(m_pFrame->getObjectTree());
  m_pFrame->removeDockWidget(treeDock);
  m_pFrame->addDockWidget(Qt::LeftDockWidgetArea, treeDock);
  auto prpDock = m_pFrame->getDock(m_pFrame->getPropertyWnd());
  m_pFrame->removeDockWidget(prpDock);
  m_pFrame->addDockWidget(Qt::LeftDockWidgetArea, prpDock);
  auto pickDock = m_pFrame->getDock(m_pFrame->getPickWnd());
  m_pFrame->removeDockWidget(pickDock);
  m_pFrame->addDockWidget(Qt::LeftDockWidgetArea, pickDock);
  auto msgDock = m_pFrame->getDock(m_pFrame->getMessageWnd());
  m_pFrame->removeDockWidget(msgDock);
  m_pFrame->addDockWidget(Qt::BottomDockWidgetArea, msgDock);
  m_pFrame->setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
  m_pCmdDock->setWidget(cmdWnd);
  cmdWnd->setWndButtonVisible(Wnd_OK | Wnd_Cancel, false);
  m_pFrame->addDockWidget(Qt::LeftDockWidgetArea, m_pCmdDock);
  treeDock->showNormal();
  msgDock->showNormal();
  prpDock->showNormal();
  pickDock->showNormal();
  m_pCmdDock->showNormal();
  m_pFrame->splitDockWidget(treeDock, m_pCmdDock, Qt::Horizontal);
  m_pFrame->splitDockWidget(treeDock, prpDock, Qt::Vertical);
  pickDock->hide();
}

在离开该应用界面时,也应重新实现deactivate函数以清除该应用特有的设定,如固定功能对话框变为浮动对话框等等。

void PreUIProxy::deactivate()
{
  auto cmdWnd = static_cast<XCommandWnd*>(m_pFrame->getCommandWindow());
  cmdWnd->setDockFixed(false);
  getRender()->saveVisualAngle(m_pDoc->getViewData()->getVisualAngle());
  UIProxy::deactivate();
  m_pFrame->removeDockWidget(m_pCmdDock);
  cmdWnd->setParent(m_pFrame);
  m_pCmdDock->setWidget(0);
  m_pCmdDock->hide();
}

一般的,当用户在对象树上单击某个对象时会在XPropertyWnd显示其属性,如果希望在XPropertyWnd显示一些特殊的属性时,界面代理需要重新实现listProperty接口,如果希望显示材料分配的数量,按如下代码实现即可:

void TestProxy::listProperty(TypeID type,const XItem * item,TypeID domainType )
{
  const XItem * di = (const XItem *)item;
  auto doc = m_pFrame->getCurrentDocument();
  XPropertyWnd * psw = m_pFrame->getPropertyWnd();
  if (type == Domain_Material) {
    psw->clear();
    psw->addItem(&SheetItem("材料数量", doc->getItemManager(Domain_Material)->getItemCount()));
    psw->addItem(&SheetItem("材料分配数量", doc->getItemManager(Domain_Property)->getItemCount()));
  }
  else
    return UIProxy::listProperty(type, item, domainType);
}
dev_guide/adduiproxy.txt · Last modified: 2022/08/23 17:30 (external edit)