简介

Qt 中的布局有三种方式,水平布局,垂直布局,栅格布局。

通过ui设置布局

我们先创建一个窗口应用程序,程序名叫layout,基类选择QMainWindow。但我们不使用这个mainwindow,我们创建一个Qt应用程序类Login,Qt会为我们自动生成login.ui文件。我们进入ui文件编辑,添加一个label,提示改为用户: , 在后边添加一个lineedit控件,按住ctrl鼠标依次点击这两个控件选中后,再点击工具栏的水平布局按钮就可以看到用户label和输入框处于同一水平线了。但是输入框会被拉长,而且label和输入框占满了整个水平空间。这时我们可以通过拖动左侧控件列表中的Horizonal Spacer,将其放入用户标签的左侧,再拖动一个Horizonal Spacer将其放在输入框的右侧,就可以看到用户标签和输入框被挤在中间了,并且两侧留有空间了。Spacer可以设置几种模式,包括fixed,expanding, maximum, minimum等模式。 依次类推,我们在添加密码标签和输入框,以及登录和注册按钮,通过ui界面的控件调整布局。 https://cdn.llfc.club/1665043183045.jpg

通过代码设置布局

上面我们通过ui设置了布局,接下来我们通过代码设置布局,设置注册界面的布局 注册类的声明如下

#ifndef REGISTER_H
#define REGISTER_H

#include <QDialog>
#include <memory>
using namespace std;
class  Login;
namespace Ui {
class Register;
}

class Register : public QDialog
{
    Q_OBJECT

public:
    explicit Register(QWidget *parent = nullptr);
    ~Register();
    void set_login(const  weak_ptr<Login> &_login);
private:
    Ui::Register *ui;
    weak_ptr<Login> _login;
    QPushButton* _reg_btn;
public slots:
    void ShowLogin();
};

#endif // REGISTER_H

因为要实现登录和注册界面之间的切换,所以Register类包含了Login类的弱指针,Register类的具体实现如下

#include "register.h"
#include "ui_register.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QSpacerItem>

Register::Register(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Register)
{
    ui->setupUi(this);
    this->setMaximumSize(QSize(300,350));
    this->setMinimumSize(QSize(300,350));
    auto vbox_layout = new QVBoxLayout();

    auto verticalSpacer1 = new QSpacerItem(40,20, QSizePolicy::Minimum, QSizePolicy::Expanding);
    vbox_layout->addItem(verticalSpacer1);
    QSpacerItem *name_item1 = new QSpacerItem(40,20, QSizePolicy::Fixed, QSizePolicy::Minimum);
    QLabel * name_label = new QLabel();
    name_label->setText("邮箱:");
    QLineEdit * name_edit = new QLineEdit();
    auto name_layout = new QHBoxLayout();
    name_layout->addItem(name_item1);
    name_layout->addWidget(name_label);
    name_layout->addWidget(name_edit);
    QSpacerItem *name_item2 = new QSpacerItem(40,20, QSizePolicy::Fixed, QSizePolicy::Minimum);
    name_layout->addItem(name_item2);
    vbox_layout->addLayout(name_layout);

    QLabel * pwd_label = new QLabel();
    pwd_label->setText("密码:");
    QLineEdit * pwd_edit = new QLineEdit();

    auto verticalSpacer2 = new QSpacerItem(40,20, QSizePolicy::Maximum, QSizePolicy::Maximum);
    vbox_layout->addItem(verticalSpacer2);
    auto pwd_layout = new QHBoxLayout();

    QSpacerItem *pwd_item2 = new QSpacerItem(40,20, QSizePolicy::Fixed, QSizePolicy::Minimum);
    QSpacerItem *pwd_item1 = new QSpacerItem(40,20, QSizePolicy::Fixed, QSizePolicy::Minimum);
    pwd_layout->addItem(pwd_item1);
    pwd_layout->addWidget(pwd_label);
    pwd_layout->addWidget(pwd_edit);
    pwd_layout->addItem(pwd_item2);
    vbox_layout->addLayout(pwd_layout);

    auto verticalSpacer3 = new QSpacerItem(40,30, QSizePolicy::Fixed, QSizePolicy::Maximum);
    vbox_layout->addItem(verticalSpacer3);

    QSpacerItem* reg_btn_item1 = new QSpacerItem(150,20, QSizePolicy::Fixed, QSizePolicy::Minimum);
    _reg_btn = new QPushButton();
    _reg_btn->setText("注册");
    auto regbtn_layout = new QHBoxLayout();
    regbtn_layout->addItem(reg_btn_item1);
    regbtn_layout->addWidget(_reg_btn,5);
    QSpacerItem* reg_btn_item2 = new QSpacerItem(40,20, QSizePolicy::Fixed, QSizePolicy::Minimum);

    regbtn_layout->addItem(reg_btn_item2);
    vbox_layout->addLayout(regbtn_layout);

    auto verticalSpacer4 = new QSpacerItem(40,20, QSizePolicy::Fixed, QSizePolicy::Expanding);
    vbox_layout->addItem(verticalSpacer4);
    this->setLayout(vbox_layout);
}

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

void Register::set_login(const  weak_ptr<Login> &login){
    _login = login;
}

void Register::ShowLogin()
{

}

Register的构造函数中用代码的方式创建了一个垂直布局,垂直布局中增加了两个spacer,分别是verticalSpacer1和verticalSpacer4,以及三个水平布局pwd_layout,name_layout以及regbtn_layout,然后分别用代码的方式在三个布局中添加spacer和控件。 Login类的声明如下

#ifndef LOGIN_H
#define LOGIN_H

#include <QDialog>
#include <memory>
class Register;
using namespace std;
namespace Ui {
class Login;
}

class Login : public QDialog, public std::enable_shared_from_this<Login>
{
    Q_OBJECT

public:
    explicit Login(QWidget *parent = nullptr);
    ~Login();
    void initSignals();

private slots:
    void on_regBtn_clicked();

private:
    Ui::Login *ui;
    std::shared_ptr<Register> _register;
};

#endif // LOGIN_H

Login实现如下下

#include "ui_login.h"
#include <QBitmap>
#include <QPainter>
#include "register.h"

Login::Login(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Login)
{
    ui->setupUi(this);
}

void Login::initSignals(){
     _register = make_shared<Register>();
      //从本类转化为共享的智能指针给register类
     _register->set_login(shared_from_this());
}

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

void Login::on_regBtn_clicked()
{

    this->close();
    _register->show();
}

main函数的实现如下

#include "login.h"
#include <QApplication>
#include <memory>
using namespace  std;
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    std::shared_ptr<Login> w = make_shared<Login>();
    w->initSignals();
    w->show();

    return a.exec();
}

点击运行按钮,程序运行起来就可以从登录界面切换到注册界面了

总结

源码链接https://gitee.com/secondtonone1/qt-learning-notes

results matching ""

    No results matching ""