qt布局嵌套_QDockWidget嵌套布局详解-实现Visual Studio布局
概述
許多工程軟件,如Qt Creator,VS,matlab等,都是使用dock布局窗口,這樣用戶可以自定義界面,自由組合窗口。
Qt的嵌套布局由QDockWidget完成,用Qt Creator拖界面得到的dock布置形式比較固定,不能得想要的任意組合形式,要得到如下圖所示的效果,后續布局必須通過代碼來完成。
?
ps:這是自己沒事寫的一個數據可視化軟件
下面說說如何實現完全自由的界面布局效果:
QDockWidget在QMainWindow的布局函數
要在QMainWindow里對dock進行布局,需要用到如下幾個函數:
添加dock函數
此函數用于給dock指定位置,同時也可以更改dock的位置,此函數命名為addDockWidget有點容易誤導,因為不僅僅有add的功能,還有chang的功能
void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)
void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)
1
2
1
2
分割dock窗口函數
此函數的功能是把兩個dock進行左右或上下并排布置,做成一個類似QSplit的功能
void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)
1
1
tab化窗口函數
此函數的功能是把多個dock變成一個tab形式的窗體
void QMainWindow::tabifyDockWidget(QDockWidget * first, QDockWidget * second)
1
1
設置dock嵌套布局
此函數是設置嵌套布局的關鍵
void QMainWindow::setDockNestingEnabled(bool enabled)
1
1
以上幾個函數就能完成比較復雜的嵌套布局了。
設置嵌套布局
下面通過例子來講解如何設置復雜的嵌套布局
先用Qt Creator拖放9個dock進視圖里,為了好區分,給每個dock設置一個背景顏色:
?
dock屬性隨便設置,保證都任意區域可以停靠即可
由于這里不需要MainWindow的中間窗口,整個視圖都由dock組成,因此先把QMainWindow的中間窗口部件去除:
在MainWindow的構造函數加入如下語句,即可把MainWindow的中間窗口去除,這時整個MainWindow只有Dock組成
QWidget* p = takeCentralWidget();
if(p)
delete p;
1
2
3
1
2
3
編譯出來的效果如圖所示:
?
拖動dock可以發現,只能在兩邊進行組合,我想把dock放置到中間是無法實現的,這是由于為了簡化dock的吸附,QMainWindow默認是把dock嵌套關閉的,需要我們手動設置,在MainWindow的構造函數里添加:
setDockNestingEnabled(true);
1
1
即可打開嵌套功能,這時編譯出來的窗口能實現如下嵌套:
?
此時,整個窗口的布局將變得非常靈活且復雜,由于Qt Creator在ui編輯器中無法像編譯出來的程序那樣任意調整位置,因此需要手動對窗口進行設置。下面將介紹如何用代碼設置復雜的dock
為了方便,添加兩個函數和一個成員變量:
head:
public:
//移除并隱藏所有dock
void removeAllDock();
//顯示dock窗口
void showDock(const QList& index = QList());
private:
QList m_docks;///< 記錄所有dockWidget的指針
1
2
3
4
5
6
7
1
2
3
4
5
6
7
CPP:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//刪除中央窗體
QWidget* p = takeCentralWidget();
if(p)
delete p;
//允許嵌套dock
setDockNestingEnabled(true);
//記錄所有的dock指針
m_docks.append(ui->dockWidget_1);
m_docks.append(ui->dockWidget_2);
m_docks.append(ui->dockWidget_3);
m_docks.append(ui->dockWidget_4);
m_docks.append(ui->dockWidget_5);
m_docks.append(ui->dockWidget_6);
m_docks.append(ui->dockWidget_7);
m_docks.append(ui->dockWidget_8);
m_docks.append(ui->dockWidget_9);
}
MainWindow::~MainWindow()
{
delete ui;
}
///
/// \brief 移除并隱藏所有的dock
///
void MainWindow::removeAllDock()
{
for(int i=0;i<9;++i)
{
removeDockWidget(m_docks[i]);
}
}
///
/// \brief 顯示指定序號的dock
/// \param index 指定序號,如果不指定,則會顯示所有
///
void MainWindow::showDock(const QList &index)
{
if (index.isEmpty())
{
for(int i=0;i<9;++i)
{
m_docks[i]->show();
}
}
else
{
foreach (int i, index) {
m_docks[i]->show();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void removeAllDock();函數可以把所有的dock隱藏void showDock(const QList& index = QList())則可以顯示指定的dock。
下面先對需要用到的幾個函數進行示范:
addDockWidget
addDockWidget函數用于給MainWindow添加dock窗體,指定添加的區域,如果想改變dock的位置,也可以使用此函數進行移動。
void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)
void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)
1
2
1
2
如:
addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
addDockWidget(Qt::RightDockWidgetArea,ui->dockWidget_2);
addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_3);
addDockWidget(Qt::BottomDockWidgetArea,ui->dockWidget_4);
1
2
3
4
1
2
3
4
把4個dock按照上下左右布置,效果如下:
splitDockWidget
splitDockWidget
void QMainWindow::splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)
1
1
此函數可以把一個dock(QDockWidget * first)在其位置上進行嵌套,嵌套可以指定水平嵌套或者垂直嵌套,嵌套方向是從左到右,從上到下,也就是QDockWidget * first相對于QDockWidget * second永遠在左邊或者上邊。
如:
removeAllDock();
addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal);
splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Horizontal);
showDock(QList()<< 0<<1<<2<<3<<4);
1
2
3
4
5
6
7
1
2
3
4
5
6
7
得到如下效果:
?
若是:
removeAllDock();
addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Vertical);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Vertical);
splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Vertical);
splitDockWidget(ui->dockWidget_4,ui->dockWidget_5,Qt::Vertical);
showDock(QList()<< 0<<1<<2<<3<<4);
1
2
3
4
5
6
7
1
2
3
4
5
6
7
那么效果變為:
?
此函數是實現嵌套布局的關鍵,首先指定基準,然后開始進行分割,即可得到比較復雜的布局。
分割原則是:先水平,再豎直,從左到右,從上到下
下面顯示一個九宮格布局:
?
實現代碼
removeAllDock();
//原則,先左右,再上下
addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Vertical);
splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical);
splitDockWidget(ui->dockWidget_5,ui->dockWidget_8,Qt::Vertical);
splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical);
showDock();
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
?
實現代碼:
removeAllDock();
//原則,先左右,再上下
addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Vertical);
splitDockWidget(ui->dockWidget_6,ui->dockWidget_9,Qt::Vertical);
showDock(QList()<< 0<<1<<2<<3<<5<<6<<8);
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
10
?
實現代碼:
removeAllDock();
addDockWidget(Qt::TopDockWidgetArea,ui->dockWidget_1);
addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_2);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
splitDockWidget(ui->dockWidget_3,ui->dockWidget_4,Qt::Horizontal);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Horizontal);
splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Horizontal);
splitDockWidget(ui->dockWidget_4,ui->dockWidget_7,Qt::Horizontal);
showDock(QList()<< 0<<1<<2<<3<<4<<5<<6);
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
反正就是用splitDockWidget和addDockWidget你想怎么布置就怎么布置。
tabifyDockWidget
此函數就是實現tab合并功能
直接看看下面例子:
?
實現原理:
removeAllDock();
addDockWidget(Qt::LeftDockWidgetArea,ui->dockWidget_1);
splitDockWidget(ui->dockWidget_1,ui->dockWidget_2,Qt::Horizontal);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_3,Qt::Horizontal);
splitDockWidget(ui->dockWidget_1,ui->dockWidget_4,Qt::Vertical);
splitDockWidget(ui->dockWidget_2,ui->dockWidget_5,Qt::Vertical);
splitDockWidget(ui->dockWidget_3,ui->dockWidget_6,Qt::Vertical);
tabifyDockWidget(ui->dockWidget_1,ui->dockWidget_7);
tabifyDockWidget(ui->dockWidget_5,ui->dockWidget_8);
tabifyDockWidget(ui->dockWidget_3,ui->dockWidget_9);
showDock();
1
2
3
4
5
6
7
8
9
10
11
1
2
3
4
5
6
7
8
9
10
11
代碼:
本例代碼下載:本例代碼免積分-
http://blog.csdn.net/czyt1988/article/details/51209619#comments
NUint使用詳解及Visual Studio配置
NUint使用詳解及Visual Studio配置 閱讀目錄 什么是單元測試? 為什么使用單元測試? NUint使用詳解: 示例 屬性 斷言 簡單測試 VS配置: External Tools Vis ...
Android 布局學習之——Layout(布局)詳解二(常見布局和布局參數)
[Android布局學習系列] ? 1.Android 布局學習之——Layout(布局)詳解一 ? 2.Android 布局學習之——Layout(布局)詳解二(常見布局和布局參數) ? 3.And ...
【單元測試】NUint使用詳解及Visual Studio配置
閱讀目錄 什么是單元測試? 為什么使用單元測試? NUint使用詳解: 示例 屬性 斷言 簡單測試 VS配置: External Tools Visual Nunit 2010 NUnit Test ...
Android五大布局詳解——FrameLayout(幀布局)
FrameLayout 這個布局相對前面兩節介紹的布局就簡單了很多,因此它的應用場景也就特別的少.這種布局沒有方便的定位方式,所有的控件都會默認擺放在布局的左上角.新建UILayoutTestThre ...
Android五大布局詳解——LinearLayout(線性布局)
Android五大布局 本篇開始介紹Android的五大布局的知識,一個豐富的界面顯示總是要有眾多的控件來組成的,那么怎樣才能讓這些控件能夠按你的想法進行擺放,從而自定義你所想要的用戶界面呢?這就牽涉 ...
詳解在Visual Studio中使用git版本系統[轉]
這篇教程的預期,是希望沒有任何版本使用基礎的新手也可以掌握,所以細節較多,不當之處,歡迎指正. 一 .安裝 git 開發工具 如果要使用 git 進行版本管理,其實使用 git 命令行工具就完全足夠了 ...
詳解在visual studio中使用git版本系統(圖文)
很多人已經在使用git(或正在轉移到git上),在github.com上,也看到園子里不少同學的開源項目,非常不錯.但相關教程似乎不多,所以趁著我自己的開源項目源碼托管(https://github. ...
詳解在Visual Studio中使用git版本系統
轉自:http://www.uml.org.cn/pzgl/201206211.asp
【轉】詳解在visual studio中使用git版本系統(圖文)
http://blog.csdn.net/wojilu/article/details/6976230 很多人已經在使用git(或正在轉移到git上),在github.com上,也看到不少國內同學的開 ...
隨機推薦
安卓SQLite常見錯誤
利用閑時寫了一個簡單的Sql語句操作SQLite數據庫,在用SimpleCursorAdapter時出了一個異常好久都沒解決 Process: com.example.chunchuner.usesq ...
Flatten Binary Tree to Linked List
Flatten a binary tree to a fake "linked list" in pre-order traversal. Here we use the?righ ...
MSP430F149學習之路——LED
#include void int_clk(); void delay(int i); void main() { WDTCTL = WDTPW + WDTH ...
JS 獲取Button控件的提交類型
windows下查找指定端口被哪個程序占用
在Windows環境下,用netstat命令查看某個端口號是否占用,為哪個進程所占用. eg.查看端口號為61078被哪個程序占用 1.查看端口號為61079被哪個PID所占用:Netstat –an ...
javascript實現小鳥飛行軌跡
javascript實現小鳥飛行軌跡 代碼如下:
WPF在在設計模式,使用動態樣式
1.問題分析 WPF有時候要用到主題樣式,比如顏色主題(紅色.黃色之類的)通常是key相同,而value不同,比如會這么寫: Background="{DynamicResource Bac ...
LeetCode算法題-Non-decreasing Array(Java實現)
這是悅樂書的第283次更新,第300篇原創 01 看題和準備 今天介紹的是LeetCode算法題中Easy級別的第151題(順位題號是665).給定一個包含n個整數的數組,您的任務是通過修改最多1個元 ...
Ubuntu網絡不通解決辦法
如下問題: 嘗試和Host主機互ping也不通, Ubuntu: vmware 橋接模式 IP:192.168.1.202/24 gateway:192.168.1.1 Host主機:網絡正常 IP: ...
通過C#調用,實現js加密代碼的反混淆,并運行js函數
前一篇我測試了vba調用htmlfile做反混淆,并執行js加密函數的代碼.本文換成C#實現. 聯系QQ:564955427 C#操作JS函數,可以通過ScriptControl組件,但這個組件只能在 ...
總結
以上是生活随笔為你收集整理的qt布局嵌套_QDockWidget嵌套布局详解-实现Visual Studio布局的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: arp miss攻击_网络应用华为S93
- 下一篇: vm虚拟机安装_虚拟机 --- 安装V