目录

目录

一、C++基础

1、类和对象

2、继承

3、多态

4、数据封装

5、接口(抽象类)

二、QT笔记

1、QT基类

2、QT项目文件组成 

3、mainwindow.cpp程序主函数开头:

4、QT信号与槽(声明在mainwindow.h中,定义和connect在mainwindow.cpp中)

三、QT实战

1、向开发板的出厂系统中拷贝编译后的QT文件

2、交叉编译QT工程文件


一、C++基础

        C++面向对象的三大特征:封装、继承和多态;

0.1、LINUX中C++环境配置:

sudo apt-get install gcc g++
sudo apt-get install lsb-core lib32stdc++6 // 安装其他库

测试是否安装成功:

g++ -v
gcc -v

1、类和对象

1.1类是C++的核心特征,类用于指定对象的形式:

        例如Dog为狗这一大类、dog1可以作为一个对象;

1.2从类中实例化对象两种方式:

从栈中实例化对象 从堆中实例化对象

                          /*class.cpp*/
#include <iostream>
#include <string>

using namespace std;

class Dog{      //定义类
    public:
            string name;    //成员变量
            int age;

            void run(){
            cout<<"name: "<<name<<"\n"<<"age: "<<age<<endl;   //输出流
            }
};

int main(){      //主函数
Dog dog1;        //*从栈中实例化对象

dog1.name="xiaohuang";
dog1.age=2;
dog1.run();

Dog *dog2 = new Dog();  //*从堆中实例化对象  (指针对象都得这么实例化吗?)
    if(NULL ==dog2){    //如果申请的内存空间为空,则直接返回
        return 0;
        }
dog2.name="xiaohei";
dog2.age=3;
dog2.run();

return 0;
}

 随后可以在LINUX中编译然后执行:     

  g++ class.cpp -o CLASS         编译

  ./CLASS                        执行

 1.3、构造函数与析构函数

        实际上定义类时,如果没有定义构造函数和析构函数,编译器就 会生成一个构造函数和析构函数。

 构造函数:在对象实例化时被系统自动调用,仅且调用一次。

析构函数:在对象结束其生命周期时系统自动执行析构函数。

1.4、this 指针

        this指针一般在成员函数里用:

 void Dog::func()       //类外定义函数用::(作用域限定符)
20 {
21 this->name = "小黄";
22 cout<<"name:"<<this->name<<endl;
23 }
        谁调用这个函数, this 就 指向谁

2、继承

         面向对象程序设计中最重要的一个概念;

     2.1、    class 派生类 :access-specifier 基类

         class derived-class: access-specifier base-class

        访问修饰符 access-specifier 是 public、 protected private 其中的一个, base-class 是之前定义过的某个类的名称。如果未使用访问修饰符 access-specifier ,则默认为 private
        1. 公有继承( public ):当一个类派生继承公有基类时,基类的公有成员也是派生类的公有成
员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但
是可以通过调用基类的公有和保护成员来访问。
        2. 保护继承( protected ): 当一个类派生继承保护基类时,基类的公有和保护成员将成为派
生类的保护成员。
        3. 私有继承( private ):当一个类派生继承私有基类时,基类的公有和保护成员将成为派生类 的私有成员。
class Dog : public Animal

2.2、重载: 函数重载运算符重载

        重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。

3、多态

        多态:C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数;
        
        形成多态必须具备三个条件:
1. 必须存在继承关系;
2. 继承关系必须有同名虚函数(其中虚函数是在基类中使用关键字 virtual 声明的函数,在派
生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数);
3. 存在基类类型的指针或者引用,通过该指针或引用调用虚函数。

3.1、虚函数:是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数;

        想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接或后期绑定。
        虚函数声明如下:
        virtual ReturnType FunctionName(Parameter)
        虚函数必须实现,如果不实现,编译器将报错;
        纯虚函数:virtual void funtion1()=0;
包含纯虚函数的类是抽象类,抽象类不能定义实例,但是可以声明指针对象
/* 声明一个 Animal 的指针对象,注:并没有实例化 */
37 Animal *animal;
/* 实例化 dog 对象 */
39 Dog dog;
43 /* 存储 dog 对象的地址 */
44 animal = &dog;
45 /* 调用 run()方法 */
46 animal->run();
        虚函数是 C++ 中用于实现多态 (polymorphism) 的机制 核心理念就是通过基类访 问派生类定义的函数

4、数据封装

        4.1封装是面向对象编程中的把数据操作数据的函数绑定在一起的一个概念;
            数据封装是一种把数据和操作数据的函数捆绑在一起的机制,
            数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。

5、接口(抽象类)

        设计抽象类(通常称为 ABC )的目的,是为了给其他类提供一个可以继承的适当的基类。
        抽象类不能被用于实例化对象 ,它只能 作为接口使用

二、QT笔记

        Qt Designer 方式开发程序简单,优点就是方便快捷,ui 文件的优点就是能比较直观快捷的看到整体的布局。
        但是缺点也很明显!简单的一两个部件还是可以的,但是控件多了就不好管理,每次都要 打开 ui 文件添加新控件,不好用代码管理!——> 用编程方式而不用Qt Designer 方式开发程序( 在新建项目时*ui 文件不勾选)。

1、QT基类

  • 为了学习方便,我们统一默认基类为 QMainWindow,但是注意,在嵌入 式里一般不需要标题栏,状态栏等,所以常用的是 QWidget 基类。
  1. QMainWindow:主窗口类,主窗口具有主菜单栏、工具栏和状态栏。类似于一般的应用程序的主窗口。如果您想做个嵌套的窗口程序开发的软件,不妨选择这个 QMainWindow
  2. QWidget:是可视界面类的基类,也就是说QMainWindow类也是由QWidget继承封装而来。 所以 QWidget 要比 QMainWindow 功能少一些。
  3.  QDialog:对话框类,建立一个对话框界面。比较少使用此项作为基类。一般以 QMainWindow QWidget 作为基类的居多。注因为 QWidget 不带窗口标题栏等,嵌入式里最好 QWidget

2、QT项目文件组成 

 

  01_hello_world.pro 是项目管理文件,这个项目管理文件十分重要,当您加入了文件或者删除了文件,Qt Creator 会自动修改这个*.pro 文件。有时候需要打开这个*.pro 文件添加我们 的设置项。

Header 分组,这个节点下存放的是项目内所有的 头文件*.h
Source 分组,这个节点下存放的是项目内的所有 C++ 源码文件*.cpp
Forms 分组,这个节点下是存放项目内所有 界面文件*.ui *.ui 文件由 XML 语言描述组成,编译时会生成相应的 cpp 文件,这样交叉编译器就可以编译它了。
  1.  mainwindow.h 一般有与之对应的一个 cpp 文件叫 mianwindow.cpp。其中 mainwindow.h 包含类的声明,mianwindow.cpp 包含类的实现。这与我们前面学习的 c++是一样的。
    Q_OBJECT 是一个宏,由 Qt 进行处理,这 也是 Qt 针对 C++ 扩展的地方,所有用到信号的类都要加这个宏。

3、mainwindow.cpp程序主函数开头:


MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent)

  • QMainWindow是父类(基类)而MainWindow是子类(派生类)
  • QMainWindow(parent)是基类构造函数
  • 类Mainwindow在实现构造函数时,要初始化基类QMainwindow的数据成员但是因为无法继承基类的构造函数,所以才用这种方式初始化基类的数据成员。

MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)

  • ui(new Ui::MainWindow)和QMainWindow(parent)一样,都是构造函数MainWindow(QWidget *parent)里的初始化的一部分,语法用“,”隔开;

4、QT信号与槽(声明在mainwindow.h中,定义和connect在mainwindow.cpp中

  • GUI 程序设计的主要内容就是对界面上各组件的信号的响应; 信号与槽函数参数类型要保持相同?
  • 信号( Signal )就是在特定情况下被发射的事件;
  • 槽( Slot )就是对信号响应的函数;
  1. 信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:
    QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
    • sender 是发射信号的对象的名称;
    • signal() 是信号名称;
    • receiver 是接收信号的对象名称;
    • slot() 是槽函数的名称,需要带括号,有参数时还需要指明参数;
    • ​​​​​​SIGNAL 和 SLOT 是 Qt 的宏,用于指明信号和槽,并将它们的参数转换为相应的字符串。
  2. 一个信号可以连接多个槽,例如:
    connect(pushButton, SIGNAL(clicked()), this, SLOT(hide());
    connect(pushButton, SIGNAL(clicked()), this, SLOT(close());
    这是当一个对象 pushButton 的被单击时,所在窗体有两个槽进行响应,一个 hide() 用于隐
    藏主窗体,一个 close 用于关闭主窗体。
  3. 一个信号可以连接另外一个信号(说明了 connect 万物皆可连,非常好用!),例如:

    connect(pushButton, SIGNAL(objectNameChanged(QString)),this, SIGNAL(windowTitelChan
    ged(QString)));
    这样,当一个信号发射时,也会发射另外一个信号,实现某些特殊的功能。
  4. 在使用信号与槽的类中,必须在类的定义中加入宏 Q_OBJECT (特别重要)。
  5. ​​​​​​​断开连接的方法:disconnect();

2.5 QtCreator常用快捷键​​​​​​​

        运行  ctrl +R

        编译  ctrl +B

        帮助文档  F1 ,点击F1两次跳到帮助界面

        跳到符号定义 F2 或者ctrl + 鼠标点击

        注释 ctrl+/

        字体缩放  ctrl + 鼠标滚轮

        整行移动代码 ctrl + shift + ↑或↓

        自动对齐   ctrl + i

        同名之间的.h和.cpp文件跳转 F4

三、QT实战

  • 开发板:正点原子I.MX 6ULL(linux)
  • ubuntu18.04+QT 5.12.9

1、向开发板的出厂系统中拷贝编译后的QT文件

  1. 利用(ubunt以下称其为主机)开启NFS服务器挂载根文件系统

    主机开启NFS服务器,建立/home/xu/linux/nfs/rootfs根文件目录,作为网络根文件系统供开发板内核启动的时候挂载;

    开发板通过网线路由器和主机相连,在uboot命令行模式下设置环境参数,以便boot启动系统后能连接上主机的网络根文件系统;

    以上工作完成后,开发板可以直接共享主机根文件系统目录下的文件,也就可以通过这种方式将交叉编译后的可执行文件交由开发板执行。

  2. Windows 通过MobaXterm ssh 连接到开发板 

开发板通过网线/(USB WiFi)-路由器和主机windows相连,将win中的文件直接拖拽到ssh界面即可。

使用前提:开发板与 PC 机用网线连接在同一路由器上,路由器能上网。
请注意,这里使用的是 出厂的文件系统 ,支持 ssh 协议 。默认开发板文件系统不支持 FTP
传输,其他文件系统请确认是否支持 ssh 协议。
【正点原子】 I.MX6U 嵌入式 Linux 驱动开发指南 V1.x 4.9 小节已经安装过 MobaXterm
使用 ifconfig MobaXterm 查看开发板的 ip ,如下图,记下开发板的 ip 192.168.1.222
                                     
   ifconfig

win中查看ip用

ipconfig

2、交叉编译QT工程文件

  1. 小型工程(例如01_led)
  • 在编译QT工程前,主机上前提需要先安装 (用户快速上手指南)4.2 小节的 Poky 交叉编译工具链。
  • 使能第 4.2 小节的交叉编译环境变量。
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
  • 执行 qmake ,生成 Makefile ,用于编译。
qmake

 

  • 执行 make ,开始编译 Qt 综合 Demo
make -j 16 // -j 16 是允许最大同时 16 条编译任务同时执行,16 一般取分配虚拟机的核
心数的 2 倍
  • 编译过和中有报警告,可忽略。编译完成如下图,编译得到的 QDesktop 文件,可以直接
拷贝到出厂系统下直接执行 ./01_led  即可。
  • 开发板执行上诉文件时若遇到权限不够的问题执行:
chmod 777 可执行文件名
  • 执行文件前可以先从设置关闭开发板的桌面程序
  • 关闭桌面程序后,可执行下面的指令进行重启桌面程序
/opt/QDesktop > /dev/null 2>&1 &

Logo

更多推荐