單窗口多視口實現思路
眾多工程應用軟件中,一個模型中查看的數據會多種多樣,比如:三維模型視圖,受力圖表等。然后,在查看過程中,用戶可能還需要同時對各種數據進行對比查看等。在以前的軟件中,多視口的實現通過多選項卡(多窗口)模式來實現的,如下圖,這在軟件操作過程中給用戶帶來了極大的不變,對于多模型來說,更是痛苦至極。

目前多視口的界面大體如下:

其中,左上為工程的整體三維視圖,右上為計算域三維網格,左下為切片、矢量圖等后處理結果,右下為部分邊界網格。
這僅是列舉的一小部分,這對于用戶來說,查看不同的數據,對比分析也更加直觀。而卻各個視口獨立于其他視口,只與當前的工程有關。用戶可以在不同的視口中做不同的操作,不影響其他視口。
實現思路:
多視口中,每個視口都“貼”在一個父窗口上。當視口被分割成兩個視口時,首先創建一個父窗口,用來“裝”原視口和新創建出來的視口,然后再將創建的父窗口“貼”于原視口的位置。流程如下表示:

實現流程:
通過上述流程,不難發現,這與數據結構中的二叉樹的數據結構類似,因此,采用動態數組來描述多視口數據。父窗口采用Qt中的QSplitter類,視口為相應的窗口類。
1. 定義數據元素類型:
struct ViewCell
{
Direction direction; // 方向
double splitFraction; // 分割比例
QWidget* view;
ViewCell() : direction(NONE), splitFraction(0.5), view(0) {}
};
其中,direction和splitFraction當為父窗口時有效。
2. 定義數據結構
QVector<ViewCell> m_Cells;
3. 分割算法:
由于二叉樹的特性,每分割一次,數組的變為 (2*location)+2+1個,原視口變為 2*location+1,其中,location為當前窗口的序號(序號按照二叉樹的前序序號排列)。然后將location位置的元素類型更改為父窗口內容,將2*location+1位置的元素類型更改為原視口內容,偽代碼如下:
int split(int location, Direction direction, double fraction)
{
ViewCell cell = m_Cells[location];
cell.direction = direction;
cell.splitFraction = fraction;
m_Cells.resize(2 * location + 2 + 1);
int child_location = (2 * location + 1);
ViewCell& child = m_Cells[child_location];
child.view = cell.view;
cell.view = NULL;// 默認為空,在創建窗口函數中自動創建
m_Cells[location] = cell;
return child_location;
}
4. 創建窗口:
當二叉樹的數據完成后,接下來就需要創建窗口,刷新等操作了。可以按照二叉樹的前序遍歷進行迭代了。偽代碼如下:
QWidget* createWidget(int index, QWidget* parentWdg)
{
Direction direction = m_Cells[index].direction;
QWidget* widget = m_Cells[index].view;
switch (direction)
{
case NONE:
{
if (!widget)
{
widget = new QWidget(this);
}
frame->setParent(parentWdg);
m_Cells[index].view = widget;
return widget;
}
case VERTICAL:
case HORIZONTAL:
{
QSplitter* splitter = qobject_cast<QSplitter*>(widget);
if (!splitter)
{
splitter = new QSplitter(parentWdg);
}
m_Cells[index].view = splitter;
splitter->setParent(parentWdg);
splitter->setOrientation(direction);
// 采用前序遍歷,迭代
splitter->insertWidget(0, createWidget(2 * index + 1, splitter));
splitter->insertWidget(1, createWidget(2 * index + 2, splitter));
return splitter;
}
}
return NULL;
}
到此,多視口的大體實現已經完成。
工程師必備
- 項目客服
- 培訓客服
- 平臺客服
TOP




















