Qt 之 show,hide,setVisible,setHidden,close 等小结
0
QObject::deleteLater()
delete obj;析构对象
1
QWidget::setVisible(bool)
使得Widget可见或不可见
2
QWidget::setHidden(bool)
1号的马甲
3
QWidget::show()
1号的马甲
4
QWidget::hide()
1号的马甲
5
QWidget::close()
视情况确定是否调用4号0号
6
QDialog::done(int)
始终会调用4号,视情况调用0号
7
QDialog::accept()
6号的马甲
8
QDialog::reject()
6号的马甲
写在前面
我们知道,
分配到heap中的对象(通过 new),当对其delete,才会被析构。
分配在stack中的对象,当其离开作用域是被析构
在 Qt 中,一般建议你使用 new 的方式创建对象。或者,你可以看看 从 Qt 的 delete 说开来
注意:
本文接下来的讨论,都是假定你用的 new 创建的对象。
QObject
从Qt类的祖宗开始吧。因为QObject不涉及界面啊,成员中只涉及析构问题。在从 Qt 的 delete 说开来 一文中,我们知道,
obj->deleteLater();
最后调用的就是:
delete obj;
很简单哈。所以,这个函数的谈论(略)
另外:对象析构时会发射 destroyed 信号。注意,是对象析构时,这是句废话,但要记住。
QWidget
setVisible
呵呵,show()、hide()、setVisible()、setHidden() 这4个函数让人看得眼花缭乱。怎么办?
看看代码吧:
virtual void setVisible(bool visible);
inline void setHidden(bool hidden) { setVisible(!hidden); }
inline void show() { setVisible(true); }
inline void hide() { setVisible(false); }
代码很清楚:这四个东西之中,只有 setVisible 是独立的,其他三个都是它的马甲!
setVisible 的作用是什么呢?顾名思义,使得一个Widget可见或不可见。
要点:不可见,是Widget不在界面上显示,但不代表对象被析构!
close
这个函数,Manual中给的其实很详细的,很透彻。但一开始想弄明白还真是不容易。
首先,我们直接调用close时(或者点击关闭按钮调用),它会生成 QCloseEvent 事件:(我们可以选择接受或阻止它,如果我们阻止事件,close将直接返回,什么都不做)
看点源码:
bool QWidgetPrivate::close_helper(CloseMode mode)
{
...
QCloseEvent e;
if (mode == CloseWithSpontaneousEvent)
QApplication::sendSpontaneousEvent(q, &e);
else
QApplication::sendEvent(q, &e);
if (!that.isNull() && !e.isAccepted()) {
data.is_closing = 0;
return false;
}
...
}
其次:如果我们接受了事件(默认),她就直接调用我们前面提到的朋友。(从界面上干掉)
q->hide();
再次:如果我们为它设置过标记位(关闭时删除它):又看到老朋友不是?(从内存中干掉)
if (q->testAttribute(Qt::WA_DeleteOnClose)) {
q->setAttribute(Qt::WA_DeleteOnClose, false);
q->deleteLater();
}
题外:close 还是其他代码,但与本主题无关,不再涉及。
QDialog
QDialog 和 QWidget 相比,多了 done、reject 和 accept 3个相关函数:
先看看两个马甲:
void QDialog::accept()
{
done(Accepted);
}
void QDialog::reject()
{
done(Rejected);
}
done
done 做的事情和close比较类似:因为它调用了close所调用的 close_helper 函数。只不过不同于close函数,它始终会先让Widget不可见。然后close操作,最后根据参数发射信号
void QDialog::done(int r)
{
Q_D(QDialog);
hide();
setResult(r);
d->close_helper(QWidgetPrivate::CloseNoEvent);
emit finished(r);
if (r == Accepted)
emit accepted();
else if (r == Rejected)
emit rejected();
}
注意:QDilaog可能包含事件循环,事件循环由QDialog::exec() 开始,QDialog::setVisible(false)将负责退出事件循环,这儿用的是其马甲hide()。
Qt 之 show,hide,setVisible,setHidden,close 等小结的更多相关文章
- VC生成的DLL给QT的EXE调用时lib路径问题小结
VC生成的DLL给QT调用,有两种方式,一种是隐式调用调用(使用.lib文件方式): ① 在*.pro工程文件中添加VC生成的lib文件路径时,或者使用一个绝对路径,如: LIBS += " ...
- QDialog在hide()之后,就被销毁的原因
一路跟踪源码,关键就是这两句: int QDialog::exec() { Q_D(QDialog); if (d->eventLoop) { qWarning("QDialog::e ...
- Qt中让Qwidget置顶的方法
一般来是说窗体置顶和取消只要 setWindowFlags(Qt::WindowStaysOnTopHint); setWindowFlags(Qt::Widget); 要 ...
- QtNetwork说明(两)使用QT实现360的ctrl+ctrl特征
头文字说明: <span style="font-size:18px;">#ifndef GOOGLESUGGEST_H #define GOOGLESUGGEST_H ...
- Pyqt QSystemTrayIcon 实现托盘效果
pyqt的托盘效果很好实现,在Pyqt的demo中有个例子 路径:PyQt4\examples\desktop\systray.py 今天我就仿这个Tray效果做效果 一. 创建UI trayicon ...
- 拦截QWebView弹出窗口
环境 系统:win7 64位旗舰版 软件:VS2013.QT5.5.1-32位 概述 当网页打开一个新的窗口时,我们有时候需要根据URL地址来判断弹出窗口是否合理,如果合理则弹出新窗口,否则不弹出.本 ...
- 写给iOS小白的MVVM教程(一): 从MVC到MVVM之一个典型的MVC应用场景
前言 本着实践为主的原则,此系列文章不做过多的概念性的阐述和讨论;更多的代码和篇幅用来展示MVC和MVVC下的基础代码结构与具体实现,来展示各自优劣.这篇文章,更多的在于发掘MVC与MVVC的共性,以 ...
- QT源码解析(七)Qt创建窗体的过程,作者“ tingsking18 ”(真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法)
前言:分析Qt的代码也有一段时间了,以前在进行QT源码解析的时候总是使用ue,一个函数名在QTDIR/src目录下反复的查找,然后分析函数之间的调用关系,效率实在是太低了,最近总结出一个更简便的方法, ...
- 【QT】C++ GUI Qt4 学习笔记3
菜单界面的实现. 看书上第三章,好长,好多代码.我敲了半天,想看看效果,结果却显示不出来.仔细一看,发现spreadsheet的实现在第四章.郁闷.... 又到官网上下代码,结果居然不能运行.难道是因 ...
随机推荐
- H面试程序(12): 输出字符串中第一个只出现一次的字母
题目描述: 若字符串str为'' sbdddsbfc'',则输出 f; 若字符串str为''aabbccdd'',则输出:字符串str中的字符都出现两次以上 #include <stdio.h& ...
- vim乱码问题
有的时候使用gvim查看文本文件时,出现乱码,现在来确定下原因. 经过我的查资料,发现gvim里有几个关于编码设置的变量:encoding.fileencoding.fileencodings.ter ...
- linux-FTP服务常用命令及测试
一.vsftpd服务的安装,启动及关闭1.安装vsftpd[root@rusky bdump]# yum install vsftpd --必须配置yum源才能使用yum命令来安装vsftpd,或者挂 ...
- Android开发 学习笔记——HelloWorld
Day01 1.java开发过程———————————————不建议先用ECLIPSE写代码,因为它的函数式自动生成的,不利于找寻编程手感打开记事本写完程序后,修改扩展名为.java然后在DOS控制台 ...
- GridView专栏
鉴于GridView的强大,鄙人突然心血来潮,想把GridView单独拿出来整理一下. (一)gridview如何加自增长列 protected void GridView1_RowDataBound ...
- 开启MSSQLServer跨服务器查询功能
首先在MSSQL客户端中进行如下图文操作配置 其次使用脚本进行操作配置 ---开启SQLServer 跨服务器查询功能 exec sp_configure 'show advanced options ...
- 02js高级Function
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- sql server sys.object表字段说明
列名 数据类型 说明 name sysname 对象名. object_id int 对象标识号. 在数据库中是唯一的. principal_id int 如果不是架构所有者,则为单个所有者的 ID. ...
- filestream 读取视频文件
class Program { static void Main(string[] args) { string source = @"F:\361\android studio\4.0\亲 ...
- network-manager与interfaces冲突
网络配置的两种方式 Ubuntu下修改网络配置有两种方式:图形界面方式(network-manager)和修改/etc/network/interfaces 但是如果两种方式的网络设置不同,就会产生冲 ...