第3章 Qt 5布局管理

一、分割窗口QSplitter类

【例】(简单)(CH301)一个十分简单的分割窗口功能,整个窗口由三个子窗口组成,各个子窗口之间的大小可随意拖曳改变,效果如图3.1所示。

 本实例采用编写代码的方式实现,具体步骤如下。

(1)新建Qt Widgets Application(详见1.3.1节),项目名称为“Splitter”,基类选择“QMainWindow”,取消“创建界面”复选框的选中状态。

(2)在上述工程的“main.cpp”文件中添加如下代码。

#include "mainwindow.h"
#include <QApplication>
#include<Qsplitter>
#include<QTextEdit>
#include <QTextCodec>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QFont font("ZYSong18030",12);                               //指定显示字体
    a.setFont(font);
    //主分割窗口
    QSplitter *splitterMain =new QSplitter(Qt::Horizontal,0);	//(a)
    QTextEdit *textLeft =new QTextEdit(QObject::tr("Left Widget"), splitterMain);//(b)
    textLeft->setAlignment(Qt::AlignCenter);					//(c)
    //右部分分割窗口												//(d)
    QSplitter *splitterRight =new QSplitter(Qt::Vertical,splitterMain);
    splitterRight->setOpaqueResize(false);						//(e)
    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);						//(f)
    splitterMain->setWindowTitle(QObject::tr("Splitter"));
    splitterMain->show();

    //MainWindow w;
    //w.show();

    return a.exec();
}

其中, (a) QSplitter *splitterMain =new QSplitter(Qt::Horizontal,0):新建一个QSplitter类对象,作为主分割窗口,设定此分割窗口为水平分割窗口。

(b) QTextEdit *textLeft =new QTextEdit(QObject::tr("Left Widget"),splitterMain):新建一个QTextEdit类对象,并将其插入主分割窗口中。

(c) textLeft->setAlignment(Qt::AlignCenter):设定TextEdit中文字的对齐方式

(d) QSplitter *splitterRight =new QSplitter(Qt::Vertical,splitterMain):新建一个QSplitter类对象,作为右分割窗口,设定此分割窗口为垂直分割窗口,并以主分割窗口为父窗口。

(e) splitterRight->setOpaqueResize(false):调用setOpaqueResize(bool)方法用于设定分割窗口的分割条在拖曳时是否为实时更新显示,若设为true则实时更新显示,若设为false则在拖曳时只显示一条灰色的粗线条,在拖曳到位并释放鼠标后再显示分割条。默认设置为true。

(f) splitterMain->setStretchFactor(1,1):调用setStretchFactor()方法用于设定可伸缩控件,它的第1个参数用于指定设置的控件序号,控件序号按插入的先后次序从0起依次编号;第2个参数为大于0的值,表示此控件为可伸缩控件。

二、停靠窗口QDockWidget类

停靠窗口QDockWidget类也是在应用程序中经常用到的,设置停靠窗口的一般流程如下。

(1)创建一个QDockWidget对象的停靠窗体。

(2)设置此停靠窗体的属性,通常调用setFeatures()及setAllowedAreas()两种方法。

(3)新建一个要插入停靠窗体的控件,常用的有QListWidget和QTextEdit。

(4)将控件插入停靠窗体,调用QDockWidget的setWidget()方法。

(5)使用addDockWidget()方法在MainWindow中加入此停靠窗体。

【例】(简单)(CH302)停靠窗口QDockWidget类的使用:窗口1只可在主窗口的左边和右边停靠;窗口2只可在浮动和右部停靠两种状态间切换,并且不可移动;窗口3可实现停靠窗口的各种状态。效果如图3.2所示。

 (1)新建Qt Widgets Application (详见1.3.1节),项目名称为“DockWindows”,基类选择“QMainWindow”,类名命名为“DockWindows”,取消“创建界面”复选框的选中状态。

(2)DockWindows类中只有一个构造函数的声明。位于“dockwindows.h”文件中,代码如下:

#ifndef DOCKWINDOWS_H
#define DOCKWINDOWS_H

#include <QMainWindow>

class DockWindows : public QMainWindow
{
    Q_OBJECT

public:
    DockWindows(QWidget *parent = 0);
    ~DockWindows();
};

#endif // DOCKWINDOWS_H

(3)打开“dockwindows.cpp”文件,DockWindows类构造函数实现窗口的初始化及功能实现,具体代码。

#include "dockwindows.h"
#include<QTextEdit>
#include<QDockWidget>
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);	//(a)
    dock->setAllowedAreas(Qt::LeftDockWidgetArea|Qt::RightDockWidgetArea);														//(b)
    QTextEdit *te1 =new QTextEdit();
    te1->setText(tr("Window1,The dock widget can be moved between docks by the user" ""));
    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"));
    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"));
    dock->setWidget(te3);
    addDockWidget(Qt::RightDockWidgetArea,dock);
}

DockWindows::~DockWindows()
{

}

其中,

(a) setFeatures()方法设置停靠窗体的特性,原型如下:    

void setFeatures(DockWidgetFeatures features)

参数QDockWidget::DockWidgetFeatures指定停靠窗体的特性,

包括以下几种参数。

① QDockWidget::DockWidgetClosable:停靠窗体可关闭。

② QDockWidget::DockWidgetMovable:停靠窗体可移动。

③ QDockWidget::DockWidgetFloatable:停靠窗体可浮动。

④ QDockWidget::AllDockWidgetFeatures:此参数表示拥有停靠窗体的所有特性。

⑤ QDockWidget::NoDockWidgetFeatures:不可移动、不可关闭、不可浮动。

(b) setAllowedAreas()方法设置停靠窗体可停靠的区域,原型如下:

void setAllowedAreas(Qt::DockWidgetAreas  areas)

参数Qt::DockWidgetAreas指定停靠窗体可停靠的区域,包括以下几种参数。

① Qt::LeftDockWidgetArea:可在主窗口的左侧停靠。

② Qt::RightDockWidgetArea:可在主窗口的右侧停靠。

③ Qt::TopDockWidgetArea:可在主窗口的顶部停靠。

④ Qt::BottomDockWidgetArea:可在主窗口的底部停靠。

⑤ Qt::AllDockWidgetArea:可在主窗口任意(以上四个)部位停靠。

⑥ Qt::NoDockWidgetArea:只可停靠在插入处。 各区域设定也可采用或(|)的方式进行。

三、堆栈窗体QStackedWidget类

【例】(简单)(CH303)堆栈窗体QStackedWidget类的使用,当选择左侧列表框中不同的选项时,右侧显示所选的不同的窗体。在此使用列表框QListWidget,效果如图3.4所示。

 本实例是采用编写代码的方式实现的,具体步骤如下:

(1)新建Qt Widgets Application(详见1.3.1节),项目名称为“StackedWidget”,基类选择“QDialog”,类名命名为“StackDlg”,取消“创建界面”复选框的选中状态。

(2)打开“stackdlg.h”文件:

#ifndef STACKDLG_H
#define STACKDLG_H

#include <QDialog>
#include <QListWidget>
#include <QStackedWidget>
#include <QLabel>
class StackDlg : public QDialog
{
    Q_OBJECT

public:
    StackDlg(QWidget *parent = 0);
    ~StackDlg();
private:
    QListWidget *list;
    QStackedWidget *stack;
    QLabel *label1;
    QLabel *label2;
    QLabel *label3;
};

#endif // STACKDLG_H

(3)打开“stackdlg.cpp”文件,在停靠窗体StackDlg类的构造函数中添加如下代码。

#include "stackdlg.h"
#include <QHBoxLayout>
StackDlg::StackDlg(QWidget *parent)
    : QDialog(parent)
{
    setWindowTitle(tr("StackedWidget"));
    list =new QListWidget(this);	//新建一个QListWidget控件对象
    //在新建的QListWidget控件中插入三个条目,作为选择项
    list->insertItem(0,tr("Window1"));
    list->insertItem(1,tr("Window2"));
    list->insertItem(2,tr("Window3"));
    //创建三个QLabel标签控件对象,作为堆栈窗口需要显示的三层窗体
    label1 =new QLabel(tr("WindowTest1"));
    label2 =new QLabel(tr("WindowTest2"));
    label3 =new QLabel(tr("WindowTest3"));
    stack =new QStackedWidget(this);
    //新建一个QStackedWidget堆栈窗体对象
    //将创建的三个QLabel标签控件依次插入堆栈窗体中
    stack->addWidget(label1);
    stack->addWidget(label2);
    stack->addWidget(label3);
    QHBoxLayout *mainLayout =new QHBoxLayout(this);
                                    //对整个对话框进行布局
    mainLayout->setMargin(5);		//设定对话框(或窗体)的边距为5
    mainLayout->setSpacing(5);		//设定各个控件之间的间距为5
    mainLayout->addWidget(list);
    mainLayout->addWidget(stack,0,Qt::AlignHCenter);
    mainLayout->setStretchFactor(list,1);		//(a)
    mainLayout->setStretchFactor(stack,3);
    connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int)));//(b)
}

StackDlg::~StackDlg()
{

}

其中,

(a) mainLayout->setStretchFactor(list,1):设定可伸缩控件,第1个参数用于指定设置的控件(序号从0起编号),第2个参数的值大于0则表示此控件为可伸缩控件。

(b) connect(list,SIGNAL(currentRowChanged(int)),stack,SLOT(setCurrentIndex(int))):将QListWidget的currentRowChanged()信号与堆栈窗体的setCurrentIndex()槽函数连接起来,实现按选择显示窗体。此处的堆栈窗体index按插入的顺序从0起依次排序,与QListWidget的条目排序相一致。

四、基本布局(QLayout)

Qt提供了QHBoxLayout类、QVBoxLayout类及QGridLayout类等的基本布局管理,分别是水平排列布局、垂直排列布局和网格排列布局。各种布局类及继承关系如图3.6所示。

布局中常用的方法有addWidget()和addLayout()。 addWidget()方法用于加入需要布局的控件,方法原型如下:

void addWidget
(
	QWidget *widget,           			//需要插入的控件对象
	int  fromRow,              			//插入的行
	int  fromColumn,           			//插入的列
	int  rowSpan,              			//表示占用的行数
	int  columnSpan,           			//表示占用的列数
	Qt::Alignment  alignment=0  			//描述各个控件的对齐方式
)

addLayout()方法用于加入子布局,方法原型如下:

void addLayout
(
	QLayout *layout,              			//表示需要插入的子布局对象
	int row,                      			//插入的起始行
	int column,                  			//插入的起始列
	int rowSpan,                  			//表示占用的行数
	int columnSpan,               			//表示占用的列数
	Qt::Alignment alignment=0      		//指定对齐方式
)

【例】(难度一般)(CH304)通过实现一个“用户基本资料修改”的功能表单来介绍如何使用基本布局管理,如QHBoxLayout类、QVBoxLayout类及QGridLayout类,效果如图3.7所示。

 本实例共用到四个布局管理器,分别是LeftLayout、RightLayout、BottomLayout和MainLayout,其布局框架如图3.8所示。

 (1)新建Qt Widgets Application(详见1.3.1节),项目名称为“UserInfo”,基类选择“QDialog”,取消“创建界面”复选框的选中状态。

(2)打开“dialog.h”头文件,在头文件中声明对话框中的各个控件。添加如下代码。 添加如下头文件:

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QTextEdit>
#include <QGridLayout>
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;
};

#endif // DIALOG_H

(3)打开“dialog.cpp”文件,在类Dialog的构造函数中添加如下代码。

#include "dialog.h"
#include<QLabel>
#include<QLineEdit>
#include<QComboBox>
#include<QPushButton>
#include<QFrame>
#include<QGridLayout>
#include<QPixmap>
#include<QHBoxLayout>
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);//(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;
    QPixmap icon("312.png");
    HeadIconLabel->setPixmap(icon);
    HeadIconLabel->resize(icon.width(),icon.height());
    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->setMargin(10);
    RightLayout->addLayout(TopRightLayout);
    RightLayout->addWidget(IntroductionLabel);
    RightLayout->addWidget(IntroductionTextEdit);
    /*--------------------- 底部 --------------------*/
    OkBtn =new QPushButton(tr("确定"));
    CancelBtn =new QPushButton(tr("取消"));
    //完成下方两个按钮的布局
    ButtomLayout =new QHBoxLayout();
    ButtomLayout->addStretch();							//(d)
    ButtomLayout->addWidget(OkBtn);
    ButtomLayout->addWidget(CancelBtn);
    /*---------------------------------------------*/
    QGridLayout *mainLayout =new QGridLayout(this);     //(e)
    mainLayout->setMargin(15);					//设定对话框的边距为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);	//(f)
}

Dialog::~Dialog()
{

}

其中,

(a) OtherLabel->setFrameStyle(QFrame::Panel|QFrame::Sunken):设置控件的风格。setFrameStyle()是QFrame的方法,参数以或(|)的方式设定控件的面板风格,由形状(QFrame::Shape)和阴影(QFrame::shadow)两项配合设定。其中,形状包括六种,分别是NoFrame、Panel、Box、HLine、VLine及WinPanel;阴影包括三种,分别是Plain、Raised和Sunken。

(b) LeftLayout =new QGridLayout():左部布局,由于此布局管理器不是主布局管理器,所以不用指定父窗口。

(c) LeftLayout->setColumnStretch(0,1)、LeftLayout->setColumnStretch(1,3):设定两列分别占用空间的比例,本例设定为1:3。即使对话框框架大小改变了,两列之间的宽度比依然保持不变。

(d) ButtomLayout->addStretch():在按钮之前插入一个占位符,使两个按钮能够靠右对齐,并且在整个对话框的大小发生改变时,保证按钮的大小不发生变化。

(e) QGridLayout *mainLayout =new QGridLayout(this):实现主布局,指定父窗口this,也可调用this->setLayout(mainLayout)实现。

(f) mainLayout->setSizeConstraint(QLayout::SetFixedSize):设定最优化显示,并且使用户无法改变对话框的大小。所谓最优化显示,即控件都按其sizeHint()的大小显示。

五、【综合实例】(CH305):修改用户资料

通过实现修改用户资料功能这一综合实例,介绍如何使用布局方法实现一个复杂的窗口布局,如何使用分割窗口,以及如何使用堆栈窗体。实例效果如图3.9所示。

(a)“基本信息”页面

 

 (b)“联系方式”页面

 (c)“详细资料”页面

最外层是一个分割窗体QSplitter,分割窗体的左侧是一个QListWidget,右侧是一个QVBoxLayout布局,此布局包括一个堆栈窗体QStackWidget和一个按钮布局。在此堆栈窗体QStackWidget中包含三个页面,每个页面采用基本布局方式进行布局管理,如图3.10所示。

 1.导航页实现

(1)新建Qt Widgets Application(详见1.3.1节),项目名称为“Example”,基类选择“QDialog”,类名命名为“Content”,取消“创建界面”复选框的选中状态。

(2)在如图3.10所示的布局框架中,框架左侧的页面(导航页)就用Content类来实现。 打开“content.h”头文件,修改Content类继承自QFrame类,类声明中包含自定义的三个页面类对象、两个按钮对象及一个堆栈窗体对象,添加如下代码:

#ifndef CONTENT_H
#define CONTENT_H

#include <QDialog>
#include <QStackedWidget>
#include <QPushButton>
#include "baseinfo.h"
#include "contact.h"
#include "detail.h"
class Content : public QFrame
{
    Q_OBJECT

public:
    Content(QWidget *parent = 0);
    ~Content();
    QStackedWidget *stack;
    QPushButton *AmendBtn;
    QPushButton *CloseBtn;
    BaseInfo  *baseInfo;
    Contact *contact;
    Detail *detail;
};

#endif // CONTENT_H

(3)打开“Content.cpp”文件,添加如下代码:

#include "content.h"

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

Content::~Content()
{

}

其中,

(a) baseInfo =new BaseInfo()至stack->addWidget(detail):这段代码是在堆栈窗口中顺序插入“基本信息”“联系方式”“详细资料”三个页面。其中,BaseInfo类的具体完成代码参照3.4节,后两个与此类似。

(b) AmendBtn =new QPushButton(tr("修改"))至BtnLayout->addWidget(CloseBtn):这段代码用于创建两个按钮,并利用QHBoxLayout对其进行布局。

2.“修改用户基本信息”设计

(1)添加该工程的提供主要显示用户基本信息界面的函数所在的文件,在“Example”项目名上单击鼠标右键,在弹出的快捷菜单中选择“添加新文件...”选项,在弹出的如图3.11所示的对话框中选择“C++ Class”选项,单击“Choose...”按钮。

(2)弹出如图3.12所示的对话框,在“Base class”下拉列表框中选择基类名为“QWidget”,在“Class name”的文本框中输入类的名称“BaseInfo”。单击“下一步”按钮,单击“完成”按钮,添加“baseinfo.h”头文件和“baseinfo.cpp”源文件。

(3)打开“baseinfo.h”头文件,添加的代码(具体解释请参照3.4节)。

#ifndef BASEINFO_H
#define BASEINFO_H

#include <QWidget>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QTextEdit>
#include <QGridLayout>
#include <QPushButton>
class BaseInfo : public QWidget
{
    Q_OBJECT
public:
    explicit BaseInfo(QWidget *parent = 0);

signals:

public slots:
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;
};

#endif // BASEINFO_H

(4)打开“baseinfo.cpp”文件,添加如下代码(具体解释请参照3.4节)。

#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("备注:"));
    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);
    /*************************************/
    QGridLayout *mainLayout =new QGridLayout(this);
    mainLayout->setMargin(15);
    mainLayout->setSpacing(10);
    mainLayout->addLayout(LeftLayout,0,0);
    mainLayout->addLayout(RightLayout,0,1);
    mainLayout->setSizeConstraint(QLayout::SetFixedSize);
}

3.“显示用户的联系方式”设计

(1)添加该工程的提供主要显示用户的联系方式界面的函数所在的文件,在“Example”项目名上单击鼠标右键,在弹出的快捷菜单中选择“添加新文件...”选项,在弹出的对话框中选择“C++ Class”选项。单击“Choose...”按钮,在弹出的对话框的“Base class”的下拉列表框中选择基类名为“QWidget”,在“Class name”文本框中输入类的名称“Contact”。

(2)单击“下一步”按钮,单击“完成”按钮,添加“contact.h”头文件和“contact.cpp”源文件。

(3)打开“contact.h”头文件,添加如下代码。

#ifndef CONTACT_H
#define CONTACT_H

#include <QWidget>
#include <QLabel>
#include <QGridLayout>
#include <QLineEdit>
#include <QCheckBox>
class Contact : public QWidget
{
    Q_OBJECT
public:
    explicit Contact(QWidget *parent = 0);

signals:

public slots:
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_H

(4)打开“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);
}

4.“显示用户的详细资料”设计

(1)添加主要显示用户的详细资料界面的函数所在的文件,在“Example”项目名上单击鼠标右键,在弹出的快捷菜单中选择“添加新文件...”选项,在弹出的对话框中选择“C++ Class”选项,单击“Choose...”按钮,在弹出的对话框的“Base class”的下拉列表框中选择基类名为“QWidget”,在“Class name”后面的文本框中输入类的名称“Detail”。

(2)单击“下一步”按钮,单击“完成”按钮,添加“detail.h”头文件和“detail.cpp”源文件。

(3)打开“detail.h”头文件,添加如下代码。

#ifndef DETAIL_H
#define DETAIL_H

#include <QWidget>
#include <QLabel>
#include <QComboBox>
#include <QLineEdit>
#include <QTextEdit>
#include <QGridLayout>
class Detail : public QWidget
{
    Q_OBJECT
public:
    explicit Detail(QWidget *parent = 0);

signals:

public slots:
private:
    QLabel *NationalLabel;
    QComboBox *NationalComboBox;
    QLabel *ProvinceLabel;
    QComboBox *ProvinceComboBox;
    QLabel *CityLabel;
    QLineEdit *CityLineEdit;
    QLabel *IntroductLabel;
    QTextEdit *IntroductTextEdit;
    QGridLayout *mainLayout;
};

#endif // DETAIL_H

(4)打开“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);
}

下面编写该工程的入口函数(所在的文件为main.cpp)。打开“main.cpp”文件,编写以下代码。

#include "content.h"
#include <QApplication>
#include <QTextCodec>
#include <QSplitter>
#include <QListWidget>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QFont font("AR PL KaitiM GB",12);	//设置整个程序采用的字体与字号
    a.setFont(font);
    //新建一个水平分割窗对象,作为主布局框
    QSplitter *splitterMain =new QSplitter(Qt::Horizontal,0);
    splitterMain->setOpaqueResize(true);
    QListWidget *list =new QListWidget(splitterMain);	//(a)
    list->insertItem(0,QObject::tr("基本信息"));
    list->insertItem(1,QObject::tr("联系方式"));
    list->insertItem(2,QObject::tr("详细资料"));
    Content *content =new Content(splitterMain);		//(b)
    QObject::connect(list,SIGNAL(currentRowChanged(int)),content->stack,
    SLOT(setCurrentIndex(int)));						//(c)
    //设置主布局框即水平分割窗的标题
    splitterMain->setWindowTitle(QObject::tr("修改用户资料"));
    //设置主布局框即水平分割窗的最小尺寸
    splitterMain->setMinimumSize(splitterMain->minimumSize());
    //设置主布局框即水平分割窗的最大尺寸
    splitterMain->setMaximumSize(splitterMain->maximumSize());
    splitterMain->show();	//显示主布局框,其上面的控件一同显示

    //Content w;
    //w.show();

    return a.exec();
}

其中,

(a) QListWidget *list =new QListWidget(splitterMain):在新建的水平分割窗的左侧窗口中插入一个QListWidget作为条目选择框,并在此依次插入“基本信息”“联系方式”“详细资料”条目。

(b) Content *content =new Content(splitterMain):在新建的水平分割窗的右侧窗口中插入Content类对象。

(c) QObject::connect(list,SIGNAL(currentRowChanged(int)),content->stack,SLOT(setCurrentIndex (int))):连接列表框的currentRowChanged()信号与堆栈窗口的setCurrentIndex()槽函数。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt5开发及实例 第三版》是一本关于Qt5框架开发的书籍。本书按照学习路径将Qt5的基本概念、GUI设计、数据库操作、网络编程等内容进行了详细讲解,并给出了大量的实例代码供读者学习和实践。 在第三版,作者对Qt5的各个方面进行了更新和改进。首先,书详细介绍了Qt5的安装和配置,让读者能够很容易地搭建开发环境。其次,本书对Qt5的GUI设计进行了深入的探讨,包括窗口、对话框、布局管理等内容,并且给出了丰富的示例代码,帮助读者理解和掌握相关知识。 此外,本书还介绍了Qt5涉及到的一些常用的工具类和模块,例如Qt Designer、Qt Creator、Qt Quick等,它们在Qt5开发扮演着重要的角色。作者对这些工具进行了详细的讲解,并且给出了相关的示例代码,帮助读者更好地使用它们。 在第三版的实例代码,作者给出了许多实际应用场景的示例,例如一个简单的文本编辑器、一个数据库管理系统、一个网络聊天程序等等。这些实例代码不仅体现了Qt5的各种功能和特性,还能帮助读者将理论知识应用到实际项目,提高开发效率和质量。 总之,《Qt5开发及实例 第三版》是一本非常实用的书籍,适合有一定编程基础的读者学习和使用。无论是想学习Qt5框架的初学者,还是已经有一定经验的开发者,都能够从获得一定的收获,并且能够将所学知识应用到实际项目去。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值