Qt使用代码放置控件并布局

        上一章中我们从头一步一步地新建项目并运行了窗口,本章就正式踏入Qt界面编程之路。在本章节,我们先用代码编写界面,进行简单的控件放置,然后用代码进行布局;之后使用Qt Designer进行控件放置和界面布局,这使得复杂界面的设计变得简单起来。

1.主窗口的组成

        对于界面设计来说,Qt的窗口相当于一张画布,设计人员可以在这张画布上任意的绘画,我们按照“国际惯例”,先实现一个“Hello World”字符显示作为入门demo。

        在上一章中,新建的空白项目直接运行的窗口如下:

5efcf96962a848aa84b98c8607d8eadd.png

        这个窗口看似空空如也,实则暗藏玄机,窗口上有几个默认的控件,见下图:

10a2b2645eb548b091d9ad5309dae7cd.png

         从上图标示可以看出,窗口的上部分是菜单栏,下部分是状态栏,中间那个大区域是中心控件。菜单栏是放置菜单的地方;状态栏可以显示如一些操作动作或信息;中心控件是我们所谓的“画布”,用来放置控件、布局的地方。

2使用代码放置控件

        我们暂时不去管菜单栏和状态栏,这个我们之后再慢慢玩。中心控件区域是我们放置控件的地方,我们用代码编写在中心控件区域放置一个“Hello World”字符。

        在编写代码之前,我们先看下Qt自动生成的mainwindow.cpp文件中的内容:

#include "mainwindow.h"
#include "ui_mainwindow.h"

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

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

        该文件默认有三个部分,分别是头文件包含、构造函数、析构函数,我们在构造函数中放置一个用于显示字符串的标签,该控件是QLabel(使用之前先包含QLabel的头文件),并将该标签的文本设置为“Hello World”,代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>  // 包含QLabel的头文件

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

    /* 实例一个QLabel对象指针label,
     * 并将中心控件的指针(this->centralWidget()返回中心控件的指针)传入QLabel的构造函数,
     * 表示QLabel的父类是中心控件,即QLabel会显示在中心控件区域 */
    QLabel *label = new QLabel(this->centralWidget());
    // 设置标签文本
    label->setText("Hello World");
}

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

        上述增加的代码给出了注释,运行程序,显示的窗口如下:0413ba4f415e400fb538d5768829fa24.png

         当看到窗口中出现了“HelloWorld”字符串,恭喜你,实现了Qt第一个界面程序。

        这里必须指明一点,就是Qt编程中实例的控件一般情况下都是使用指针变量,这样控件不会随着函数的生命周期结束而结束,如果你在构造函数中这样声明QLabel变量:

QLabel label(this->centralWidget());

label.setText("Hello World");

        那么你在运行后会发现窗口还是空空如也,没有显示你想要的字符串。因为label这个变量是构造函数的局部变量,当构造函数运行完毕后,label变量也随之释放。使用指针变量,只要不是人为地去释放指针,则指针变量会一直存在。

        虽然实现了“Hello World”字符串在窗口中显示,但是你可能会想,如何将这个字符串放置在窗口的其它位置。在研究字符串放置的位置之前,我们得先知道窗口的坐标是如何规定的,下面我们看下Qt窗口的坐标系统是什么样的,见下图:

8fa41d44bed3426a8f91c621e8b49a79.png

         从图中可以看出,Qt窗口的左上角坐标是(0,0),向右走是X轴正方向,向下走是Y轴正方向。那么,这个窗口究竟多大的呢,我们可以使用函数获取,再将它们显示在标签上,见如下代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>  // 包含QLabel的头文件

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

    // 获取窗口宽度
    int width = this->width();
    // 获取窗口高度
    int height = this->height();

    QLabel *label = new QLabel(this->centralWidget());
    // 显示出窗口宽度和高度
    label->setText(QString::number(width) + " " + QString::number(height));
}

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

        以上代码中,先通过this->width()和this->height()两个函数获取窗口的宽度和高度,然后显示在标签中。其中QString::number(width)和QString::number(height)是将数值转换成字符串,因为setText()函数只能传入字符串变量QString。运行程序,显示的窗口如下:8dadb24a3eff42b48e7e348838d8d99e.png

        从窗口中显示的字符串可以看到,该窗口的宽度是800像素点,高度是600像素点。接下来我们将“Hello World”的标签换个位置放置,代码修改如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>  // 包含QLabel的头文件

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

    QLabel *label = new QLabel(this->centralWidget());
    // 设置文本
    label->setText("Hello World");
    // 设置标签的位置和大小
    label->setGeometry(0, 300, 80, 30);
}

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

        这里使用了QLabel的函数setGeometry(int ax, int ay, int aw, int ah),该函数有四个参数,依次是控件要设置的x轴坐标、y轴坐标、控件的宽度、控件的高度,这里我们设置“Hello World”标签的位置为(0,300),标签的宽度为80、高度为30。这里要注意的是,Qt中所有的控件的起始坐标都是控件的左上角,放置的位置也是以控件的(0,0)坐标为参考点,比如说这里把“Hello World”标签放置在窗口的(0,300)位置,准确地说,是把标签的(0,0)坐标点放置在窗口的(0,300)位置 。运行程序,显示的窗口如下:6f32ff4fb67042ec9c95552b05227339.png

         “Hello World”字符串放置在了我们设置的地方,程序运行成功!

3使用代码进行界面布局

        我们在界面上放置3个控件,分别是标签控件QLabel、行输入控件QLineEdit和按钮控件QPushButton,代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>       // 包含QLabel的头文件
#include <QLineEdit>    // 包含QLineEdit的头文件
#include <QPushButton>  // 包含QPushButton的头文件

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

    // 标签控件
    QLabel *label = new QLabel(this->centralWidget());
    // 设置标签文本
    label->setText("Hello World");
    // 设置位置和大小
    label->setGeometry(0, 0, 80, 25);

    // 行输入控件
    QLineEdit *lineEdit = new QLineEdit(this->centralWidget());
    // 设置位置和大小
    lineEdit->setGeometry(100, 0, 80, 25);

    // 按钮控件
    QPushButton *pushButton = new QPushButton(this->centralWidget());
    // 设置按钮文本
    pushButton->setText("我是按钮");
    // 设置位置和大小
    pushButton->setGeometry(200, 0, 80, 25);
}

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

        运行程序,显示的窗口如下:

b0e274c21e4645e6b997f58073889975.png

         可以看到,三个控件按我们给定的位置和大小在窗口中水平排列,因为我们给定的是控件的绝对位置和绝对大小,所以控件的位置和大小不会随着窗口的大小变化而自动变化,有时会出现窗口显示不全控件的情况,如下图所示:

d9f2b85feec64b14832ddad40734c854.png

         为了让控件的位置和大小随着窗口大小的改变而自动变化,使控件能够自适应窗口的变化,我们使用Qt的水平布局控件QHBoxLayout。QHBoxLayout是水平布局控件,放置在QHBoxLayout里的控件会自动水平分布,并且随着QHBoxLayout的大小变化而自动变化,代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>       // 包含QLabel的头文件
#include <QLineEdit>    // 包含QLineEdit的头文件
#include <QPushButton>  // 包含QPushButton的头文件
#include <QHBoxLayout>  // 包含QHBoxLayout的头文件

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

    // 标签控件
    QLabel *label = new QLabel;
    // 设置标签文本
    label->setText("Hello World");

    // 行输入控件
    QLineEdit *lineEdit = new QLineEdit;

    // 按钮控件
    QPushButton *pushButton = new QPushButton;
    // 设置按钮文本
    pushButton->setText("我是按钮");

    // 水平布局控件
    QHBoxLayout *hBoxLayout = new QHBoxLayout(this->centralWidget());
    hBoxLayout->addWidget(label);
    hBoxLayout->addWidget(lineEdit);
    hBoxLayout->addWidget(pushButton);
}

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

        运行程序,显示的窗口如下:c042bd9393594cbb8f7643ef06ed810f.png

         可以看出,三个控件水平分布在窗口中,将窗口的横坐标填充满,当我们缩小或放大窗口时,控件的大小和位置会跟随着窗口的大小变化而变化,起到控件自适应窗口大小的效果。

        当然,有水平布局控件就有垂直布局控件,我们将上面的QHBoxLayout改为QVBoxLayout看看什么效果,代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>       // 包含QLabel的头文件
#include <QLineEdit>    // 包含QLineEdit的头文件
#include <QPushButton>  // 包含QPushButton的头文件
#include <QVBoxLayout>  // 包含QVBoxLayout的头文件

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

    // 标签控件
    QLabel *label = new QLabel;
    // 设置标签文本
    label->setText("Hello World");

    // 行输入控件
    QLineEdit *lineEdit = new QLineEdit;

    // 按钮控件
    QPushButton *pushButton = new QPushButton;
    // 设置按钮文本
    pushButton->setText("我是按钮");

    // 垂直布局控件
    QVBoxLayout *vBoxLayout = new QVBoxLayout(this->centralWidget());
    vBoxLayout->addWidget(label);
    vBoxLayout->addWidget(lineEdit);
    vBoxLayout->addWidget(pushButton);
}

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

        运行程序,显示的窗口如下:

2b3c98b6c6284625a467f95855086890.png

         可以看出,三个控件按垂直方向分布,当缩小窗口后,三个控件的大小和位置会随窗口的改变而改变。比如,窗口缩小后,效果如下图:

7c092781fa034cf19652a4bba7003493.png

         窗口是不是变得紧凑且美观了一些。

        QHBoxLayout和QVBoxLayout可以相互嵌套使用,除了这两个布局控件,Qt还有网格布局控件QGridLayout和表单布局控件QFormLayout,大家可以自行了解,在需要的时候使用。

4总结

        在这一章中,我们使用代码放置了几个控件,并使用了QHBoxLayout和QVBoxLayout布局控件对其进行了水平布局和垂直布局。这一章通过编写代码放置控件并布局,只是让我们初步了解Qt的界面编程,对于复杂点的界面设计,我推荐大家使用Qt自带的界面设计软件Qt Designer,使用它可以大大简化界面设计的工作量,并且设计逻辑清晰易于维护,界面直观,所见即所得。但如果涉及到控件大小和位置的动态修改,还是得使用代码直接编程。

  • 12
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt的网格布局(QGridLayout)是一种方便的方式来排列控件。它将控件放置在一个二维的网格中,类似于表格布局。 下面是一个简单的示例,展示如何使用网格布局来排版控件: ```cpp #include <QtWidgets> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 创建一个主窗口 QWidget window; window.setWindowTitle("Grid Layout Example"); // 创建一个网格布局 QGridLayout *layout = new QGridLayout(&window); // 创建一些控件 QLabel *label1 = new QLabel("Label 1"); QLabel *label2 = new QLabel("Label 2"); QPushButton *button1 = new QPushButton("Button 1"); QPushButton *button2 = new QPushButton("Button 2"); // 将控件添加到网格布局中 layout->addWidget(label1, 0, 0); // 在第一行、第一列 layout->addWidget(label2, 0, 1); // 在第一行、第二列 layout->addWidget(button1, 1, 0); // 在第二行、第一列 layout->addWidget(button2, 1, 1); // 在第二行、第二列 // 设置布局边距和控件间距 layout->setContentsMargins(10, 10, 10, 10); layout->setSpacing(10); // 显示主窗口 window.show(); return app.exec(); } ``` 在这个示例中,我们创建了一个主窗口,并在其中创建了一个网格布局。然后,我们创建了两个标签和两个按钮,并将它们添加到网格布局中的不同位置。最后,我们设置了布局的边距和控件间距,并显示了主窗口。 当运行这个示例时,你会看到标签和按钮按照网格布局的方式进行排列。 希望这个示例对你有所帮助!如果你还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值