Qt 4开发实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.4 基本布局(QLayout)

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

图4.6 各种布局类及之间的关系

布局中常用的方法有addWidget()和addLayout ()。

addWidget()方法用来向布局中加入需布局的控件,addWidget()的函数原型如下:

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

addLayout ()方法用来向布局中加入需布局的子布局,addLayout ()的函数原型如下:

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

其中各个参数的作用如注释所示。

本小节将通过实现一个“用户基本资料修改”的功能来介绍如何使用基本布局管理,如QHBoxLayout类、QVBoxLayout类及QGridLayout类,效果如图4.7所示。本实例共用到4个布局管理器,分别是LeftLayout、RightLayout、BottomLayout和MainLayout,其布局框架如图4.8所示。见代码CH404。

图4.7 基本信息实例

图4.8 基本信息实例布局框架

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

(1) 创建一个工程,在创建过程中,创建过程中在“Qt4 Gui Application”界面中,选择“Base Class”下拉列表框中“QDialog”选项,取消“Gernerate form”复选框的选中状态。

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

    class Dialog : public QDialog
    {
        Q_OBJECT
    public:
        Dialog(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;                  //右上角部分
        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("37.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);
        }

其中:

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

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

LeftLayout->addWidget(UserNameLabel,0,0):向布局中加入需布局的控件。

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

TopRightLayout =new QHBoxLayout():完成右上侧的头像选择区的布局。

TopRightLayout->setSpacing(20):设定各个控件之间的间距为20。

RightLayout =new QVBoxLayout():完成右侧的布局。

ButtomLayout =new QHBoxLayout():完成下方两个按钮的布局。

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

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

mainLayout->setMargin(15):设定对话框的边距为15。

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

(4) 在dialog.cpp文件的开始部分加入以下头文件:

        #include<QLabel>
        #include<QLineEdit>
        #include<QComboBox>
        #include<QPushButton>
        #include<QFrame>
        #include<QGridLayout>
        #include<QPixmap>
        #include<QHBoxLayout>

(5) 打开main.cpp文件,在主函数中添加以下加黑代码:

        int main(int argc, char *argv[])
        {
            QApplication a(argc, argv);
            QTextCodec::setCodecForTr(QTextCodec::codecForLocale());  //在窗口中
    显示中文
            Dialog w;
            w.show();
            return a.exec();
        }

(6) 运行程序,显示效果如图4.7所示。

此实例是通过编写代码实现的,在这里还可以采用Qt Designer来进行布局。

注意:QHBoxLayout默认采取的是自左向右的方式顺序排列插入控件或子布局,也可通过调用setDirection()方法设定排列的顺序(如:layout-> setDirection(QBoxLayout::RightToLeft))。QVBoxLayout默认采取的是自上而下的方式顺序排列插入控件或子布局,也可通过调用setDirection()方法设定排列的顺序。