零基础Qt笔记<传智教育>Qt版本:2022 5.15

目录

1、创建第一个Qt程序

2、命名规范以及快捷键

3、QPushBottom的创建

4、对象树

5、Qt中的坐标系

6、信号和槽

6.1 实现点击按钮关闭窗口

6.2 自定义的信号和槽

6.3 自定义的信号和槽发生重载的解决

6.4 信号连接信号

6.5 Qt4版本信号连接

6.5 Lambda表达式

6.6 信号槽的总结

7、QMainWindow

7.1 菜单栏和工具栏

7.2 状态栏、铆接部件、核心部件 

8、资源文件的添加 

9、模态和非模态对话框创建

10、消息对话框

11、其他对话框

12、登陆窗口布局

13、控件

13.1 按钮组

13.2 QListWidget控件

13.3 QTreeWidget控件

13.4 QTableWidget控件

13.5 其他控件介绍

14、自定义控件

15、Qt的鼠标事件

16、定时器

17、event 事件分发器和事件过滤器 

​编辑

18、QPainter

18.1 绘图事件 

18.2 绘图高级设置

18.3 手动调用绘图事件

18.4 绘图设备 

19、QFile文件读写操作

文件QFile和文件信息读写QFileInfo

20、翻金币项目 

 ***问题总结


1、创建第一个Qt程序

Create Project->Qt Widgets Application(创建一个Qt应用,包含一个基于qt设计师的主窗体)

->Location(不能有空格和中文,可以有下划线),路径选择不能有中文(重要!!!)->Build System(选择qmake,ps:一般的Qt工程你就直接使用qmake就可以了,cmake的强大功能一般人是用不到的 //参考的另一篇博客)->Details(QWidget是QDialog和QMainWindow的父类,Qwidget是空窗口,QMainWindow多了工具栏,QDialog是对话框),选择QWidget作为基类,取消Generate form使用代码编写。->Kits(选择套件)->Summary(finish)团队开发时,添加到版本控制系统(svn,vss,git)

 main函数代码

#include "mywidget.h"

#include <QApplication>// 包含一个应用程序类的头文件

// main程序入口 argc命令行变量的数量 argv命令行变量的数组
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);// a应用程序对象,在qt中,有且仅有一个
    MyWidget w;// 创建窗口对象,MyWidget的父类->QWidget
    w.show();// 窗口对象 默认不会显示,必须调用show方法显示
    return a.exec();//让应用程序对象a进入消息循环机制,等待用户点叉叉,使得窗口不会一闪而过,使代码阻塞到这一行
}

2、命名规范以及快捷键

.pro文件不要添加任何东西,除非你知道写的是什么。.pro文件就是工程文件,它是qmake自动生

成的用于生产makefile的配置文件。

QT       += core gui //Qt包含的模块

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets//大于4版本以上,包含widget模块

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 \
    mywidget.cpp
//头文件 自动生成的
HEADERS += \
    mywidget.h

Qt基本模块

 mywidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>//窗口类头文件 QWidget

class MyWidget : public QWidget
{
    Q_OBJECT // Q_OBJECT宏,允许类中使用信号和槽的机制

public:
    MyWidget(QWidget *parent = nullptr); // 有参构造函数
    ~MyWidget();
};
#endif // MYWIDGET_H

mywidget.cpp 

#include "mywidget.h"

// 命名规范
// 类名 首字母大写,单词和单词之间首字母大写
// 函数名 变量名称 首字母小写,单词和单词之间首字母大写

// 快捷键
// 注释 ctrl + /
// 运行 ctrl + r
// 编译 ctrl + b
// 字体缩放 ctrl + 鼠标滚轮
// 查找 ctrl + f
// 整行移动 ctrl + shift + ⬆或者⬇
// 帮助文档 F1
// 自动对齐 ctrl + i
// 同名之间的.h和.cpp切换 F4

// 帮助文档,左侧的帮助;在Qt5.16\mingw49_32\bin的Qt助手

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)// 初始化列表
{
}

MyWidget::~MyWidget()
{
}

3、QPushBottom的创建

 构造函数里创建

#include "mywidget.h"
#include <QPushButton>

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)// 初始化列表
{
    // 创建一个按钮
    QPushButton * btn = new QPushButton;
    // btn->show();// show以顶层方式弹出窗口控件
    // 让btn对象 依赖在 MyWdget窗口中
    btn->setParent(this);

    // 显示文本
    btn->setText("first button");

    // 创建第二个按钮 按照控件的大小创建窗口
    QPushButton * btn2 = new QPushButton("second button",this);
    // 重置窗口大小 长x宽
    resize(600,400);
    
    // 移动btn2按钮,设置坐标
    btn2->move(100,100);
    
    // 设置固定窗口大小,用户不能改变串窗口大小
    setFixedSize(600,400);
    
    // 设置窗口标题
    setWindowTitle("第一个窗口");

}

MyWidget::~MyWidget()
{
}

4、对象树

父类先构造,子类先析构

在Qt中创建对象的时候会提供一个Parent对象指针。

QObject是以对象树的形式组织起来的。

当你创建一个QObject对象时候,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是Parent,也就是父对象指针。

这相当于,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父类对象的children()列表。

当父类对象析构的时候,这个列表中的所有对象也会被析构(注意:这里的父对象并不是继承意义的父类

QWdget是能够在屏幕上显示的一切组件的父类。
QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。例如,当用户关闭一个对话框的时侯,应用程序将共刑除,那么,我们希望属于这个对话框的按钮、图标等应该一起被迸除。事实就是如此,因为这些都是对话框的子组件。

 MyPushButton类的创建

#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H

#include <QPushButton>//继承QPushButton,没有这个选择就先选择继承它的父亲

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

    ~MyPushButton();

signals:

};

#endif // MYPUSHBUTTON_H
#include "mypushbutton.h"
#include <QDebug>//打印输出

MyPushButton::MyPushButton(QWidget *parent)
    : QPushButton(parent)//换父亲
{
    qDebug()<<"我的按钮类构造调用";
}

MyPushButton::~MyPushButton()
{
    qDebug()<<"我的按钮类析构调用";
}

打印先打印的是儿子的析构,但是是后面释放。 

#include "mywidget.h"
#include <QPushButton>
#include <mypushbutton.h>
#include <QDebug>//打印输出
MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)// 初始化列表
{

    // 创建一个自己的按钮对象
    MyPushButton *mybtn = new MyPushButton;
    mybtn->setText("我自己的按钮");
    mybtn->move(200,0);
    mybtn->setParent(this);
    qDebug()<<"MyWidget构造";
}

MyWidget::~MyWidget()
{
    qDebug()<<"MyWidget析构";
}


总结:当创建的对象在堆区时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作(就是不用deletex),将对象会放入到对象树中。一定程度上简化了内存回收机制

5、Qt中的坐标系

左上角为(0,0),x向右增大,y向下增大

6、信号和槽

6.1 实现点击按钮关闭窗口

connect( 信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽))

信号槽的优点:松散耦合,信号发送端和接受端本身是没有关联的,通过connect连接将两端耦合在一起。 

#include "mywidget.h"
#include <QPushButton>
#include <mypushbutton.h>
#include <QDebug>//打印输出
MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)// 初始化列表
{

    // 创建一个自己的按钮对象
    MyPushButton *mybtn = new MyPushButton;
    mybtn->setText("我自己的按钮");
    mybtn->move(200,0);
    mybtn->setParent(this);

    // 点击我的按钮,关掉窗口
    // 参数1:信号的发送者,参数2:发送的具体信号(点击)函数的地址;参数3:信号的接受者this窗口,参数4:信号的处理(槽)函数地址
    connect(mybtn,&MyPushButton::clicked,this,&MyWidget::close);
    //connect(mybtn,&QPushButton::clicked,this,&QWidget::close);// 用父类的也可以
}

MyWidget::~MyWidget()
{
}

6.2 自定义的信号和槽

自定义信号:写到signals下;返回值是void,只需要声明,不需要实现;可以有参数,可以重载。

自定义槽:早期Qt槽函数必须写在public slot下,高级版本可以写道public或者全局下;返回值是void,需要声明,也需要实现;可以有参数,可以重载。

触发自定义信号:emit

#include "widget.h"

// Teacher 类 老师类
// Student 类 学生类
// 下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    // 创建老师和学生对象,并且指定父亲,就不用释放
    this->zt = new Teacher(this);
    this->st = new Student(this);

    connect(zt,&Teacher::Hungry,st,&Student::treat);

    // 调用下课,触发老师饿了,随后学生响应
    classisover();
}

Widget::~Widget()
{
}

void Widget::classisover()
{
    // 下课函数 调用后触发老师饿了信号
    emit zt->Hungry();
}

6.3 自定义的信号和槽发生重载的解决

1.需要利用函数指针明确指向函数的地址,成员函数指针需要加上作用域

2.QString->char * 先转成QByteArray(.toUtf8())再转char*(),.data的返回值是char *

Widget代码 

#include "widget.h"

// Teacher 类 老师类
// Student 类 学生类
// 下课后,老师会触发一个信号,饿了,学生响应信号,请客吃饭

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    // 创建老师和学生对象,并且指定父亲,就不用释放
    this->zt = new Teacher(this);
    this->st = new Student(this);

    //connect(zt,&Teacher::Hungry,st,&Student::treat);

    // 调用下课,触发老师饿了,随后学生响应
    //classisover();
    // 函数指针->函数地址,&+函数名
    void(Teacher::*teacherSignal)(QString) = &Teacher::Hungry;// 成员函数的函数指针
    void(Student::*studentSlot)(QString) = &Student::treat;
    // 当出现重载的时候,需要出现设置信号和槽的函数地址
    connect(zt,teacherSignal,st,studentSlot);//重载出现二义性

    classisover();
}

Widget::~Widget()
{
}

void Widget::classisover()
{
    // 下课函数 调用后触发老师饿了信号,两个信号
    emit zt->Hungry();
    emit zt->Hungry("宫保鸡丁");
}

 槽函数重载

#include "student.h"
#include <QDebug>
Student::Student(QObject *parent)
    : QObject{parent}
{

}

void Student::treat()
{
    qDebug()<<"请老师吃饭";
}
void Student::treat(QString foodname)// 重载treat
{
    //打印QString类型有引号,要转成char*就没有引号
    //qDebug()<<"请老师吃饭,老师要吃:"<<foodname;
    // QString->char * 先转成QByteArray(.toUtf8())再转char*(),data的返回值是char *
    qDebug()<<"请老师吃饭,老师要吃:"<<foodname.toUtf8().data();
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值