1. Hello Qt ¶

本章我们开始学习Qt Creator、工程文件的创建、以及构建运行等操作。

Qt是一个C++应用程序框架,首先我们需要掌握C++的知识,其次才是熟悉Qt的相关特性,这里就默认读者已经对C++有所了解。 这章将以简单的Hello qt例程介绍下项目的文件组成和管理、项目的构建、与运行,以及在鲁班猫板卡上部署。

提示

Qt开发环境:如果是交叉编译,Qt源码版本是5.15.8/6.2.4;如果是在板卡上编译,根据系统不同Qt版本不同。

1.1. 创建一个简单工程 ¶

我们依然从最基础的Hello Qt开始,使用Qt Creator创建一个简单工程。

打开Qt Creator,点击 创建项目,选择 Qt Widgets Application:

helloqt001

重命名工程,设置路径,新建一个空白工程:

helloqt002

选择用什么构建项目:

helloqt003

接下来设置要创建的类名、选择其父类(默认选择了QMainWindow)、编辑相关的头文件和源码文件名,勾选form复选框来创建ui文件(这些可以根据自己工程修改,教程是都保持默认值):

helloqt022

然后选择构建套件:

helloqt004

最后点击完成工程的构建,工程界面显示:

helloqt005

创建完成,最终会切换到这个界面,

  • 编号1为工程的项目结构,也可以切换到其他视图;

  • 编号2为代码编辑区域;

  • 编号3则是编译生成的Qt程序预览;

  • 编号4选择不同的kits来编译不同平台的Qt程序;

  • 编号5为编译构建项目并运行。

切换到我们创建指定的工程目录,该目录下会有项目结构中显示的文件:

helloqt005

一些工程文件的解释:

  • .h .c++ 文件为头文件和源文件,我们的代码通常都是写在这两种文件中的

  • .ui 文件就是我们前面提到界面文件,其实质是xml格式的文本文件

  • .pro 文件就是工程管理文件,以qmake特有的语法记录了工程的文件和配置

  • .pri pri文件通常也用于工程管理,将代码整理成一个模块,通过引入pri文件来引入代码模块

  • .pro.user 为用户描述文件,记录了我们工程的开发环境构建环境等等,也是xml格式的文本文件

  • .qrc 除上面的文件,工程中一般还会有qrc资源文件,用于记录图片,音视频等文件

提示

更多.pro工程文件的配置项详细,或者想了解工程的配置,查看下https://doc.qt.io/qt-6/qmake-project-files.html

我们双击工程管理里面的mainwindow.ui,会切换到可视化的UI设计窗口QtDesigner。

helloqt006
  • 编号1为Qt给我们提供的标准控件,可以拖控件到编号为3的区域。

  • 编号2为布局和界面设计工具栏,前面几个是进入不同的设计模式,后面是界面的布局

  • 编号3选中区域为窗口布局区域,待设计的界面为窗体(form),运行起来的界面就是窗口。图片中我们添加了一个控件,显示”Hello Qt”。

  • 编号4为信号与槽编辑器与 Action 编辑器,进行可视化地进行信号与槽的关联,可视化设计 Action。

  • 编号5为对象浏览栏,用树状视图显示窗体上各组件之间的布局包含关系。

  • 编号6为属性编辑器,属性编辑器显示某个选中的组件或窗体的各种属性及其取值,可以在属性编辑器里修改这些属性的值。

关于Qt Designer更多描述参考下 野火Qt教程 以及Qt官网的 Qt Designer教程 。

点击左侧编辑,回到代码编辑界面。 这时我们会看到,代码编辑区域出现大篇幅字符,这时XMl格式的文本。 其文本内容记录着我们刚刚编辑的UI信息,比如窗口,Label显示的位置、内容等等。 当我们拖动控件,调整UI的时候,QtDesigner会自动更新XML文本。

helloqt007

点击左侧的小电脑配置程序,选择前面选择的kits套件,选择 Desktop Qt5.15.2 GCC 64-bit Debug 套件, 然后点击绿色三角形符号,编译运行程序就会看到:程序主界面上多出了 ‘Hello Qt’ 的字样。

1.2. Hello widget ¶

上面使用Qt可视化工具创建了一个hello qt窗口,下面演示使用代码来创建一个widget窗口。

首先点击工程目录,鼠标右键单击,然后点击 Add New … 新建文件,选择C++中的类,点击choose:

helloqt008
helloqt009

修改类名,MyWidget,包含QObject和QWidget:

helloqt010

直接点击完成:

helloqt011

最终在工程以及工程目录下都添加了mywidget.h和mywidget.cpp:

helloqt012

在这两个文件中,手动修改代码,如下:

lubancat_qt_tutorial_code/HelloQt/mywidget.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#ifndef MYWidget_H
#define MYWidget_H

#include <QWidget>
#include <QObject>

class MyWidget : public QWidget
{
    Q_OBJECT
public:
    explicit MyWidget(QWidget *parent = nullptr);

signals:

public slots:
};

#endif // MYWidget_H
lubancat_qt_tutorial_code/HelloQt/mywidget.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "mywidget.h"

#include <QLabel>
#include <QBoxLayout>

MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
    // 创建一个 QLabel 控件,并设置文本为 "hello widget"
    QLabel *label =new QLabel("hello widget");
    // 设置 QLabel 对齐方式为居中对齐
    label->setAlignment(Qt::AlignCenter);

    // 创建一个 QVBoxLayout 布局,并将其设置为 MyWidget 的布局
    QVBoxLayout *verLayout = new QVBoxLayout(this);
    // 设置布局的边距为0
    verLayout->setContentsMargins(0, 0, 0, 0);
    // 设置布局的间距为0,以避免控件之间的间隔
    verLayout->setSpacing(0);

    // 将 QLabel 控件添加到垂直布局中
    verLayout->addWidget(label);
}

在这两个文件中,我们创建了一个类MyWidget,这个类继承自QWidget,具备QWidget的所有public属性。 在MyWidget类的构造函数中,我们定义了一个QLabel,label中有文字 hello widget, 我们通过 setAlignment 设置label上的文字居中显示。

然后我们又定义了一个垂直布局的类 QVBoxLayout,我们把label添加到布局中, QVBoxLayout会自动根据其父窗口的大小位置,将label以最合适方式进行缩放、调整。

最后,修改main.cpp内容,注释掉之前自动创建的 MainWindow w ,手动定义 MyWidget w

lubancat_qt_tutorial_code/HelloQt/main.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include "mainwindow.h"
#include "mywidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //MainWindow w;
    MyWidget w;

    w.resize(640, 480);
    w.show();

    return a.exec();
}

在main函数中,我们定义了一个应用程序a和窗口w,我们设置窗口大小 640*480 ,并通过 show 将其显示。 随后a.exec()会让整个应用进入 事件循环。

比如当我们改变窗口大小时,会产生绘图事件,Qt就会将显示的窗口进行重绘; 当我们点击关闭按钮时,就会产生关闭事件,Qt就会结束应用 。

上面的一连串的代码修改最终的效果和使用Qt Designer最终效果相同, 使用Qt Designer显然更加快捷,但是代码方式更加灵活,两者都需要掌握。

1.3. 例程说明 ¶

文档所涉及的示例代码可以从网盘配套资料获取,也可以从下面仓库获取:

  • https://gitee.com/LubanCat/lubancat_rk_code_storage/tree/master/lubancat_qt_tutorial_code

1.3.1. 例程编程思路 ¶

  • 使用Qt Creator创建一个HelloQt简单工程;

  • 向默认生成的UI添加QLabel,显示 hello qt

  • 向工程中添加一个窗口类,MyWdiget;

  • 代码添加一个QLabel,显示 hello widget

  • 主函数声明 MyWdiget w,并显示。

1.3.2. 编译构建 ¶

这算是第一次讲解Qt程序的构建,会比较详细,后面都是按照这个套路来。

helloqt013

在左下角有四个按钮,其功能分别是,编译配置,编译并运行程序,编译并调试程序,仅编译程序。

helloqt014

先点击左侧的小电脑配置程序,会弹出几个选择框

  • 构建套件,使用 Desktop Qt5.15.2 GCC 64-bit 编译的程序可在Ubuntu上运行程序,为系统自动配置的构建套件;使用 LubanCat-RK 则会生成能在LubanCat上运行的可执行程序。

  • 构建模式:Debug:调试版本,包含调试信息,所以构建好的程序比Release大很多,并且不进行任何优化,便于程序员调试; Release:发布版本,不对源代码进行调试,编译时对应用程序的速度进行优化,使得程序在代码大小和运行速度上都是最优;Profile 则是在这两种之中取一个平衡,兼顾性能和调试

  • 最后一个为要编译的程序,一个工程包含多个子项目时使用。

套件配置完毕就可以开始编译。 选择底部有八个选项用于log输出,选择编译输出, 窗口输出程序编译时候的log,debug模式也可以看debug输出。

helloqt015

除此以为,我们可以直接鼠标右键某个工程进行编译、清除、重新构建。

提示

当两种构建套件进行切换时,请重新构建项目或清除之前项目。

helloqt015

1.3.3. 运行结果 ¶

1.3.3.1. ubuntu20.04上直接编译运行 ¶

选择“Desktop Qt5.15.2 GCC 64-bit”构建套件,然后在虚拟机ubuntu20.04上直接点击 绿色三角形符号,编译并运行程序,效果如下:

helloqt017

如果是在板卡上使用Qt Creator,可以直接点击编译运行,不需要下面的操作。

1.3.3.2. 交叉编译部署到板卡 ¶

选择*LubanCat-RK*构建套件,然后部署到板卡可以使用远程连接部署,或者单独编译,然后将编译好的程序拷贝到LubanCat上。

直接远程连接部署

远程连接部署参考下前面环境 搭建章节 先修改下部署的路径,打开helloqt.pro,修改 target.path = /home/cat/,如下所示:

lubancat_qt_tutorial_code/HelloQt/helloqt.pro
 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
# 添加QT项目需要的模块
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

# 添加c17配置支持
CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

# 源文件
SOURCES += \
    main.cpp \
    mainwindow.cpp \
    mywidget.cpp

# 头文件
HEADERS += \
    mainwindow.h \
    mywidget.h

# UI
FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /home/cat/
!isEmpty(target.path): INSTALLS += target

远程连接参考下前面的环境搭建章节,这里点击选择使用*LubanCat-RK* 编译套件:

helloqt017

点击构建运行,会自动部署到板卡,并运行:

helloqt018

板端显示结果(带桌面系统的Debian10):

helloqt018

并把可执行文件传输到/home/cat/目录下:

cat@lubancat:~$ file helloqt
helloqt: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter
/lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, with debug_info, not stripped
cat@lubancat:~$

单独编译拷贝到板卡部署:

拷贝可执行程序到板卡,可以通过SCP、NFS、sftp、u盘等。 NFS使用 参考这里

SCP命令如下:

# scp传输文件,ip地址根据具体板子和PC,板子和PC在一个局域网下
# scp 文件名 服务器上的某个用户@服务器ip:/文件保存路径
scp filename server_user_name@192.168.103.102:server_file_path
# 从服务器拉取文件
# scp 服务器上的某个用户@服务器ip:/服务器文件存放路径 拉取文件保存路径
scp server_user_name@192.168.103.102:server_file_path local_path

编译好的程序在 lubancat_qt_tutorial_code 目录中,通过scp命令将编译好的程序拉到LubanCat。

# 可执行程序文件的目录,根据自己实际项目设置的目录
scp root@192.168.103.102:~/lubancat_qt_tutorial_code/xxx/helloqt ~/

在LubanCat板卡上运行程序,执行helloqt。

# 简单设置环境,然后执行程序
cd ~
./helloqt

1.4. 参考链接 ¶

Qt Creator的更多设置和使用参考下 Qt Creator Manual ,

Qt官方非常详细的 Qt 示例 ,

网上能找到很多非常优秀的 Qt 教程 。