Qt布局管理

Qt布局管理

  • 分割窗口QSplitter
  • 停靠窗口QDockWidget
  • 堆栈窗体QStackedWidget
  • 基本布局QLayout
    • 水平布局QHBoxLayout
    • 垂直布局QVBoxLayout
    • 栅格布局QGridLayout
    • 窗体布局QFormLayout
    • 栈布局QStackedLayout
    • 实例

分割窗口QSplitter

Splitter.pro

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Splitter
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += main.cpp

main.cpp

#include 
#include 
#include 

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QFont font("ZYSong18030", 12);                               //指定显示字体
    a.setFont(font);
    
    //Qt::AlignLeft, Qt::AlignRight
    //Qt::AlignCenter, Qt::AlignVCenter, Qt::AlignHCenter
    //Qt::AlignTop, Qt::AlignBottom
    //QTextEdit只能水平居中,不能垂直居中
    
     //左侧
    QTextEdit *textLeft = new QTextEdit(QObject::tr("Left Widget"));
    textLeft->setAlignment(Qt::AlignCenter);

     //右侧
    QTextEdit *textUp = new QTextEdit(QObject::tr("Top Widget"));
    textUp->setAlignment(Qt::AlignCenter);
    QTextEdit *textBottom = new QTextEdit(QObject::tr("Bottom Widget"));
    textBottom->setAlignment(Qt::AlignCenter);
    QSplitter *splitterRight = new QSplitter(Qt::Vertical);
    splitterRight->setOpaqueResize(false);
    splitterRight->addWidget(textUp);
    splitterRight->addWidget(textBottom);

    //主分割窗口
    QSplitter *splitterMain = new QSplitter(Qt::Horizontal, nullptr);
    splitterMain->addWidget(textLeft);
    splitterMain->addWidget(splitterRight);
    splitterMain->setStretchFactor(1, 1); //设置伸缩因子
    splitterMain->setWindowFlags(Qt::WindowCloseButtonHint);
    splitterMain->setWindowTitle(QObject::tr("Splitter"));
    splitterMain->show();

    return a.exec();
}

停靠窗口QDockWidget

DockWidget.pro

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = DockWindows
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += main.cpp \
        dockwindows.cpp
HEADERS  += dockwindows.h

main.cpp

#include 
#include "dockwindows.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    DockWindows w;
    w.show();

    return a.exec();
}

dockwindows.h

#ifndef DOCKWINDOWS_H
#define DOCKWINDOWS_H

#include 
#include 
#include 

class DockWindows : public QMainWindow {
    Q_OBJECT
public:
    explicit DockWindows(QWidget *parent = nullptr);
private:
    QTextEdit *te;
    QTextEdit *te1;
    QTextEdit *te2;
    QTextEdit *te3;
    QDockWidget *dock1;
    QDockWidget *dock2;
    QDockWidget *dock3;
};

#endif

dockwindows.cpp

#include "dockwindows.h"

DockWindows::DockWindows(QWidget *parent) : QMainWindow(parent) {
    te = new QTextEdit(tr("Main Window"));	//定义一个QTextEdit对象作为主窗口
    te->setAlignment(Qt::AlignCenter);
    setCentralWidget(te);          		//将此编辑框设为主窗口的中央窗体

    te1 = new QTextEdit(tr("Window1, the dock widget can be moved between docks by the user"));

    //停靠窗口1
    dock1 = new QDockWidget(tr("DockWindow1"));

    //QDockWidget::DockWidgetClosable
    //QDockWidget::DockWidgetMovable
    //QDockWidget::DockWidgetFloatable
    //QDockWidget::AllDockWidgetFeatures
    //QDockWidget::NoDockWidgetFeatures
    dock1->setFeatures(QDockWidget::DockWidgetMovable);	//可移动

    //Qt::LeftDockWidgetArea
    //Qt::RightDockWidgetArea
    //Qt::TopDockWidgetArea
    //Qt::BottomDockWidgetArea
    //Qt::AllDockWidgetArea
    //Qt::NoDockWidgetArea,只可停靠在插入处
    dock1->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);	//允许停靠区域

    dock1->setWidget(te1);

    addDockWidget(Qt::RightDockWidgetArea,dock1);

    //停靠窗口2
    te2 = new QTextEdit(tr("Window2, the dock widget can be detached from the main window, "
                           "and floated as an independent window, and can be close"));
    dock2 = new QDockWidget(tr("DockWindow2"));
    dock2->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable); //可关闭、可浮动
    dock2->setWidget(te2);
    addDockWidget(Qt::RightDockWidgetArea, dock2);

    //停靠窗口3
    te3 = new QTextEdit(tr("Window3, the dock widget can be closed, moved, and floated"));
    dock3 = new QDockWidget(tr("DockWindow3"));
    dock3->setFeatures(QDockWidget::AllDockWidgetFeatures);//全部特性
    dock3->setWidget(te3);
    addDockWidget(Qt::RightDockWidgetArea, dock3);

    setWindowTitle(tr("DockWindows"));	//设置主窗口的标题栏文字
}

堆栈窗体QStackedWidget

StackedWidget.pro

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = StackedWidget
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += main.cpp \
        stackdlg.cpp
HEADERS  += stackdlg.h

main.cpp

#include 
#include "stackdlg.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    StackDlg w;
    w.show();

    return a.exec();
}

stackdlg.h

#ifndef STACKDLG_H
#define STACKDLG_H

#include 
#include 
#include 
#include 
#include 

class StackDlg : public QDialog {
    Q_OBJECT
public:
    explicit StackDlg(QWidget *parent = nullptr);
private:
    QListWidget *list;
    QLabel *label1;
    QLabel *label2;
    QLabel *label3;
    QStackedWidget *stack;
    QHBoxLayout *mainLayout;
};

#endif

stackdlg.cpp

#include "stackdlg.h"

StackDlg::StackDlg(QWidget *parent) : QDialog(parent) {
    list = new QListWidget;
    //在新建的QListWidget控件中插入三个条目,作为选择项
    list->insertItem(0, tr("Window1"));
    list->insertItem(1, tr("Window2"));
    list->insertItem(2, tr("Window3"));
    list->setCurrentRow(0);

    //创建三个QLabel标签控件对象,作为堆栈窗口需要显示的三层窗体
    label1 = new QLabel(tr("WindowTest1"));
    label2 = new QLabel(tr("WindowTest2"));
    label3 = new QLabel(tr("WindowTest3"));

    stack = new QStackedWidget;
    //将创建的三个QLabel标签控件依次插入堆栈窗体中
    stack->addWidget(label1);
    stack->addWidget(label2);
    stack->addWidget(label3);
    stack->setCurrentIndex(0);
    connect(list, SIGNAL(currentRowChanged(int)), stack, SLOT(setCurrentIndex(int)));

    mainLayout = new QHBoxLayout(this);
    mainLayout->setMargin(5);//设定窗体边距
    mainLayout->setSpacing(5);		//设定各个控件之间的间距为5
    mainLayout->addWidget(list, 1);
    mainLayout->addWidget(stack, 3, Qt::AlignHCenter);

    setWindowFlags(Qt::WindowCloseButtonHint);
    setWindowTitle(tr("StackedWidget"));
}

基本布局QLayout

属性 说明
layoutName 名称
layoutLeftMargin 左边界距离
layoutTopMargin 上边界距离
layoutRightMargin 右边界距离
layoutBottomMargin 下边界距离
layoutSpacing 控件间距离
layoutStretch 伸缩因子
layoutSizeConstraint 大小约束条件
void addWidget(
	QWidget *widget,
	int fromRow,
	int fromColumn,
	int rowSpan,
	int columnSpan,
	Qt::Alignment alignment=0
)

void addLayout(
	QLayout *layout,
	int row,
	int column,
	int rowSpan,
	int columnSpan,
	Qt::Alignment alignment=0
)
//最优化显示(控件按sizeHint()显示),并无法改变大小。
setSizeConstraint(QLayout::SetFixedSize);

//设置排列顺序
setDirection(QBoxLayout::RightToLeft);
setDirection(QBoxLayout::BottomToTop);

水平布局QHBoxLayout

QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(fontComboBox);
layout->addWidget(textEdit);
layout->setSpacing(50);
//左,上,右,下
layout->setContentsMargins(0, 0, 50, 100);

垂直布局QVBoxLayout

栅格布局QGridLayout

QGridLayout *layout = new QGridLayout(this);
layout->addWidget(fontComboBox, 0, 0, 1, 2);
//1行0列开始,占据1行3列。
layout->addWidget(textEdit, 1, 0, 1, 3);
//设置列占用空间比
setColumnStretch

窗体布局QFormLayout

管理表单的标签和输入控件,最后一列占据所有空间。

栈布局QStackedLayout

特点:

  • 控件大小一致且充满父控件的显示区;
  • 不能直接嵌套其他布局管理器;
  • 能够自由切换需要显示的控件;
  • 每次能且仅能显示一个控件。
QStackedLayout *layout = new QStackedLayout(this);
layout->addWidget(&button1);
layout->addWidget(&button2);
layout->addWidget(&button3);
layout->setCurrentIndex(0);

实例

312.png
请添加图片描述

Example.pro

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Example
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += main.cpp \
    content.cpp \
    baseinfo.cpp \
    contact.cpp \
    detail.cpp
HEADERS  += content.h \
    baseinfo.h \
    contact.h \
    detail.h

main.cpp

#include 
#include 
#include 
#include "content.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QFont font("AR PL KaitiM GB",12);	//设置整个程序采用的字体与字号
    a.setFont(font);

    QListWidget *list = new QListWidget;	//(a)
    list->insertItem(0, QObject::tr("基本信息"));
    list->insertItem(1, QObject::tr("联系方式"));
    list->insertItem(2, QObject::tr("详细资料"));
    list->setCurrentRow(0);

    Content *content = new Content;		//(b)
    content->stack->setCurrentIndex(0);
    QObject::connect(list, SIGNAL(currentRowChanged(int)), content->stack, SLOT(setCurrentIndex(int)));//(c)

    //新建一个水平分割窗对象,作为主布局框
    QSplitter *splitterMain = new QSplitter(Qt::Horizontal, nullptr);
    splitterMain->addWidget(list);
    splitterMain->addWidget(content);
    splitterMain->setOpaqueResize(true);

    //设置主布局框即水平分割窗的标题
    splitterMain->setWindowTitle(QObject::tr("修改用户资料"));
    //设置主布局框即水平分割窗的最小尺寸
    splitterMain->setMinimumSize(splitterMain->minimumSize());
    //设置主布局框即水平分割窗的最大尺寸
    splitterMain->setMaximumSize(splitterMain->maximumSize());
    splitterMain->show();	//显示主布局框,其上面的控件一同显示

    return a.exec();
}

baseinfo.h

#ifndef BASEINFO_H
#define BASEINFO_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class BaseInfo : public QWidget {
    Q_OBJECT
public:
    explicit BaseInfo(QWidget *parent = 0);
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;
    QPixmap pixmap;
    QLabel *HeadIconLabel;
    QPushButton *UpdateHeadBtn;
    QHBoxLayout *TopRightLayout;
    //右下角部分
    QLabel *IntroductionLabel;
    QTextEdit *IntroductionTextEdit;
    QVBoxLayout *RightLayout;
    //底部
    QPushButton *OkBtn;
    QPushButton *CancelBtn;
    QHBoxLayout *BottomLayout;

    QGridLayout *mainLayout;
};

#endif

baseinfo.cpp

#include "baseinfo.h"

BaseInfo::BaseInfo(QWidget *parent) : QWidget(parent) {
    /************** 左侧 ******************************/
    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("备注:"));

    //Shape: NoFrame、Panel、Box、HLine、VLine、WinPanel
    //Shadow: Plain、Raised、Sunken
    //设置控件风格,QFrame::Shape和QFrame::Shadow两项配合设定。
    OtherLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken);//(a)

    LeftLayout = new QGridLayout();						//(b)
    //向布局中加入需要布局的控件
    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);					//(c)
    LeftLayout->setColumnStretch(1,3);

    /*********右侧*********/
    //右上角部分
    HeadLabel = new QLabel(tr("头像: "));
    HeadIconLabel = new QLabel;
    pixmap.load("312.png");
    HeadIconLabel->setPixmap(pixmap);
    HeadIconLabel->resize(pixmap.size());
    UpdateHeadBtn = new QPushButton(tr("更新"));
    //完成右上侧头像选择区的布局
    TopRightLayout = new QHBoxLayout();
    TopRightLayout->setSpacing(20);		//设定各个控件之间的间距为20
    TopRightLayout->addWidget(HeadLabel);
    TopRightLayout->addWidget(HeadIconLabel);
    TopRightLayout->addWidget(UpdateHeadBtn);
    //右下角部分
    IntroductionLabel = new QLabel(tr("个人说明:"));		//右下角部分
    IntroductionTextEdit = new QTextEdit;
    //完成右侧的布局
    RightLayout = new QVBoxLayout();
    RightLayout->addLayout(TopRightLayout);
    RightLayout->addWidget(IntroductionLabel);
    RightLayout->addWidget(IntroductionTextEdit);

    /*--------------------- 底部 --------------------*/
    OkBtn = new QPushButton(tr("确定"));
    CancelBtn = new QPushButton(tr("取消"));
    //完成下方两个按钮的布局
    BottomLayout = new QHBoxLayout();
    BottomLayout->addStretch();     //插入占位符
    BottomLayout->addWidget(OkBtn);
    BottomLayout->addWidget(CancelBtn);

    /*---------------------------------------------*/
    mainLayout = new QGridLayout(this);        //(e)
    mainLayout->setMargin(15);	//设定对话框的边距为15
    mainLayout->setSpacing(10);
    mainLayout->addLayout(LeftLayout,0,0);
    mainLayout->addLayout(RightLayout,0,1);
    mainLayout->addLayout(BottomLayout,1,0,1,2);
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);	//最优化显示(控件按sizeHint()显示 ),且大小固定

    setWindowTitle(tr("UserInfo"));
    setWindowFlags(Qt::WindowCloseButtonHint);
}

contact.h

#ifndef CONTACT_H
#define CONTACT_H

#include 
#include 
#include 
#include 
#include 

class Contact : public QWidget {
    Q_OBJECT
public:
    explicit Contact(QWidget *parent = 0);
private:
    QLabel *EmailLabel;
    QLineEdit *EmailLineEdit;
    QLabel *AddrLabel;
    QLineEdit *AddrLineEdit;
    QLabel *CodeLabel;
    QLineEdit *CodeLineEdit;
    QLabel *MoviTelLabel;
    QLineEdit *MoviTelLineEdit;
    QCheckBox *MoviTelCheckBook;
    QLabel *ProTelLabel;
    QLineEdit *ProTelLineEdit;
    QGridLayout *mainLayout;
};

#endif

contact.cpp

#include "contact.h"

Contact::Contact(QWidget *parent) : QWidget(parent) {
    EmailLabel = new QLabel(tr("电子邮件:"));
    EmailLineEdit = new QLineEdit;
    AddrLabel = new QLabel(tr("联系地址:"));
    AddrLineEdit = new QLineEdit;
    CodeLabel = new QLabel(tr("邮政编码:"));
    CodeLineEdit = new QLineEdit;
    MoviTelLabel = new QLabel(tr("移动电话:"));
    MoviTelLineEdit = new QLineEdit;
    MoviTelCheckBook = new QCheckBox(tr("接收留言"));
    ProTelLabel = new QLabel(tr("办公电话:"));
    ProTelLineEdit = new QLineEdit;
    mainLayout = new QGridLayout(this);
    mainLayout->setMargin(15);
    mainLayout->setSpacing(10);
    mainLayout->addWidget(EmailLabel,0,0);
    mainLayout->addWidget(EmailLineEdit,0,1);
    mainLayout->addWidget(AddrLabel,1,0);
    mainLayout->addWidget(AddrLineEdit,1,1);
    mainLayout->addWidget(CodeLabel,2,0);
    mainLayout->addWidget(CodeLineEdit,2,1);
    mainLayout->addWidget(MoviTelLabel,3,0);
    mainLayout->addWidget(MoviTelLineEdit,3,1);
    mainLayout->addWidget(MoviTelCheckBook,3,2);
    mainLayout->addWidget(ProTelLabel,4,0);
    mainLayout->addWidget(ProTelLineEdit,4,1);
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);
}

detail.h

#ifndef DETAIL_H
#define DETAIL_H

#include 
#include 
#include 
#include 
#include 
#include 

class Detail : public QWidget {
    Q_OBJECT
public:
    explicit Detail(QWidget *parent = 0);
private:
    QLabel *NationalLabel;
    QComboBox *NationalComboBox;
    QLabel *ProvinceLabel;
    QComboBox *ProvinceComboBox;
    QLabel *CityLabel;
    QLineEdit *CityLineEdit;
    QLabel *IntroductLabel;
    QTextEdit *IntroductTextEdit;
    QGridLayout *mainLayout;
};

#endif

detail.cpp

#include "detail.h"

Detail::Detail(QWidget *parent) : QWidget(parent) {
    NationalLabel = new QLabel(tr("国家/地址:"));
    NationalComboBox = new QComboBox;
    NationalComboBox->insertItem(0,tr("中国"));
    NationalComboBox->insertItem(1,tr("美国"));
    NationalComboBox->insertItem(2,tr("英国"));
    ProvinceLabel = new QLabel(tr("省份:"));
    ProvinceComboBox = new QComboBox;
    ProvinceComboBox->insertItem(0,tr("江苏省"));
    ProvinceComboBox->insertItem(1,tr("山东省"));
    ProvinceComboBox->insertItem(2,tr("浙江省"));
    CityLabel = new QLabel(tr("城市:"));
    CityLineEdit = new QLineEdit;
    IntroductLabel = new QLabel(tr("个人说明:"));
    IntroductTextEdit = new QTextEdit;
    mainLayout = new QGridLayout(this);
    mainLayout->setMargin(15);
    mainLayout->setSpacing(10);
    mainLayout->addWidget(NationalLabel,0,0);
    mainLayout->addWidget(NationalComboBox,0,1);
    mainLayout->addWidget(ProvinceLabel,1,0);
    mainLayout->addWidget(ProvinceComboBox,1,1);
    mainLayout->addWidget(CityLabel,2,0);
    mainLayout->addWidget(CityLineEdit,2,1);
    mainLayout->addWidget(IntroductLabel,3,0);
    mainLayout->addWidget(IntroductTextEdit,3,1);
}

content.h

#ifndef CONTENT_H
#define CONTENT_H

#include 
#include 
#include 
#include "baseinfo.h"
#include "contact.h"
#include "detail.h"

class Content : public QFrame {
    Q_OBJECT
public:
    explicit Content(QWidget *parent = 0);

    BaseInfo  *baseInfo;
    Contact *contact;
    Detail *detail;
    QStackedWidget *stack;

    QPushButton *AmendBtn;
    QPushButton *CloseBtn;
    QHBoxLayout *BtnLayout;

    QVBoxLayout *mainLayout;
};

#endif

content.cpp

#include "content.h"

Content::Content(QWidget *parent) : QFrame(parent) {
    baseInfo = new BaseInfo();
    contact = new Contact();
    detail = new Detail();
    stack = new QStackedWidget(this);	//创建一个QStackedWiget对象
    //对堆栈窗口的显示风格进行设置
    stack->setFrameStyle(QFrame::Panel|QFrame::Raised);
    /* 插入三个页面 */
    stack->addWidget(baseInfo);
    stack->addWidget(contact);
    stack->addWidget(detail);
    /* 创建两个按钮 */					//(b)
    AmendBtn = new QPushButton(tr("修改"));
    CloseBtn = new QPushButton(tr("关闭"));
    BtnLayout = new QHBoxLayout;
    BtnLayout->addStretch(1);
    BtnLayout->addWidget(AmendBtn);
    BtnLayout->addWidget(CloseBtn);
    /* 进行整体布局 */
    mainLayout  = new QVBoxLayout(this);
    mainLayout->setMargin(10);
    mainLayout ->setSpacing(6);
    mainLayout ->addWidget(stack);
    mainLayout ->addLayout(BtnLayout);
}

你可能感兴趣的:(qt,学习,整理,qt,布局管理)