QT 学习笔记(二)

一. 在QT Widget中创建一个按钮

包含头文件: #include <QPushButton>

详情看代码

  1. #include "widget.h"
  2. #include <QPushButton>
  3. #include "ui_widget.h"
  4. Widget::Widget(QWidget *parent)
  5. : QWidget(parent) // 初始化列表
  6. , ui(new Ui::Widget)
  7. {
  8. ui->setupUi(this);
  9. /// 按钮
  10. QPushButton *button = new QPushButton;
  11. /// button->show(); show()以顶层方式弹出, 想在Widget窗口显示, 就需要依赖Widget窗口
  12. /// 设置父亲
  13. button->setParent(this);
  14. /// 设置文字
  15. button->setText("加入");
  16. /// 创建按钮第二种方式
  17. QPushButton *button2 = new QPushButton("第二按钮", this);
  18. /// 重置窗口大小
  19. this->resize(600, 400);
  20. /// 移动按钮
  21. button2->move(100, 0);
  22. /// 重置按钮大小
  23. button2->resize(150, 50);
  24. /// 重置窗口标题
  25. setWindowTitle("QTFirst_Window");
  26. /// 设置固定窗口大小
  27. setFixedSize(600, 400);
  28. }
  29. Widget::~Widget()
  30. {
  31. delete ui;
  32. }

二. 对象模型

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

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

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

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

这种机制在 GUI 程序设计中相当有用。例如,一个按钮有一个QShortcut(快捷键)对象作为其子对象。当我们删除按钮的时候,这个快捷键理应被删除。这是合理的

说人话:

  • 所有new出来的对象不用管释放, children表中的对象会在窗口关闭后自动释放
  • 在创建一个自己的类时, 一定要加上QOBJECT, 将这个类添加进children表中

代码说明:

mybutton.h mybutton.cpp

  1. /// mybutton.h
  2. #ifndef MYBUTTON_H
  3. #define MYBUTTON_H
  4. #include <QWidget>
  5. #include <QPushButton>
  6. class Mybutton : public QPushButton
  7. {
  8. Q_OBJECT
  9. public:
  10. explicit Mybutton(QWidget *parent = nullptr);
  11. ~Mybutton();
  12. signals:
  13. };
  14. #endif // MYBUTTON_H
  15. /// mybutton.cpp
  16. #include "mybutton.h"
  17. #include <QDebug>
  18. Mybutton::Mybutton(QWidget *parent) : QPushButton(parent)
  19. {
  20. }
  21. Mybutton::~Mybutton()
  22. {
  23. qDebug() << "Mybutton析构";
  24. }

wigdet.cpp

  1. #include "widget.h"
  2. #include <QPushButton>
  3. #include "mybutton.h"
  4. #include "ui_widget.h"
  5. #include <QDebug>
  6. Widget::Widget(QWidget *parent)
  7. : QWidget(parent) // 初始化列表
  8. , ui(new Ui::Widget)
  9. {
  10. ui->setupUi(this);
  11. /// 重置窗口标题
  12. setWindowTitle("QTFirst_Window");
  13. /// 设置固定窗口大小
  14. setFixedSize(600, 400);
  15. Mybutton *mybtn = new Mybutton;
  16. mybtn->setText("我的按钮");
  17. mybtn->move(100, 100);
  18. mybtn->setParent(this);
  19. }
  20. Widget::~Widget()
  21. {
  22. delete ui;
  23. qDebug() << "Wigdet的析构";
  24. }

在wigdet中设置parent后, 析构顺序如下:

QT 学习笔记二 - 图1

三. QT中的坐标系

QT 学习笔记二 - 图2

四. 信号和槽机制

信号槽是 Qt 框架引以为豪的机制之一。所谓信号槽,实际就是观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。这就类似观察者模式:当发生了感兴趣的事件,某一个操作就会被自动触发。

系统自带的的信号和槽

信号和槽的使用方式:

connect(sender, signal, receiver, slot)

参数解释:

  • sender:发出信号的对象
  • signal:发送对象发出的信号, 传入地址
  • receiver:接收信号的对象, 传入地址
  • slot:接收对象在接收到信号之后所需要调用的函数(槽函数)

!

QT 学习笔记二 - 图3

自定义信号和槽

  • 自定义信号
    • 写到 signals下
    • 返回 void
    • 需要声明,不需要实现
    • 可以有参数 ,可以重载
  • 自定义槽函数
    • 返回void
    • 需要声明 ,也需要实现
    • 可以有参数 ,可以重载
    • 写到 public slot下 或者public 或者全局函数
  • 触发自定义信号 emit

下课后,老师触发饿了信号,学生响应信号,请客吃饭

实现:

widget.cpp

  1. #include "widget.h"
  2. #include "ui_widget.h"
  3. Widget::Widget(QWidget *parent)
  4. : QWidget(parent)
  5. , ui(new Ui::Widget)
  6. {
  7. ui->setupUi(this);
  8. zt = new Teacher(this);
  9. st = new Student(this);
  10. /// 连接
  11. connect(zt, &Teacher::hungry, st, &Student::treat);
  12. ///下课
  13. classIsOver();
  14. }
  15. void Widget::classIsOver()
  16. {
  17. // 触发自定义信号 emit
  18. emit zt->hungry();
  19. }
  20. Widget::~Widget()
  21. {
  22. delete ui;
  23. }