QT布局之表单布局QFormLayout

下面是一个表单布局,经典的表单布局分为2列

第一列是标题列,通常是QLabel,也可以是其他控件

第二列就是内容列,为具体的控件,也可以是个布局(比如水平布局,垂直布局...),布局里面套着多个控件

添加行

有多个重载形式

//参数1:标题列的文本
//参数2:内容列的控件
void QFormLayout::addRow(const QString &labelText, QWidget *field)
//参数1:标题列的控件
//参数2:内容列的控件
void QFormLayout::addRow(QWidget *label, QWidget *field)
//参数1:标题列的文本
//参数2:内容列是一个布局
void QFormLayout::addRow(const QString &labelText, QLayout *field)

 比如下图,内容列是一个布局,布局里面有2个按钮

//参数1:一个控件或者布局
//没有指定标题列内容,添加的控件会充满整行
void QFormLayout::addRow(QWidget *widget)
void QFormLayout::addRow(QLayout *layout)

上面这种重载,没有指定标题列内容,添加的控件会充满整行,如下:

 

插入行

和添加行的重载差不多,需要多传一个参数,指定插在第几行

//在指定的row行插入
void QFormLayout::insertRow(int row, const QString &labelText, QWidget *field)
void QFormLayout::insertRow(int row, const QString &labelText, QLayout *field)

隐藏某一行

根据行号,隐藏这一行6.4版本开始支持

[since 6.4] void QFormLayout::setRowVisible(int row, bool on)

替换布局里面的某个Widget

[virtual] QLayoutItem *QLayout::replaceWidget(QWidget *from, QWidget *to, Qt::FindChildOptions options = Qt::FindChildrenRecursively)

替换之后要将原来的那个hide(),否在会堆叠在一起 

设置行的换行策略

QFormLayout::RowWrapPolicy rowWrapPolicy() const
void setRowWrapPolicy(QFormLayout::RowWrapPolicy policy)

policy有三种取值

  • QFormLayout::DontWrapRows,每一行左右排列,,默认就是这种

  • QFormLayout::WrapLongRows,根据情况,比较长的行会被换行

  • QFormLayout::WrapAllRows,每一行上下显示

获取行数

int QFormLayout::rowCount() const

根据行和列获取所在的item

QLayoutItem *QFormLayout::itemAt(int row, QFormLayout::ItemRole role) const

返回值:获取到的item,可以通过其widget()方法或者layout()方法获取item内部真实的项

参数1:row,行号

参数2:role,是一个枚举

有三种取值

  • QFormLayout::LabelRole,指的是标题列
  • QFormLayout::FieldRole,指的是内容列
  • QFormLayout::SpanningRole,指的的是横跨2列的

 

比如itemAt(1,QFormLayout::FieldRole),表示获取第2行内容列的那一项

举例:

点击save按钮,遍历表单布局里的内容,校验表单布局里面的edit是否为空,为空则弹出错误提示,且将焦点移到为空的edit上

点击清除按钮,遍历表单布局里的内容,将edit的内容清空

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QFormLayout>
#include<QPushButton>
#include<QLineEdit>
#include<QLabel>
#include<QHBoxLayout>
#include<QMessageBox>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr): QWidget(parent)
    {
        resize(500,400);
        QFormLayout* f_layout=new QFormLayout(this);
        f_layout->setVerticalSpacing(10);

        //添加一行
        QLineEdit* name=new QLineEdit(this);
        f_layout->addRow("名称",name);

        QLineEdit* email=new QLineEdit(this);
        f_layout->addRow("邮箱",email);

        //插入一行
        QLineEdit* age=new QLineEdit(this);
        //插到第二行
        f_layout->insertRow(1,"年龄",age);



        //添加子布局
        QPushButton* save=new QPushButton("save",this);
        QPushButton* clr=new QPushButton("clear",this);
        QHBoxLayout* h_box=new QHBoxLayout();
        h_box->addWidget(save);
        h_box->addWidget(clr);
        f_layout->addRow(h_box);//不指定标题,则会充满整行


        //绑定按钮的槽函数
        //清除按钮:清空每一个输入框里的内容
        connect(clr,&QPushButton::clicked,this,[=](){
            //获取布局
            QFormLayout* lay=(QFormLayout*)this->layout();

            //遍历表单布局中的每一项
            for(int i=0;i<lay->rowCount();++i)
            {
                //获取第i行指定列的元素,比如标题列、内容列、跨越了标题列和内容列

                QLayoutItem* item=lay->itemAt(i,QFormLayout::FieldRole);
                if(item==nullptr)//有可能为空,为什么可能为空,因为当前项有可能是其他的role
                {
                    continue;
                }

                QLineEdit* e=(QLineEdit*)item->widget();
                if(e==nullptr)//有可能为空,为什么可能为空,因为有可能是个布局
                {
                    continue;
                }

                //获取真正的类型 是QLineEdit则清空
                QString name=e->metaObject()->className();
                if(name=="QLineEdit")
                {
                    e->setText("");
                }
            }


        });
        connect(save,&QPushButton::clicked,this,[=](){
            //获取布局
            QFormLayout* lay=(QFormLayout*)this->layout();

            QString err="";

            //遍历表单布局中的每一项
            for(int i=0;i<lay->rowCount();++i)
            {
                //获取标题,为了组装错误提示
                QLayoutItem* title_item=lay->itemAt(i,QFormLayout::LabelRole);
                if(title_item==nullptr)//有可能为空,为什么可能为空,因为当前项有可能是其他的role
                {
                    continue;
                }
                QLabel* title_lbl=(QLabel*)title_item->widget();
                if(title_lbl==nullptr)//有可能为空,为什么可能为空,因为有可能是个布局
                {
                    continue;
                }
                QString title=title_lbl->text();


                //获取第i行指定列的元素,比如标题列、内容列、跨越了标题列和内容列
                QLayoutItem* item=lay->itemAt(i,QFormLayout::FieldRole);
                if(item==nullptr)//有可能为空,为什么可能为空,因为当前项有可能是其他的role
                {
                    continue;
                }
                //转为实际类型
                QLineEdit* e=(QLineEdit*)item->widget();
                if(e==nullptr)//有可能为空,为什么可能为空,因为有可能是个布局
                {
                    continue;
                }
                QString name=e->metaObject()->className();
                if(name=="QLineEdit")
                {
                    //去掉内容里的空格后还是空的
                    if(e->text().trimmed()=="")
                    {
                        e->setFocus();
                        err+=title;
                        err+=" is empty!\n";
                    }
                }
            }

            if(!err.isEmpty())
            {
                QMessageBox::information(this,"提示",err);
            }
        });

    }
    ~Widget()=default;

};
#endif // WIDGET_H

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值