C++QT5跨平台界面编程原理--QLayout布局器、QObject子节点遍历

 

遍历所有QOjbect的子节点

遍历子节点-获取节 点对象名称
●QObjectList children()
●objectName()
转换子节点-获取节点对象类型
●QMetaObject * metaObject() 
●metaObject()-> className();
●qobject_cast<QCheckBox*> ( cb )


#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <iostream>
using namespace std;
static QObject *PrintName(QObject *obj)
{
    if(!obj)  //为空直接返回
    {
        return NULL;
    }
    cout<<obj->objectName().toStdString(); //转换成std格式字符串
    const QMetaObject *mobj = obj->metaObject(); //获取元数据
    QString cname = mobj->className();
    cout<<":"<<cname.toStdString()<<endl;//打印类的名字

    if(cname == "QPushButton")
    {
        QPushButton *pb = qobject_cast<QPushButton*>(obj);
        if(pb)
        {
             pb->setText(pb->text()+"class");
        }
    }
   //递归打印名字
    QObjectList cs = obj->children();
    if(cs.size()<=0)
    {
        return NULL;
    }
    for(int i =0;i < cs.size(); i++)
    {
        PrintName(cs[i]);
    }
}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    PrintName(this); 
    qDebug()<<"====================";
    QObjectList cs = this->children();//获取子节点
    for(int i = 0; i < cs.size(); i++)//遍历打印名字
    {
        qDebug()<<cs[i]->objectName();
    }

    QObjectList gs = ui->groupwidget->children();//同理
    for(int i = 0; i < gs.size();i++)
    {
        qDebug()<<gs[i]->objectName();
    }
}

Widget::~Widget()
{
    delete ui;
}

布局Layout

​
系统生成的代码:    
        //系统创建
        verticalLayoutWidget = new QWidget(Dialog);
        verticalLayoutWidget->setObjectName(QStringLiteral("verticalLayoutWidget"));
        verticalLayoutWidget->setGeometry(QRect(80, 90, 160, 83));
		//创建verticalLayout
        verticalLayout = new QVBoxLayout(verticalLayoutWidget);
        verticalLayout->setSpacing(6);
        verticalLayout->setContentsMargins(11, 11, 11, 11);
        verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
        verticalLayout->setContentsMargins(0, 0, 0, 0);
		
		//添加子节点
        pushButton = new QPushButton(verticalLayoutWidget);
        pushButton->setObjectName(QStringLiteral("pushButton"));
        verticalLayout->addWidget(pushButton);
		
		//忽略了...

​

QSizePolicy布局尺寸策略分析

sizeHint推荐尺寸

 ●QSize sizeHint()   推荐尺寸只能重载修改
●QSize size()不包含边框的窗口尺寸QSizePolicy::PolicyFlag

●GrowFlag必要时可超过推荐
●ExpandFlag尽可能的拓展
●ShrinkFlag必要时可小于推荐
●lgnoreFlag缺省大小被忽略

setSizePolicy
●(QSizePolic.:Policy horizontal, QSizePolicy::Policy vertical)

#include <QtCore/QCoreApplication>
#include <QWidget>
#include <QApplication>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	QWidget *win = new QWidget;
	win->resize(400, 400);
	
	//垂直布局  构造函数中传递widget
	QVBoxLayout *lay = new QVBoxLayout();

	//水平布局,布局器设置
	//QHBoxLayout *lay = new QHBoxLayout();
	win->setLayout(lay);
    
	//放置button
	QPushButton *but1 = new QPushButton("button1");
	lay->addWidget(but1);

    //添加button2
	QPushButton *but2 = new QPushButton("button2");
	lay->addWidget(but2);
	
    //添加button3
	QPushButton *but3 = new QPushButton("button3");
	lay->addWidget(but3);

	win->show();

	qDebug() << but1->sizeHint().width() << ":" << but1->sizeHint().height();	
	qDebug() << but1->width() << ":" << but1->height();

	return a.exec();
}

 

 改变边框的距离

	//边框距离,上下左右,受策略的影响
	lay->setContentsMargins(0, 0, 0, 0);

 

 

//1.水平 垂直 fixed使用推荐大小,如果拉伸了,就不会随窗口改变

      

//3.忽略推荐大小,尽量缩放

    //放置button
	QPushButton *but1 = new QPushButton("button1");
	lay->addWidget(but1);
	
	//下面的代码是策略测试

	//1.水平 垂直 fixed使用推荐大小,如果拉伸了,就不会随窗口改变
	but1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

	//2.尽量缩放,最小值是推荐值,最大没影响
	//but1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	
	//3.忽略推荐大小,尽量缩放
	//but1->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);


    //边框距离,上下左右,受策略的影响
	lay->setContentsMargins(0, 0, 0, 0);

	win->show();

	qDebug() << but1->sizeHint().width() << ":" << but1->sizeHint().height();	
	qDebug() << but1->width() << ":" << but1->height();

	return a.exec();
}

设置最大和最小尺寸

	but1->setMinimumSize(100, 50);
	but1->setMaximumSize(500, 100);

元素之间的间隔

//元素间距,也就是button1 2 3, 之间的间隔
lay->setSpacing(100);

//注意:使用的对象

QGridLayout

●void addWidget(QWidget *int row,int column,Qt::Alignment = Qt::Alignment());

AlignmentFlag对齐

#include "qgridlayout.h"
#include <QtWidgets/QApplication>
#include <QGridLayout>
#include <QPushButton>
int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	QWidget *win = new QWidget;
	QGridLayout *gl = new QGridLayout(win);
	
	QPushButton *but11 = new QPushButton("but11");
	gl->addWidget(but11, 0, 0);//button位置
	
	
	QPushButton *but12 = new QPushButton("but12");
	but12->setMinimumSize(100, 100);
	but12->setMaximumSize(500, 500);
	but12->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);//缩放策略
	gl->addWidget(but12, 0, 1);//button位置

	QPushButton *but13 = new QPushButton("but13");
	gl->addWidget(but13, 0, 2);//button位置
	QPushButton *but21 = new QPushButton("but21");
	gl->addWidget(but21, 1, 0);//button位置
	QPushButton *but23 = new QPushButton("but23");
	gl->addWidget(but23, 1, 2);//button位置

	//水平间距
	gl->setHorizontalSpacing(10);

	//垂直间距
	gl->setVerticalSpacing(10);


	win->show();

	///qgridlayout w;
	//w.show();
	return a.exec();
}

 

QFormLayout

 

/***
*public slots:
*	void Save();
*	void Clear();
***/
#include "QFormLayoutTest.h"
#include <QFormLayout>
#include <QLineEdit>
#include <QLabel>
#include <QPushButton>
QFormLayoutTest::QFormLayoutTest(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	QFormLayout *lay = new QFormLayout(this);
	QLineEdit *name = new QLineEdit();
	lay->addRow("&Name", name);  //标题

	QLineEdit *email = new QLineEdit();
	lay->addRow("&Email", email);

	QLineEdit *age = new QLineEdit();
	//插入到下标1的位置(0开始)
	lay->insertRow(1, "&Age",age);

	//显示出错信息
	QLabel *info = new QLabel();
	info->setText("input");
	//设置样式表
	info->setStyleSheet("color:red;");
	lay->insertRow(0, "", info);


	//添加Save 和Clear按钮
	QPushButton *save = new QPushButton("Save");
	QPushButton *clear = new QPushButton("Clear");

	//绑定信号槽,按钮点击事件
	QObject::connect(save, SIGNAL(clicked()), this, SLOT(Save()) );
	QObject::connect(clear, SIGNAL(clicked()), this, SLOT(Clear()));

	//添加一个平行布局
	QHBoxLayout *hlay = new QHBoxLayout();
	hlay->addWidget(save);
	hlay->addWidget(clear);
	lay->addRow(hlay);
}

void QFormLayoutTest::Save()
{
	//找到layout
	QFormLayout *lay = (QFormLayout*)this->layout();
	//显示错误信息label
	QLabel *label = (QLabel *)lay->itemAt(0, QFormLayout::FieldRole)->widget();
	//存放错误信息
	QString error = "";


	//遍历所有QLineEdit
	//遍历FormLayout的所有元素
	for (int i = 0; i < lay->rowCount(); i++)
	{
		//获取输入框
		QLayoutItem *item = lay->itemAt(i, QFormLayout::FieldRole);
		QLineEdit *e = (QLineEdit *)item->widget();
		if (!e) continue;

		//获取标题内容
		QLayoutItem *layItem = lay->itemAt(i, QFormLayout::LabelRole);
		if (!layItem) continue;
		QLabel *titleLabel = (QLabel *)layItem->widget();
		if (!titleLabel) continue;
		QString title = titleLabel->text();

		QString cname = e->metaObject()->className();
		if (cname == "QLineEdit")
		{
			if (e->text().trimmed() == "")
			{
				e->setFocus();
				error += title;
				error += " is empty!\n";
			}
		}
	}

	//设置错误显示
	label->setText(error);


}
void QFormLayoutTest::Clear()
{
	//找到layout
	QFormLayout *lay = (QFormLayout*)this->layout();
	//遍历所有QLineEdit
	//遍历FormLayout的所有元素
	for (int i = 0; i < lay->rowCount(); i++)
	{
		QLayoutItem *item = lay->itemAt(i, QFormLayout::FieldRole);
		QLineEdit *e = (QLineEdit *)item->widget();
		if (!e)
			continue;
		QString cname = e->metaObject()->className();
		if (cname == "QLineEdit")
		{
			e->setText("");
		}
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值