(19 封私信 / 82 条消息) 如何优雅的在Windows上使用Qt开发STM32程序呢? - 知乎 (zhihu.com)
基于《学习之路2》学习qt
我们是推荐在栈上创建组件。因为要靠人工管理new
和delete
的出错概率要远大于在栈上的自动控制。除此之外,在堆上和在栈上创建已经没有任何区别。
看看最开始的程序
1 |
|
- 注:主事件循环是
- 处理分发事件
- 初始化和终结程序
- 设置系统范围和程序范围
如何理解下面代码:
1 | Widget::Widget(QWidget *parent) :QWidget(parent) |
将parent设置为nullptr将构造一个没有父对象的对象。如果对象是一个QWidget,它将成为一个顶级窗口。
信号和槽(signal and slot)
Qt 5 中,QObject::connect()
有五个重载:
1 | /** |
添加动作(Action)
Qt 将用户与界面进行交互的元素抽象为一种“动作”,使用QAction
类表示。
QAction
包含了图标、菜单文字、快捷键、状态栏文字、浮动帮助等信息
1 | /** |
导入资源文件
cmake
1 | # 设置资源文件名称 |
对象模型(MOC)
用标准 C++ 编译器编译 Qt 源程序之前,Qt 先使用一个叫做 moc(Meta Object Compiler,元对象编译器)的工具,先对 Qt 源代码进行一次预处理。
你应当注意到了,信号函数是不需要编写实现代码的,那怎么可以通过标准 C++ 的编译呢?,这其实就是 moc 进行了处理之后的效果。
Qt 使用 moc,为标准 C++ 增加了一些特性:
- 信号槽机制,用于解决对象之间的通讯,这个我们已经了解过了,可以认为是 Qt 最明显的特性之一;
- 可查询,并且可设计的对象属性;
- 强大的事件机制以及事件过滤器;
- 基于上下文的字符串翻译机制(国际化),也就是 tr() 函数,我们简单地介绍过;
- 复杂的定时器实现,用于在事件驱动的 GUI 中嵌入能够精确控制的任务集成;
- 层次化的可查询的对象树,提供一种自然的方式管理对象关系。
- 智能指针(QPointer),在对象析构之后自动设为 0,防止野指针;
- 能够跨越库边界的动态转换机制。
parent 指针
当你创建一个QObject
对象时,会看到QObject
的构造函数接收一个QObject
指针作为参数,这个参数就是 parent,也就是父对象指针
我们创建的这个QObject
对象会自动添加到其父对象的children()
列表。当父对象析构的时候,这个列表中的所有对象也会被析构。
(注意,这里的父对象并不是继承意义上的父类!)
我们也可以自己删除子对象,它们会自动从其父对象列表中删除。
QObject::dumpObjectTree()
和QObject::dumpObjectInfo()
这两个函数进行这方面的调试。
。Qt 保证没有QObject
会被 delete 两次,这是由析构顺序决定的。
看看下面代码
1 | { |
作为父组件的 window 和作为子组件的 quit 都是QObject
的子类(事实上,它们都是QWidget
的子类,而QWidget
是QObject
的子类)。这段代码是正确的,quit 的析构函数不会被调用两次,因为标准 C++ (ISO/IEC 14882:2003)要求,局部对象的析构顺序应该按照其创建顺序的相反过程。因此,这段代码在超出作用域时,会先调用 quit 的析构函数,将其从父对象 window 的子对象列表中删除,然后才会再调用 window 的析构函数。
布局管理(layout)
(13条消息) QT常用的布局方法_SharedNotNew的博客-CSDN博客_qt布局技巧
所谓 GUI 界面,归根结底,就是一堆组件的叠加。我们创建一个窗口,把按钮放上面,把图标放上面,这样就成了一个界面。
我们创建了一个QHBoxLayout
对象。显然,这就是一个布局管理器。然后将组件都添加到这个布局管理器,并且把该布局管理器设置为窗口的布局管理器。这些代码看起来都是顺理成章的,应该很容易明白。并且,布局管理器很聪明地做出了正确的行为:保持QSpinBox
宽度不变,自动拉伸QSlider
的宽度。
1 | void MainWindow::Layout_set() { |
一些布局类 | 描述 |
---|---|
QBoxLayout | 水平或垂直排列子控件 |
QButtonGroup | 用于组织按钮控件组的容器 |
QFormLayout | 管理输入控件和其相关的标签 |
QGraphicsAnchor | 表示在QGraphicsAnchorLayout中两个项目之间的锚 |
QGraphicsAnchorLayout | 可以在图形视图中将控件锚定在一起的布局 |
QGridLayout | 网格布局 |
QGroupBox | 带标题的分组框 |
QHBoxLayout | 水平排列控件 |
QLayout | 几何管理器的基类 |
QLayoutItem | QLayout 操作的抽象item |
QSizePolicy | 描述水平和垂直大小调整策略的布局属性 |
QSpacerItem | 布局中的空间隔 |
QStackedLayout | 堆栈布局,同一时间只有一个控件可见 |
QStackedWidget | 堆栈窗体,同一时间只有一个控件可见 |
QVBoxLayout | 垂直排列控件 |
1 | void addSpacing(int size); //添加间隔大小 |
信号重载
1 | QObject::connect(spinBox, &QSpinBox::valueChanged, slider, &QSlider::setValue); |
当我们使用&QSpinBox::valueChanged
取函数指针时,编译器不知道应该取哪一个函数(记住前面我们介绍过的,经过 moc 预处理后,signal 也是一个普通的函数。)的地址,因此报错。解决的方法很简单,编译器不是不能确定哪一个函数吗?那么我们就显式指定一个函数。
1 | //方法就是,我们创建一个函数指针,这个函数指针参数指定为 int: |
也可以
1 | QObject::connect(&newspaper, |
下一篇对话框。。。。