QWidget一生,从创建到销毁事件流
本文标题:QWidget一生,从创建到销毁事件流 本文地址:http://techieliang.com/2017/11/319/
最近做UI,有多个窗口嵌套,且所有窗口均用了Layout布局,当运行程序时,主窗口布局有效,而嵌套的窗口布局未生效。
1. 构造函数Resize()
首先我想到的是,我设置了Layout,那么他会自动调整大小,是不是在创建子窗口的时候并没有获取到此窗口在父类布局中占用的位置?那么我在构造的时候分别设置每个子窗口即可。
child_widget->Resize(this->XXXX->size());//XXXX是子窗口一个widget的区域,或者qstackedwidget等某个页面的大小
使用上述类似的指令去重新设置,发现没有任何效果。而根本原因是构造函数中获得的Size()并不对,不是主窗口的真实尺寸。
2. 笨方法-QTimer()
由于时间关系,使用了笨方法。无论如何最后构造完成以后肯定窗口显示了。。。。
那么建立一个定时器,构造的时候启动定时器,连接到槽,然后timeout()以后执行Resize指令,并且stop Timer。。。
此方法确实解决了布局适应的问题,但是建立一个timer,方法并不友好
3. QWidget构造到销毁事件流分析
此处为了方便,不对QWidget做范例分析,直接用QMainWindow做分析,QMainWindow是QWidget的子类。
下面会详细说明分析方法,若需要对QWidget或者其他控件做分析,可以仿照进行。
3.1. 实验项目配置
直接新建一个Qt Widgets项目,为了测试方便,我把默认的菜单栏、工具栏、状态栏都取消了,只添加了一个QPushButton按钮控件。
程序代码如下:
*.pro
- QT += core gui
- greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
- TARGET = untitled
- TEMPLATE = app
- DEFINES += QT_DEPRECATED_WARNINGS
- SOURCES += \
- main.cpp \
- mainwindow.cpp
- HEADERS += \
- mainwindow.h
- FORMS += \
- mainwindow.ui
mainwindow.ui
- <?xml version="1.0" encoding="UTF-8"?>
- <ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>400</width>
- <height>300</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>MainWindow</string>
- </property>
- <widget class="QWidget" name="centralWidget">
- <widget class="QPushButton" name="pushButton">
- <property name="geometry">
- <rect>
- <x>190</x>
- <y>150</y>
- <width>89</width>
- <height>24</height>
- </rect>
- </property>
- <property name="text">
- <string>PushButton</string>
- </property>
- </widget>
- </widget>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <resources/>
- <connections/>
- </ui>
main.cpp
- #include "mainwindow.h"
- #include <QApplication>
- int main(int argc, char *argv[]) {
- QApplication a(argc, argv);
- MainWindow w;
- w.show();
- return a.exec();
- }
mainwindow.h
- #pragma once
- #include <QMainWindow>
- namespace Ui {
- class MainWindow;
- }
- class MainWindow : public QMainWindow {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
- protected:
- bool event(QEvent *event) Q_DECL_OVERRIDE;
- private:
- Ui::MainWindow *ui;
- };
mainwindow.cpp
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QEvent>
- #include <QDebug>
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow) {
- qDebug()<<"Befor ui->setupUi(this)";
- ui->setupUi(this);
- qDebug()<<"After ui->setupUi(this)";
- }
- MainWindow::~MainWindow() {
- delete ui;
- }
- bool MainWindow::event(QEvent *event) {
- qDebug()<<event->type();
- QMainWindow::event(event);
- }
其实项目很简单,就是直接重写了event(QEvent *event)函数,利用qDebug()输出事件类型。
事件类型通过type调用,返回TYPE枚举类型,此类型在“qcoreevent.h”文件夹存储
- enum Type {
- None = 0, // invalid event
- Timer = 1, // timer event
- MouseButtonPress = 2, // mouse button pressed
- MouseButtonRelease = 3, // mouse button released
- MouseButtonDblClick = 4, // mouse button double click
- MouseMove = 5, // mouse move
- KeyPress = 6, // key pressed
- KeyRelease = 7, // key released
- FocusIn = 8, // keyboard focus received
- FocusOut = 9, // keyboard focus lost
- FocusAboutToChange = 23, // keyboard focus is about to be lost
- Enter = 10, // mouse enters widget
- Leave = 11, // mouse leaves widget
- Paint = 12, // paint widget
- Move = 13, // move widget
- Resize = 14, // resize widget
- Create = 15, // after widget creation
- ……………………………………………………………………//太多了,具体自行查看
- };
3.2. 结果
直接运行程序就出现了结果,从运行到窗口创建完毕:
同时在main()函数中每个位置增加断点可以看到不同指令的详细执行效果。
- Befor ui->setupUi(this)//构造函数开始----MainWindow?w;
- QEvent::Type(ChildAdded)
- QEvent::Type(WindowTitleChange)
- After ui->setupUi(this)//构造函数结束---MainWindow?w结束;
- QEvent::Type(PlatformSurface)//---w.show()开始;
- QEvent::Type(WinIdChange)
- QEvent::Type(WindowIconChange)//icon
- QEvent::Type(Polish)//style polish
- QEvent::Type(ChildPolished)
- QEvent::Type(Move)//调整窗口位置
- QEvent::Type(Resize)//调整窗口尺寸
- QEvent::Type(Show)//显示
- QEvent::Type(CursorChange)
- QEvent::Type(ShowToParent)
- QEvent::Type(PolishRequest)
- QEvent::Type(LayoutRequest)
- QEvent::Type(UpdateLater)
- QEvent::Type(UpdateRequest)//---w.show()结束
- QEvent::Type(WindowActivate)//---a.exec()
- QEvent::Type(ActivationChange)
- QEvent::Type(Paint)//---a.exec()结束
关闭窗口:
- QEvent::Type(NonClientAreaMouseMove)//鼠标移动到关闭
- QEvent::Type(NonClientAreaMouseButtonPress)//点击右上角关闭
- QEvent::Type(Close)
- QEvent::Type(WindowDeactivate)
- QEvent::Type(ActivationChange)
- QEvent::Type(Hide)
- QEvent::Type(HideToParent)
- QEvent::Type(UpdateRequest)
3.3. 结果分析
通过构造的事件流可以看到,Qt的设置各个控件的尺寸的操作在构造函数之后,所以在构造函数用Size获取到的尺寸是错误的。
Qt的Event类型有很多,发型不同类型的事件会调用对应的函数,可以看QWidget的API,上述发生事件部分对照关系已经在注释中写出,下面总结一下主要的事件流,出现的先后顺序就是事件发生顺序:
MainWindow?w;
- 调用构造函数
w.show();
- QStyle::polish()
- QWidget::moveEvent()
- QWidget::resizeEvent()
- QWidget::showEvent()—–在这里刷新所有嵌入的子页面的size即可实现自适应
a.exec();
- QWidget::ensurePolished()
- QWidgetBackingStore::sync()
- QWidget::paintEvent()
退出:
- QWidget::closerEvent()
QWidget一生,从创建到销毁事件流的更多相关文章
- 监听域对象创建和销毁的Listener
1.什么是Servlet监听器? 先来看看什么是监听器.监听器是专门用于对其它对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时立即采取相应的行动.Servlet监听器是S ...
- JavaScript 事件 事件流 事件对象 事件处理程序 回调函数 error和try...catch和throw
参考资料: 慕课网 DOM事件探秘 js事件对象 处理 事件驱动: JS是采用事件驱动的机制来响应用户操作的,也就是说当用户对某个html元素进行操作的时候,会产生一个时间,该时间会驱动某些函数 ...
- JavaScript Event 事件 事件流 事件对象 事件处理程序 回调函数 error和try...catch和throw
参考资料: 慕课网 DOM事件探秘 js事件对象 处理 事件驱动: JS是采用事件驱动的机制来响应用户操作的,也就是说当用户对某个html元素进行操作的时候,会产生一个事件,该事件会驱动某些函数 ...
- JavaScript事件流原理解析
一.为什么会有这一篇的文章 国庆前几天由于任务比较重,要赶在国庆前把一个进度的任务开发完成,所以也就有点赶,但是却遇到了一个比较奇怪的Bug,导致了任务比预计的延迟了几个小时,对此深表遗憾,所以利用国 ...
- js事件捕获,事件冒泡,事件委托以及DOM事件流
一:DOM事件流: 事件流是从页面接收事件的顺序,DOM2级事件规定事件流包括三个阶段: ①事件捕获阶段:用意在于事件达到目标之前捕获它,在事件捕获阶段事件流模型:document→html→body ...
- Android上的事件流操作数据库
最近在浏览某篇有关事件流的文章时,里面提到了数据的流处理,兴趣来了,就想看看能否在Android端实现一个. 根据文章的介绍,将每次数据的变更事件,像是插入,删除或者更新等,记为一个不可变的事件,让数 ...
- JavaScript事件流
什么是JS事件流 早期的IE事件传播方向为由上至下,即从document逐级向下传播到目标元素:而Netscape公司的Netscape Navigator则是朝相反的方向传播, 也就是从目标元素开始 ...
- [Effective Java]第二章 创建和销毁对象
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- JavaScript DOM高级程序设计 4.3控制事件流和注册事件侦听器--我要坚持到底!
一.事件流 我们通过下面一个实例,进行说明. <body> <h1>Event Flow</h1> <ul id="nav"> &l ...
随机推荐
- 微信小程序通过api接口将json数据展现到小程序上
实现知乎客户端的一个重要知识前提就是,要知道怎么通过知乎新闻的接口,来把数据展示到微信小程序端上. 那么我们这一就先学习一下,如何将接口获取到的数据展示到微信小程序上. 1.用到的知识点 <1& ...
- Java基础之instanceof和transient关键字用法
instanceof 用于检测指定对象是否是某个类(本类.父类.子类.接口)的实例.Java中的instanceof也称为类型比较运算符,因为它将类型与实例进行比较. 返回true或false. 如果 ...
- 北京Uber优步司机奖励政策(1月30日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- Java:IDEA设置虚拟机运行时参数
第一步:打开“Run->Edit Configurations”菜单 第二步:选择“VM Options”选项,输入你要设置的VM参数 第三步:点击“OK”.“Apply”后设置完成
- VINS(二)Feature Detection and Tracking
系统入口是feature_tracker_node.cpp文件中的main函数 1. 首先创建feature_tracker节点,从配置文件中读取信息(parameters.cpp),包括: ROS中 ...
- Fat Jar - Myeclipse插件安装使用方法- 完美解决
Eclipse可以安装一个叫Fat Jar的插件,用这个插件打包非常方便,Fat Jar的功能非常强大. 工具/原料 Eclipse Kepler Fat Jar 方法/步骤 1 Fat Jar功能非 ...
- 2019年猪年海报PSD模板-第四部分
14套精美猪年海报,免费猪年海报,下载地址:百度网盘,https://pan.baidu.com/s/1WUO4L5PHIHG5hAurv52_2A
- 第三模块:面向对象&网络编程基础 第1章 面向对象
我的失败与梦想(一) 我的失败与梦想之为何创办路飞学城 01-编程范式 02-面向过程编程 03-面向对象编程介绍 04-定义类与实例化出对象 05-如何使用类 06-如何使用对象 07-属性查找与绑 ...
- ISE 14.7安装教程最新版(Win10安装)——解决Win10安装完后打不开快捷方式的方法
ISE 14.7安装教程最新版(Win10安装) Xilinx ISE是一款世界著名的硬件设计软件,它为设计流程的每一步都提供了直观的生产力增强工具,覆盖从系统级设计探索.软件开发和基于HDL硬件设计 ...
- lesson 22 by heart
lesson 22 by heart on end = continuously 连续不断地 know/learn sth by heart 记忆sth falter: speak hesitantl ...