Featured image of post QT学习记录_03

QT学习记录_03

Qt Study Record Day3

第一个Qt小程序

本篇开始即进入QT的开发环节,本节主要内容有QT PushButton的添加、QT 窗口编辑操作、QT 对象树及QT中的坐标系。

QPushButton的创建

1. 查询assistant找到QPushButton的相关介绍

Picture 从图中说明我们可以看出,使用QPushButton需要包含头文件<QPushButton> ,同时需要widget模块的支持,由于我们使用的是QT5版本,因此QtCreator在项目构建时会自动包含widget模块(在使用QT4及以下版本时,需要在.pro文件中手动包含widget模块),而通过Inherits和Inherits By可得到QPushButton的继承路径:

1
QObject -> QWidget -> QAbstractButton -> QPushButton -> QCommandLinkButton

2. 通过QPushButton类创建按钮并进行一系列初始化设置

打开mywidget.cpp(构建项目时自定义的类的源文件)并添加以下代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "mywidget.h"
#include "ui_mywidget.h"
// 按钮控件的头文件
#include<QPushButton>

MyWidget::MyWidget(QWidget *parent): QWidget(parent), ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    // 使用无参构造函数重新构建一个QPushButton对象并使btn指向该对象
    QPushButton *btn = new QPushButton;
    // Question1: 添加的控件默认不会显示,需要调用show方法进行可视化,但为何生成的按钮并不依附于当前窗口内,而是重新打开一个窗口?
    // btn->show();
    // 将当前窗口设置为父窗口,使得生成的按钮依附在当前窗口内部,并依赖父窗口的show方法显示按钮
    btn->setParent(this);
    // 设置并显示含文本的按钮
    // Question2: 为什么我的中文显示乱码?
    btn->setText("第一个按钮");

    // 创建第二个按钮
    // Question3: 为什么不能使用以下方法创建按钮对象? 
    // QPushButton btn2("第二个按钮",this);
    QPushButton *btn2 = new QPushButton("第二个按钮", this);
    // 移动btn2按钮
    btn2->move(100, 100);
    // 重置窗口大小
    resize(600, 400);
    // 修改窗口标题
    setWindowTitle("这是一个窗口标题");
    // 设置固定的窗口大小(防止用户使用鼠标拉伸窗口)
    setFixedSize(600, 400);
    // 设置按钮大小
    btn2->resize(100, 50);
}

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

问题解答

  • Question1: 由于当前新建按钮是基于一个新的Qt控件类——QPushButton,因此在调用show方法时调用的是QPushButton的show方法进行显示,在运行时会分别生成主窗口和按钮窗口(回顾main.cpp的内容)。因此我们在构建按钮时需要使用setParent方法为其指定父窗口,使其能够依附于主窗口进行显示。
  • Question2: 中文显示乱码是因为文件的默认编码不是utf-8,需要在上方菜单栏中选择工具->选项->文本编辑器->Behavior找到文件编码,修改默认编码为utf-8后应用并确认即可
  • Question3: 在Qt中,对象模型一般基于动态内存分配而不是在栈上分配,即在创建对象时一般需要开发者在堆区为对象开辟内存空间,而不是将对象作为局部变量使用。这是因为局部变量存在于栈区,其生命周期在函数运行结束时截止,因此若使用QPushButton btn(“Text”, parent)的方法创建对象,那么该对象的生命周期仅仅是MiWidget构造函数的运行时间,当构造函数执行结束后,该对象也将会执行析构因此不会在运行时显示。而若使用new关键字在堆区创建对象,则其生命周期由开发者自行控制,在执行delete前该对象会一直存在。

对象树

从上文中我们可以看到,在创建控件对象时我们一般使用new关键字为新对象开辟内存空间,然而却并没有相对应的delete进行空间释放,这是因为Qt使用了对象树的技术使得程序运行结束后能够自行释放内存空间。

对象树的定义:

  • 当你创建一个QObject对象时,可以看到QObject的构造函数会接收一个QObject指针作为参数,这个参数就是parent(父对象指针)。由此,每当创建一个QObject对象时,Qt便会自动添加该对象到其父对象的children()列表,当父对象析构时,这个列表中的所有对象也会被析构。(注意:这里的父对象并不是继承意义上的父类,而是说该对象显示在(或依附于)哪个对象中。例如:一个按钮有一个QShortcut(快捷键)对象作为其子对象,当我们删除按钮时,这个快捷键也会被删除。
  • QWidget是能够在屏幕上显示的一切组件的父类。QWidget继承自QObject,因此也继承了这种对象树关系。当创建的对象在堆区时,如果指定的父对象所属类是QObject派生下来的类或其子类,那么派生下来的类可以无需管理释放操作,会将对象放入对象树,一定程度上简化了内存回收机制。

Qt中的坐标系

  • 左上角为(0, 0)点
  • x以右为正方向,y以下为正方向,坐标向右向下逐渐增大
  • 对于嵌套窗口,其坐标是相对于父窗口来说的(即坐标原点总是位于父窗口左上角)
Licensed under CC BY-NC-SA 4.0
热爱可抵岁月漫长,温柔可挡艰难时光。
Nothing but enthusiasm brightens up the endless years.
转载请注明主页网址哦~