欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

01-QT入门

程序员文章站 2022-07-12 15:51:49
...

QT学习方法:
1. qt命名非常规范,不同的类中功能类似的函数名称相同。比如show、setParent、move、resize、setFixedSize等。
2. 英文名称与中文翻译对应:resize重置窗口大小、setFixedSize固定窗口大小等。

一. 新建项目

类名:自定义的类名,继承自以下三种基类。

QMainWindow:自带工具栏、菜单栏等。
QDialog:对话框。
QWidget:QMainWindow和QDialog的父类,空窗体。

创建界面:勾选后就可以拖拽控件。

二. 项目文件内容介绍:

1. .h文件:Q_OBJECT:有这个宏就可以使用信号和槽机制。

2. .cpp文件:
        1. #include <QApplication> //包含应用程序类,这样才能创建.exe文件;
            QApplication a(argc, argv);创建应用程序对象;
            return a.exec(); //程序会被阻塞到这一句,使得应用程序进入 消息/事件循环机制;相当于先写a.exec();然后再return一个值。
        2. myWidget w; //创建自定义类的对象 w; w.show(); //调用show方法,显示。

3. pro文件:

        1. QT        += core gui //使用的qt模块。
        2. greaterThan(QT_MAJOR_VERSION, 4) : QT += widgets //widget模块在大于4的版本中独立于gui模块。增加此句判断版本,如果版本大于4,那么增加此模块。
        3. TARGET = first //应用程序名字,有此处决定;而不是QApplication a(argc, argv);的命名。
        4. TEMPLATE = app //创建应用程序模板。表示我们创建的是应用程序,而不是库。
        5. SOURCES / HEADERS:包含的源文件和头文件。
 

三. QT creator使用

        1. Ctrl + / //注释
        2. Ctrl + r //运行
        3. Ctrl + i //格式对齐
        4. Ctrl + 单击鼠标右键 //跳转到声明或定义
        5. F4 //在cpp和h文件之间切换。
        6. F1 //帮助手册

        单独使用帮助文档的方法:创建D:\Qt\Qt5.9.3\5.9.3\mingw53_32\bin\assistant.exe的快捷方式,然后将快捷方式剪切到桌面。不能直接复制帮助手册。

四. 按钮

可以在自定义类的构造函数中编写代码进行测试,构造函数会自动被调用。
1. 方式一:手动设置父对象;调用show方法,会默认以顶层方式显示按钮;
setParent方法会设定按钮的父对象,但是与继承关系不同

    QPushButton *btn = new QPushButton;
//    btn->show();
    btn->setParent(this);
    btn->setText("按钮");

2. 方式二:构造函数传入按钮名及父对象;this参数可以不写,但需要手动设置父对象或者调用show方法。

QPushButton *btn = new QPushButton("button", this);

3. 重置与固定(窗口与按钮)大小:*窗口可以不使用this调用方法,直接写函数名即可。

    this->resize(600, 400); //resize(600, 400);
    this->setFixedSize(400, 400); //setFixedSize(400, 400);
    btn->resize(100, 50);
    btn->setFixedSize(100, 50);

4. 修改窗口标题:默认为项目名称;当然此处的this也可以省略不写。

this->setWindowTitle("window");

五. 对象树
1. 是什么:
        1. 树形结构,记录着父类对象与子类对象的对应关系;
        2. 只有QObject类派生出来的类,才具备对象树功能。
        3. 当主动关闭子类对象后,也会从父对象的children列表中删除,保证每个对象只被析构一次。
2. 作用:
        1. 进入父对象的坐标系统。
        2. 简化了内存回收机制,当销毁父类对象的时候,首先销毁子类对象(递归)。也就是说,我们使用new创建出来的对象不用手动delete进行删除。
3. 不同点:不同于继承关系。
 

六. 信号和槽
1. 是什么:
        1. 信号:某个对象发出的特征/状态
        2. 槽:某个对象产生的一个行为
2. 实现方式:
        1. 信号:声明在signals下,只需要声明,不需要实现。
        2. 槽:声明在slots下,需要实现,一个成员函数。
3. 连接:当对象A发出A信号时,对象B的槽函数就会被调用。

connect(&对象A, &A的信号, &对象B, &B的槽);

4. 点击按钮关闭窗口(系统自带的信号和槽):在写信号和槽的时候,可以先打出“&”,然后就会自动提示出信号和槽函数。

connect(btn, &QPushButton::clicked, this, &myWidget::close);

5. 自定义的信号和槽:Base class:继承就会提供构造函数,可以设置父对象。
        1. 信号没有返回值类型,可以有参数,也可以重载。
        2. 槽是一个普通成员函数,所以可以是任意函数,是虚函数都可以,可以有返回值(但是一般并不使用,也没有意义),可以有参数,也可以重载。

创建A、B类,继承QWidget
A.h

signals:
    //信号没有返回值类型,可以有参数,也可以重载
    void single();

B.h

public slots:
    //槽 普通成员函数 需要实现
    void sayHi();

B.cpp

void Man:: sayHi(){
    qDebug() << "hello A";
}

mywidget.h

//头文件中添加两个成员变量
A *a;
B *b;

mywidget.cpp

    g = new Woman(this);
    b = new Man(this);
    connect(g, &Woman::single, b, &Man::sayHi);
    emit g->single(); //g->single();

emit:告知编译器发送一个信号,宏定义为空。直接调用g->single();也是可以的。

6. 点击按钮发出信号,执行槽函数:点击按钮是信号,在本类中添加一个槽函数用来发出信号,以触发另一个槽函数。即使用两个connect进行连接。

7. 信号和槽的对应关系
        1. 一个信号可以连接多个槽
        2. 一个槽可以连接多个信号

8. 带参数的信号和槽:发出信号时,信号的参数会自动被槽函数的参数接收。
        规则:槽函数的参数个数可以少于信号的,但是只要是有参数的,必须顺次与信号的参数类型一致。

9. 信号和槽有重载时的连接处理
        方法1:当信号和槽有重载版本的时候,需要声明函数指针,明确告诉编译器连接的是哪一个版本。
        注意:如注释部分所示,QT编译会报错。
                1. 函数类型转换时需要添加作用域,可以理解为权限问题,使其拥有相同的权限。
                2. QT中类型转换后的函数名不需要取地址。

    void (A::*sig_int)(int) = &A::single;
    void (B::*slots_int)(int) = &B::sayHi;

    connect(a, sig_int, b, slots_int);
    connect(a2, sig_int, b, slots_int);

    //void (*sig_int)(int) = &A::single;
    //void (*slots_int)(int) = &B::sayHi;

    //connect(a, &sig_int, b, &slots_int);
    //connect(a2, &sig_int, b, &slots_int);

        方法2:QT4版本信号槽重载时的连接处理写法:宏函数括号中的函数转换为字符串。
        优点:简便直观
        缺点:如果参数不对应,编译阶段不告警,运行阶段才告警。给程序留下潜在隐患。

connect(g, SIGNAL(single(int)), b, SLOT(sayHi(int)));

        方法3:QT的语法允许使用lambda表达式作为槽函数与信号连接起来;第三个参数可以省略

connect(btn, &QPushButton::clicked, [=](){
        this->close();
    });

评价:以便使用lambda表达式,之后是方法1,发放2使用较少。

10. 断开信号和槽的连接:体现QT信号和槽机制松散耦合的特征。

disconnect(g, SIGNAL(single(int)), b, SLOT(sayHi(int)));