布局管理和样式表

目录

手动操作

相关功能解释:

Qt Designer或者QC中的Spacer控件及其属性

网格布局

代码操作

setFocusPolicy()


如果不进行布局,意味着界面上的东西都是写死的。

当我们进行布局操作之后,控件的位置、大小一般会根据窗口缩放来自动调整。

  • QHBoxLayout  水平布局,从左往右水平排列部件
  • QVBoxLayout  垂直布局,从上往下垂直排列部件
  • QGridLayout  网格布局,将部件放置在二维网格中。
  • QFormLayout  用于表单的特殊布局
  • QStackedLayout  栈布局,允许将多个部件放在同一个位置

1.学习 Qt 我们必须经历几个阶段 我们尽量去手写所有界面业务代码,需要一年,经过一年大量的手写,这个时候 Qt 大部分东西我们就非常熟悉了.

2.第二个阶段,我们逐渐去写一些有含金量的代码,比如写复杂控件,复杂的业务。手写界面,写久了熟练了它就是个体力活.

3.这个时候,我可以用界面布局设计器,去偷懒快速去写一些东西。

手动操作

没有布局的时候是这样的图标:


在这里框选要进行布局设置的控件,然后点上面的水平布局或者垂直布局(这里我选的是垂直布局)

并且在右侧的Filter筛选器里也会发生变化:

如果想取消布局,也可以鼠标右键选中它,在布局里选择分拆。

也可以点这个按钮进行分拆:

相关功能解释:

framelayout 是基于表单的布局。

基于网格的布局:

Qt Designer或者QC中的Spacer控件及其属性

在Qt Designer中,Spacer控件是一种非常常用的控件,它可以帮助我们在界面布局中实现空白区域的占位,Spacer控件在布局调整和设计过程中有着重要的作用,但在使用过程中也需要注意一些属性的设置。


Spacer控件的常用属性有sizeType、 sizeHintstretch以及geometrv等。


sizeType属性的值为QSizePolicy中定义的枚举类型Q之一,包括Fixed、Minimum、Maximum、Preferred、Expanding和MinimumExpanding。这些枚举类型代表了不同的大小约束关系,详细说明如下:
。Fixed: 固定大小
。Minimum: 最小大小。
。Maximum: 最大大小
。Preferred:首选大小。
。Expanding:可扩展大小
。MinimumExpanding: 最小可扩展大小


我们可以根据具体的需求选择相应的sizeType类型,来指定Spacer控件的大小约束关系。

QSizePolicy::Fixed - the QWidget::sizeHint() is the only acceptable alternative, so the widget can never grow or shrink (e.g. the vertical direction of a push button).
缺省大小(sizehint)是唯一可以接收的改变,因此定义这种类型部件不会发生任何改变。

QSizePolicy::Minimum - the sizeHint() is minimal, and sufficient. The widget can be expanded, but there is no advantage to it being larger (e.g. the horizontal direction of a push button).
缺省大小定义的部件最小大小,并且是充分的。部件允许扩展,但是并不倾向扩展。

QSizePolicy::Maximum - the sizeHint() is a maximum. The widget can be shrunk any amount without detriment if other widgets need the space (e.g. a separator line).
缺省大小定义的部件是最大的,假如其它部件需要空间并且不会破坏这个部件,那么该部件允许缩小。

QSizePolicy::Preferred - the sizeHint() is best, but the widget can be shrunk and still be useful. The widget can be expanded, but there is no advantage to it being larger than sizeHint() (the default QWidget policy).
缺省大小是最佳效果,部件允许扩展或缩小,但并倾向于扩展(缺省策略)。

QSizePolicy::Expanding - the sizeHint() is a sensible size, but the widget can be shrunk and still be useful. The widget can make use of extra space, so it should get as much space as possible (e.g. the horizontal direction of a slider).
缺省大小是合理的大小,但部件允许缩小并且可用。这个部件可以利用额外的空间,因此它将会得到尽可能多的空间。

QSizePolicy::MinimumExpanding - the sizeHint() is minimal, and sufficient. The widget can make use of extra space, so it should get as much space as possible (e.g. the horizontal direction of a slider).
缺省大小是部件最小大小,并且是足够的。这个部件允许使用额外空间,因此它将会得到尽可能多的空间。

QSizePolicy::Ignored - the sizeHint() is ignored. The widget will get as much space as possible.
缺省大小将会被忽略,这个部件会得到尽可能多的空间。


设置下界面大小:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
  
    setMaximumSize(8000,6000);
    setMinimumSize(400,300);
}

先用创建两个小label:

具体字体的设置因人而异。

再弄一个line edit:

复制一份,文字改成密码:

再来个pushbutton:

复制一份弄成注册:

再弄一些弹簧,弄一些水平和垂直布局:最终就是这样样子:

然后再来个checkbox:

复制下,再弄个自动登录。

自动勾选代码:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->checkBox_2->setChecked(true);
}

网格布局

注意设置行高等参数,不要太拥挤。

代码操作

一开始,各种new的时候,不知道这些初始化有什么意义,又是怎么个作用机制,自己还是回去查了查。

在本部分写代码的时候,先创建一个widget项目,然后在类的.cpp文件里的主构造函数里添加以下代码(数值的地方可以自己调):

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTime>
#include <QTimer>   //计时器
#include<QVBoxLayout>
#include<QHBoxLayout>
#include<QLabel>
#include<QPushButton>
#include<QLineEdit>
#include<QCheckBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{

    ui->setupUi(this);
    ui->pushButton_no->setText("hao");
    setWindowTitle("CSDN");
    resize(1420,700); //刚运行的时候整个窗口的大小
    setMinimumSize(400,300);
    setMaximumSize(1420,700);
    setupLayout();
}
/*
resize()
此属性保持Widget的大小,不包括任何窗口框架。

如果Widget在调整大小时可见,它会立即接收一个调整大小事件(resizeEvent())。如果Widget当前不可见,则保证在显示之前接收到事件。

如果大小超出minimumSize()和maximumSize()定义的范围,则会调整大小。

默认情况下,此属性包含一个值,该之依赖于用户平台和屏幕几何图形的。
 */

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

void Widget::on_pushButton_clicked()
{}

void Widget::setupLayout()
{
    QVBoxLayout* pLayout= new QVBoxLayout(this); //创建一个垂直布局
    pLayout->addWidget(loadupLayout());
    pLayout->addWidget(loadmidLayout());
    pLayout->addWidget(loaddownLayout());
    setLayout(pLayout);
}

QWidget* Widget::loadupLayout()
{
    //对Widget进行Layout
    QWidget* pWidget=new QWidget(this);
    QHBoxLayout* pLayout=new QHBoxLayout(pWidget);

    //可以设置内容的一些边界啥的格式
    pLayout->setContentsMargins(0,20,0,20);
    pLayout->setSpacing(20);

    QLabel* pNameLabel=new QLabel(tr("用户登录系统"),pWidget);
    pNameLabel->setToolTip("This is a 用户登录系统.");
    pNameLabel->setObjectName("name");
    pNameLabel->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Fixed);//水平和垂直方向的布局

    pLayout->addWidget(pNameLabel,0,Qt::AlignHCenter); //0表示延伸
    pWidget->setLayout(pLayout);

    return pWidget;
}
//tr()用于各种形式的字符串转换的

QWidget* Widget::loadmidLayout()
{
    //对Widget进行Layout
    QWidget* pWidget=new QWidget(this);
    QGridLayout* pLayout=new QGridLayout(pWidget);

    //可以设置内容的一些边界啥的格式
    pLayout->setContentsMargins(30,20,10,10);
    pLayout->setHorizontalSpacing(5);
    pLayout->setVerticalSpacing(20); //竖直方向给20

    QLabel* pUserNameLabel=new QLabel(tr("用户名"));
    m_pUsernameLE=new QLineEdit();
    m_pUsernameLE->setObjectName("user_name");
    m_pUsernameLE->setMaxLength(20);//支持的最长输入
    m_pUsernameLE->setText("");
    m_pUsernameLE->setFocusPolicy(Qt::StrongFocus);

    pLayout->addWidget(pUserNameLabel,0,0);
    pLayout->addWidget(m_pUsernameLE,0,1,1,3);

    QLabel* pPasswordLabel=new QLabel(tr("密码"));
    m_pPasswordLE=new QLineEdit();
    m_pPasswordLE->setObjectName("password");
    m_pPasswordLE->setMaxLength(16);//支持的最长输入
    m_pPasswordLE->setEchoMode(QLineEdit::Password);
    m_pPasswordLE->setText("");
    // m_pPasswordLE->setFocusPolicy(Qt::NoFocus);
    pLayout->addWidget(pPasswordLabel,1,0);
    pLayout->addWidget(m_pPasswordLE,1,1,1,3);

    m_pRememberCB= new QCheckBox(tr("记住密码"));
    m_pRememberCB->setChecked(true);
    m_pRememberCB->setFocusPolicy(Qt::NoFocus);

    m_pAutoLoginCB= new QCheckBox(tr("自动登录"));
    m_pAutoLoginCB->setChecked(true);
    pLayout->addWidget(m_pRememberCB,2,0,1,2);
    pLayout->addWidget(m_pAutoLoginCB,2,2,1,1);

    pWidget->setLayout(pLayout);

    return pWidget;
}

QWidget* Widget::loaddownLayout()
{
    QWidget* pWidget=new QWidget(this);
    QHBoxLayout* pLayout=new QHBoxLayout(pWidget); //水平布局
    //可以设置内容的一些边界啥的格式
    pLayout->setContentsMargins(0,0,0,10);

    QPushButton* pLoginButton=new QPushButton(tr("登录"));
    pLoginButton->setObjectName("login_btn");
    pLoginButton->setFocusPolicy(Qt::NoFocus);
    pLoginButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);

    QPushButton* pCancelButton=new QPushButton(tr("取消"));
    pCancelButton->setObjectName("cancel_btn");
    pCancelButton->setFocusPolicy(Qt::NoFocus);
    pCancelButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);

    pLayout->addWidget(pLoginButton);
    pLayout->addWidget(pCancelButton);

    pWidget->setLayout(pLayout);

    return pWidget;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include<QDialog>
#include<QCheckBox>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class QLineEdit;
class QCheckBox;

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_pushButton_clicked();

private:
    void setupLayout();
    QWidget* loadupLayout();
    QWidget* loadmidLayout();
    QWidget* loaddownLayout();

private:
    Ui::Widget *ui;
    QLineEdit *m_pUsernameLE; //命名的时候,m表示成员变量,p表示指针,LE是LineEdit的缩写
    QLineEdit *m_pPasswordLE;
    QCheckBox *m_pRememberCB;
    QCheckBox *m_pAutoLoginCB;
};
#endif // WIDGET_H

这里补充一点:

setFocusPolicy()

如果该小部件或具父级之一是活动窗口,则将键盘输入焦点设置为该小部件或其焦点代理),reason参数将传递到从此函数发送的任何焦点事件中,它用于说明是什么原因导致小部件获很焦点。如果窗口不活动,则在窗口变为活动状态时将焦点放在小部件上。

首先,将焦点改变事件发送到焦点小部件如果有),告诉它即将失去焦点,然后更改焦点,将焦点移出事件发送到前一个焦点项,并将焦点进入事件发送到新项目,告诉它刚刚接收到佛点。 (如果焦点输入和焦点输出小部件相同,则不会发生任何事情。)

注意:在嵌入式平台上,setFocus()不会使输入法打开输入面板。如果希望这样做,必须自己向小部件发送QEvent::RequestSoftwareInputPanel事件。

setFocus() 无论小部件的焦点策略如何,都会将焦点设置为小部件,但不清除任何键盘抢占( 参见grabKeyboard() )。

请注意,如果小部件被隐藏,则在显示之前它将不会接受焦点

警告: 如果在可能从focusOutEvent() 或 focusInEvent() 调用它自己的函数中调用 setFocus() ,可能会出现无限递归.

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懒回顾,半缘君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值