QT5开发||09、QT5布局管理
摘要:
所谓 GUI 界面,归根结底,就是一堆组件的叠加。我们创建一个窗口,把按钮放上面,把图标放上面,这样就成了一
个界面。在放置时,组件的位置尤其重要。我们必须要指定组件放在哪里,以便窗口能够按照我们需要的方式进行渲
染。这就涉及到组件定位的机制。Qt 提供了两种组件定位机制:绝对定位和布局定位。
针对这种变化的需求,Qt 提供了另外的一种机制—布局—来解决这个问题。你只要把组件放入某一种布局,布局由专
门的布局管理器进行管理。布局管理是对Qt主窗体MainWindow和其他窗口的布局。下面主要介绍几种Qt布局管理类的使用和实现
一、分割窗体QSplitter类
1、分割窗体
介绍一个十分简单的分割窗口功能,整个对话框由三个窗口组成,各个窗口之间的大小可随意拖曳改变,如下图所示:
2、实现步骤
(1)新建Qt Gui应用 ,选择Qt Widgets Application,项目名称为“Splitter”基类选择“QMainWindow”, 取消“创建界面”复选
框的选中状态。
(2)在上述工程的‘main.cpp”文件中添加如下代码。
QFont font("ZYSong18030",12);//选择字体,大小为12号
a.setFont(font);
//设置主分割窗口
QSplitter *splitterMain =new QSplitter(Qt::Horizontal,0);
QTextEdit *textLeft =new QTextEdit(QObject::tr("Left Widget"),splitterMain);
textLeft->setAlignment(Qt::AlignCenter);
//设置右部分割窗口
QSplitter *splitterRight =new QSplitter(Qt::Vertical,splitterMain);
splitterRight->setOpaqueResize(false);
QTextEdit *textUp =new QTextEdit(QObject::tr("Top Widget"),splitterRight);
textUp->setAlignment(Qt::AlignCenter);
QTextEdit *textBottom =new QTextEdit(QObject::tr("Bottom Widget"),splitterRight);
textBottom->setAlignment(Qt::AlignCenter);
splitterMain->setStretchFactor(1,1);
splitterMain->setWindowTitle(QObject::tr("Splitter"));
splitterMain->show();
(3)在main.cpp” 文件的开始部分加入以下头文件:
#include <Qspltter>
#include <QTextEdit>
#include <QTextCodec>
(4)、运行程序,显示效果如上图所示。
二、停靠窗口QDockWidget类
1、停靠窗口QDockWidget类
停靠窗口QDockWidget类也是应用程序中经常用到的。设置停靠窗口的一般流程如下。
(1) 创建一个QDockWidget对象的停靠窗体。
(2)设置此停靠窗体的属性,通常调用setFeatures()及setAllowedAreas()两种方法。
(3)新建一个要插入停靠窗体的控件,常用的有QListWidget和QTextEdit。
(4)将控件插入停靠窗体,调用QDockWidget的setWidget()方法。
(5)使用addDockWidget()方法在MainWindow中加入此停靠窗体。
2、案例分析
下面通过一个简单的例子来学习停靠窗口QDockWidget类的使用,窗口1只可在主窗口的左边和右边停靠;窗口2只可在
浮动和右部停靠两种状态间切换,并且不可移动;窗口3可实现停靠窗口的各种状态。效果如下图所示。
3、实现步骤
(1) 新建Qt Gui应用 ,选择Qt Widgets Application,项目名称为“DockWindows”, 基类选择“ QMainWindow”,类名命
名为“DockWindows”,取消“创建界面”复选框的选中状态。 如下图所示。
(2) DockWindows 类说明中只有一个构造函数的说明。代码如下:
class DockWindows : public QMainWindow
{
Q_OBJECT
public:
DockWindows(QWidget *parent = 0);
~DockWindows();
};
(3)打开“dockwindows.cpp” 文件, DockWindows 类构造函数实现窗口的初始化及功能实现,具体代码如下:
DockWindows::DockWindows(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(tr("DockWindows")); //设置主窗口的标题栏文字
QTextEdit *te=new QTextEdit(this); //定义一个QTextEdit对象作为主窗口
te->setText(tr("Main Window")); //设置主窗口框中的文字
te->setAlignment(Qt::AlignCenter);
setCentralWidget(te); //将此编辑框设为主窗口的*窗体
//停靠窗口1
QDockWidget *dock=new QDockWidget(tr("DockWindow1"),this);
dock->setFeatures(QDockWidget::DockWidgetMovable); //设置可移动
dock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);
QTextEdit *te1 =new QTextEdit();
te1->setText(tr("Window1,The dock widget can be moved between docks by the user" "")); //设置窗口1框中的文字
dock->setWidget(te1);
addDockWidget(Qt::RightDockWidgetArea,dock);
//停靠窗口2
dock=new QDockWidget(tr("DockWindow2"),this);
dock->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable); //可关闭、可浮动
QTextEdit *te2 =new QTextEdit();
te2->setText(tr("Window2,The dock widget can be detached from the main window,""and floated as an independent window, and can be closed")); //设置窗口2框中的文字
dock->setWidget(te2);
addDockWidget(Qt::RightDockWidgetArea,dock);
//停靠窗口3
dock=new QDockWidget(tr("DockWindow3"),this);
dock->setFeatures(QDockWidget::AllDockWidgetFeatures); //全部特性
QTextEdit *te3 =new QTextEdit();
te3->setText(tr("Window3,The dock widget can be closed, moved, and floated")); //设置窗口3框中的文字
dock->setWidget(te3);
addDockWidget(Qt::RightDockWidgetArea,dock);
}
(4)在“dockwindows.cpp” 文件的开始部分加入以下头文件:
#include <QTextEdit>
#include <QDockWidget>
(5)运行程序,显示结果如上图所示。
三、堆栈窗体QStackedWidget类
1、堆栈窗体QStackedWidget类
通过一个简单的例子来学习堆栈窗体QStackedWidget类的使用,当选择左侧列表框中不同的选项时,右侧显示所
选的不同的窗体。在此使用列表框QListWidget,效果如下图所示。
2、实现步骤
(1) 新建Qt Gui应用 ,选择Qt Widgets Application,项目名称为“StackedWidget”, 基类选择“ QDialog”,类名命名为
“StackDlg”,取消“创建界面”复选框的选中状态。 如下图所示。
(2)、打开"stackdlg.h"文件,添加以下私有成员,分别为ListWidget、StackedWidget和两个Label:
class StackDlg : public QDialog
{
Q_OBJECT
public:
StackDlg(QWidget *parent = 0);
~StackDlg();
private:
QListWidget *list;
QStackedWidget *stack;
QLabel *label1;
QLabel *label2;
QLabel *label3;
};
并在头文件中添加以下头文件:
#include <QListWidget>
#include <QStackedWidget>
#include <QLabel>
(3)打开“stackdlg.cpp"文件,在停靠窗体StackDlg类的构造函数中添加以下代码。
StackDlg::StackDlg(QWidget *parent)
: QDialog(parent)
{
//设置窗口标题
setWindowTitle(tr("StackedWidget"));
//新建QListWidget窗口为三个项目窗口
list =new QListWidget(this);
list->insertItem(0,tr("Window1"));
list->insertItem(1,tr("Window2"));
list->insertItem(2,tr("Window3"));
//设置三个窗口标题
label1 =new QLabel(tr("WindowTest1"));
label2 =new QLabel(tr("WindowTest2"));
label3 =new QLabel(tr("WindowTest3"));
//新建QStackedWidget堆栈窗体
stack =new QStackedWidget(this);
stack->addWidget(label1);
stack->addWidget(label2);
stack->addWidget(label3);
//新建QHBoxLayout水平排列布局,并对三个窗口进行布局管理
QHBoxLayout *mainLayout =new QHBoxLayout(this);
mainLayout->setMargin(5);
mainLayout->setSpacing(5);
mainLayout->addWidget(list);
mainLayout->addWidget(stack,0,Qt::AlignHCenter);
mainLayout->setStretchFactor(list,1);
mainLayout->setStretchFactor(stack,3);
//创建信号与槽,实现堆栈窗口1、2、3的切换
connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)));
}
(4)在stackdlg.cpp文件 的开始部分加入以下头文件:
#include <QHBoxLayout>
(5)运行程序,显示效果如上图所示。
四、基本布局(QLayout)
Qt提供了QHBoxLayout类、QVBoxL _ayout类及QGridL .ayout类等的基本布局管理,分别是水平排列布局、垂直排列
布局和网格排列布局。它们之间的继承关系如下图所示。
addWidget()方法用于向布局中加入需要布局的控件,addWidget()的 函数原型如下:
void addWidget
(
QWidget *widget,
//需要插入的控件对象
int fromRow,
//插入的行
int fromColumn,
//插入的列
int rowSpan,
//表示占用的行数
int columnSpan,
//表示占用的列数
Qt::Alignment alignment=0
//描述各个控件的对齐方式
)
1、addLayout ()添加子布局
addLayout ()方法用于向布局中加入需要布局的子布局,addLayout ()的函数原型如下:
void addl ayout
(
QLayout *layout,
//表示需要插入的子布局对象
int row,
//插入的起始行
int column,
//插入的起始列
int rowSpan,
//表示占用的行数
int columnSpan,
//表示占用的列数
Qt:Alignment alignment=0
//指定对齐方式
)
2、案例分析
下面将通过实现一个“用户基本资料修改”的功能表来介绍如何使用基本布局管理,如QHBoxL _ayout类、QVBoxLayout
类及QGridL .ayout类,效果如下图所示。
本实例共用到四个布局管理器,分别是LeftLayout、RightL ayout、BottomL _ayout和MainL ayout,其布局框架如下图所示。
3、实现步骤
(1) 新建Qt Gui应用 ,选择Qt Widgets Application,项目名称为“UserInfo”, 基类选择“ QDialog”,类名命名为“dialog”,
取消“创建界面”复选框的选中状态。 如下图所示。
(2) 打开“dialog.h” 头文件,在头文件中声明对话框中的各个控件。添加代码如下所示。
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = 0);
~Dialog();
private:
//左侧
QLabel *UserNameLabel;
QLabel *NameLabel;
QLabel *SexLabel;
QLabel *DepartmentLabel;
QLabel *AgeLabel;
QLabel *OtherLabel;
QLineEdit *UserNameLineEdit;
QLineEdit *NameLineEdit;
QComboBox *SexComboBox;
QTextEdit *DepartmentTextEdit;
QLineEdit *AgeLineEdit;
QGridLayout *LeftLayout;
//右侧
QLabel *HeadLabel; //右上角部分
QLabel *HeadIconLabel;
QPushButton *UpdateHeadBtn;
QHBoxLayout *TopRightLayout;
QLabel *IntroductionLabel;
QTextEdit *IntroductionTextEdit;
QVBoxLayout *RightLayout;
//底部
QPushButton *OkBtn;
QPushButton *CancelBtn;
QHBoxLayout *ButtomLayout;
};
添加如下的头文件:
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QTextEdit>
#include <QGridLayout>
(3) 打开“dialog.cpp” 文件,在类Dialog的构造函数中添加如下代码。
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
setWindowTitle(tr("UserInfo"));
/************** 左侧 ******************************/
UserNameLabel =new QLabel(tr("用户名:"));
UserNameLineEdit =new QLineEdit;
NameLabel =new QLabel(tr("姓名:"));
NameLineEdit =new QLineEdit;
SexLabel =new QLabel(tr("性别:"));
SexComboBox =new QComboBox;
SexComboBox->addItem(tr("女"));
SexComboBox->addItem(tr("男"));
DepartmentLabel =new QLabel(tr("部门:"));
DepartmentTextEdit =new QTextEdit;
AgeLabel =new QLabel(tr("年龄:"));
AgeLineEdit =new QLineEdit;
OtherLabel =new QLabel(tr("备注:"));
OtherLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken);
LeftLayout =new QGridLayout();
LeftLayout->addWidget(UserNameLabel,0,0); //用户名
LeftLayout->addWidget(UserNameLineEdit,0,1);
LeftLayout->addWidget(NameLabel,1,0); //姓名
LeftLayout->addWidget(NameLineEdit,1,1);
LeftLayout->addWidget(SexLabel,2,0); //性别
LeftLayout->addWidget(SexComboBox,2,1);
LeftLayout->addWidget(DepartmentLabel,3,0); //部门
LeftLayout->addWidget(DepartmentTextEdit,3,1);
LeftLayout->addWidget(AgeLabel,4,0); //年龄
LeftLayout->addWidget(AgeLineEdit,4,1);
LeftLayout->addWidget(OtherLabel,5,0,1,2); //其他
LeftLayout->setColumnStretch(0,1);
LeftLayout->setColumnStretch(1,3);
/*********右侧*********/
HeadLabel =new QLabel(tr("头像: ")); //右上角部分
HeadIconLabel =new QLabel;
QPixmap icon("312.png");
HeadIconLabel->setPixmap(icon);
HeadIconLabel->resize(icon.width(),icon.height());
UpdateHeadBtn =new QPushButton(tr("更新"));
TopRightLayout =new QHBoxLayout();
TopRightLayout->setSpacing(20);
TopRightLayout->addWidget(HeadLabel);
TopRightLayout->addWidget(HeadIconLabel);
TopRightLayout->addWidget(UpdateHeadBtn);
IntroductionLabel =new QLabel(tr("个人说明:")); //右下角部分
IntroductionTextEdit =new QTextEdit;
RightLayout =new QVBoxLayout();
RightLayout->setMargin(10);
RightLayout->addLayout(TopRightLayout);
RightLayout->addWidget(IntroductionLabel);
RightLayout->addWidget(IntroductionTextEdit);
/*--------------------- 底部 --------------------*/
OkBtn =new QPushButton(tr("确定"));
CancelBtn =new QPushButton(tr("取消"));
ButtomLayout =new QHBoxLayout();
ButtomLayout->addStretch();
ButtomLayout->addWidget(OkBtn);
ButtomLayout->addWidget(CancelBtn);
/*---------------------------------------------*/
QGridLayout *mainLayout =new QGridLayout(this);
mainLayout->setMargin(15);
mainLayout->setSpacing(10);
mainLayout->addLayout(LeftLayout,0,0);
mainLayout->addLayout(RightLayout,0,1);
mainLayout->addLayout(ButtomLayout,1,0,1,2);
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
}
(4)在“dialog.cpp” 文件的开始部分加入以下头文件:
#include<QLabel>
#include<QLineEdit>
#include<QComboBox>
#include<QPushButton>
#include<QFrame>
#include<QGridLayout>
#include<QPixmap>
#include<QHBoxLayout>
(5)选择“构建”→“构建项目"UserInfo"” 命令,为了能够在界面上显示头像图片,请将事先准备好的图片.png复制到D:\Q
项目工程目录:UserInfo\build-UserInfo-Desktop_Qt_5_13_2_MSVC2017_64bit-Debug目录下。
至此,QT5的布局管理就介绍完毕了!
上一篇: Qt探索之旅(三)可切换界面