参考:
qt学习指南
Qt5和Qt6的区别-CSDN博客
Qt 学习之路_w3cschool
Qt教程,Qt5编程入门教程(非常详细)
本地环境:
win10专业版,64位
Qt5力推QML界面编程。QML类似HTML,可以借助CSS进行美化,借助JavaScript进行交互。不同平台下的QML有相同的渲染机制,界面效果一致。不过大部分时候还是要使用C++
Qt6主推QML,但是似乎有坑,不要碰。(知乎一些答案说的)
Qt5支持win7,5.12是LTS(长期支持),因此综合考虑使用Qt5.12(项目需要)
Observer Pattern,也称为发布订阅模式。就是对象之间是一对多,当一个对象改变状态时,所有依赖于它的对象都会得到通知(信号)并自动更新。
不过观察者有时候也可以是被观察者。
信号槽可以将程序中的各个对象进行解耦
当某个事件发生后,sender会发出一个signal,这是一种广播,如果有receiver对这个信号感兴趣,它就会通过connect(连接函数),用自己的一个slot(槽函数)来处理这个信号。slot是自动调用的。
connect(sender, signal, receiver, slot);
// slot是接收到信号之后需要调用的函数
原生信号槽:Qt为每一个Object都预先写好了一些信号和槽函数
也可以自定义信号槽,需要:
使用lambda表达式写槽函数
lambda表达式可以像对象一样使用,可以赋给变量或者作为参数传递,也可以像函数一样求值,同时执行完毕会自动释放内存,可以达到随时随地使用的效果。格式为:
[capture](parameters)specifiers -> return_type { body }
lambda函数 这里 写过
specifiers是可选的,比如下面这个函数,本身按lambda的写法是只读的,如果想要修改的话,可以把specifiers写成mutable,此时可以修改副本的值,不过该变量的值还是不变的
auto a2 = [Value](int x) mutable {Value++;};
如果返回值是void或者函数体只有一处return,那么可以省略return_type
将事件抽象为一个对象,当用户发起一个行为,就把对应的事件加入事件队列,对于系统来说,每次只要处理事件队列里未处理的事件就可以了;如果没用事件,程序就阻塞,不执行任何代码。
必要时,Qt的事件也可以不进入事件队列,直接处理。
与信号的区别:信号一旦发出,对应的槽函数一定会被执行,但是事件可以使用事件过滤器进行过滤。
如果要使用事件,只要让类继承QWidget类及其子类(里面定义了很多protected virtual函数),然后再重写事件回调函数即可。
下载安装不提,北大那边找不到5.12版本,我是在官网找的,用迅雷下的。安装完成后,在qt\Qt5.12.0\Tools\QtCreator\bin下找到Qt Creator,新建一个项目。勾选创建界面,此时Forms文件夹下有一个mainwindow.ui,是当前的界面。
其中.pro是项目文件、配置信息,是告诉qmake如何创建makefile的。Headers下放头文件,Sources下面放cpp文件,Forms下放窗口的设计实现。
点击ui文件可以进入设计页面,此时可以拖动左侧的空间,修改窗口的外观。
看一下ui文件的源代码,可以看到是xml格式(一堆标签),红圈部分对应的是我拖动和调过格式的Hello World。
运行效果:
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
}
MainWindow::~MainWindow()
{
}
// main.cpp
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// 填充代码 开始
MainWindow w;
w.show();
// 填充代码 结束
return a.exec();
}
假设在创建新项目时,去掉创建界面的勾选,那么新项目将没有Forms文件夹,也没有ui文件,此时设计按钮也是禁用的。
此时修改mainwindow.h,
#include
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QLabel *lab;
};
再修改mainwindow.cpp的构造函数:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->lab = new QLabel("Hello World", this);
}