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的布局管理就介绍完毕了!

猜你喜欢

转载自blog.csdn.net/weixin_43335226/article/details/106993668
Qt5