QT中QWidget类简介
一、详细描述
QWidget类是所有用户界面对象的基类。通俗的来讲,Qt基本上所有的UI类都是由QWidget继承出来的,而QWidget继承于QObject, 大家可以查阅Qt source 即可发现一些微妙的写法,如这篇文章有详细介绍:Qt 库对象数据的声明和使用。
窗口层次
窗口部件是用户界面的一个原子:它从窗口系统接收鼠标、键盘和其它事件,并且在屏幕上绘制自己的表现。每一个窗口部件都是矩形,并且它们按Z轴顺序排列的。一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分。
QDialog是最普通的顶级窗口。不被嵌入到一个父窗口部件的窗口部件被叫做顶级窗口部件。通常情况下,顶级窗口部件是有框架和标题栏的窗口(尽管如果使用了一定的窗口部件标记,创建顶级窗口部件时也可能没有这些装饰。)在Qt中,QMainWindow和不同的QDialog的子类是最普通的顶级窗口。一个没有父窗口部件的窗口部件一直是顶级窗口部件。非顶级窗口部件是子窗口部件。它们是它们的父窗口部件中的子窗口。你通常不能在视觉角度从它们的父窗口部件中辨别一个子窗口部件。在Qt中的绝大多数其它窗口部件仅仅作为子窗口部件才是有用的。(当然把一个按钮作为或者叫做顶级窗口部件也是可能的,但绝大多数人喜欢把他们的按钮放到其它按钮当中,比如 QDialog。)
QWidget有很多成员函数,但是它们中的一些有少量的直接功能:例如,QWidget有一个字体属性,但是它自己从来不用。有很多继承它的子类提供了实际的功能,比如QPushButton、QListBox和QTabDialog等等。
每一个窗口部件构造函数接受一个或两个标准参数:
1. QWidget *parent = 0是新窗口部件的父窗口部件。如果为0(默认),新的窗口部件将是一个顶级窗口部件。如果不是,它将会使parent的一个孩子,并且被parent的几何形状所强迫(除非你指定WType_TopLevel作为窗口部件标记)。
2. WFlags f = 0(在可用的情况下)设置窗口部件标记,默认设置对于几乎所有窗口部件都是适用的,但是,举例来说,一个没有窗口系统框架的顶级窗口部件,你必须使用特定的标记。
二、Top-Level 属性以及孩子构件
A widget without a parent widget is always an independent window (top-level widget). For these widgets, 一个没有父构件的构件通常是top-level 属性的窗口。对于这类构件,setWindowTitle() 和 setWindowIcon() 都是有效的。
三、QWidget事件简介
基本事件
* paintEvent() – 只要窗口部件需要被重绘就被调用。每个要显示输出的窗口部件必须实现它并且不在paintEvent()之外在屏幕上绘制是明智的。
* resizeEvent() – 当窗口部件被重新定义大小时被调用。
* mousePressEvent() – 当鼠标键被按下时被调用。有六个鼠标相关事件,但是鼠标按下和鼠标释放事件是到目前为止最重要的。当鼠标在窗口部件内或者当它使用grabMouse()来捕获鼠标时,它接收鼠标按下事件。
* mouseReleaseEvent() – 当鼠标键被释放时被调用。当窗口部件已经接收相应的鼠标按下事件时,它接收鼠标释放事件。这也就是说如果用户在你的窗口部件内按下鼠标,然后拖着鼠标到其它某个地方,然后释放,你的窗口部件接收这个释放事件。这里有一个例外:如果出现在弹出菜单中,当鼠标键被按下时,这个弹出菜单立即会偷掉这个鼠标事件。
* mouseDoubleClickEvent() – 和它看起来也许不太一样。如果用户双击,窗口部件接收一个鼠标按下事件(如果他们没有拿牢鼠标,也许会出现一个或两个鼠标移动事件)、一个鼠标释放事件并且最终是这个事件。直到你看到第二次点击是否到来之前,不能从一个双击中辨别一个点击。(这是为什么绝大多数图形用户界面图书建议双击是单击的一个扩展,而不是一个不同行为的触发的一个原因。)
如果你的窗口部件仅仅包含子窗口部件,你也许不需要实现任何一个事件处理器。如果你想检测在子窗口部件中的鼠标点击,请在父窗口部件的mousePressEvent()中调用子窗口部件的hasMouse()函数。
接收键盘的窗口部件需要重新实现一些更多的事件处理器:
* keyPressEvent() – 只要键被按下和当键已经被按下足够长的时间可以自动重复了就被调用。注意如果Tab和Shift+Tab键被用在焦点变换机制中,它们仅仅被传递给窗口部件。为了强迫那些键被你的窗口部件处理,你必须重新实现QWidget::event()。
* focusInEvent() – 当窗口部件获得键盘焦点(假设你已经调用setFocusPolicy())时被调用。写得好的窗口部件意味着它们能按照一种清晰但谨慎的方式来获得键盘焦点。
* focusOutEvent() – 当窗口部件失去键盘焦点时被调用。 一些窗口部件也许需要实现一些不太普通的事件处理器:
* mouseMoveEvent() – 只要当鼠标键被按下时鼠标移动就会被调用。举例来说,对于拖动,这个很有用。如果你调用setMouseTracking(TRUE),尽管没有鼠标键被按下,你也会获得鼠标移动事件。(注意这个使用鼠标跟踪的应用程序在低下的X连接下不是很有用。)(也可以参考拖放信息。)
* keyReleaseEvent() – 只要键被释放和当如果这个键是自动重复的并且被按下一段时间时就被调用。在这种情况下窗口部件接收一个键释放事件并且对于每一个重复立即有一个键按下事件。注意如果Tab和Shift+Tab键被用在焦点变换机制中,它们仅仅被传递给窗口部件。为了强迫那些键被你的窗口部件处理,你必须重新实现QWidget::event()。
* wheelEvent() — 当窗口部件拥有焦点时,只要用户转动鼠标滚轮就被调用。
* enterEvent() – 当鼠标进入这个窗口部件屏幕空间时被调用。(这不包括被这个窗口部件的子窗口部件所拥有的屏幕空间。)
* leaveEvent() – 当鼠标离开这个窗口部件的屏幕空间时被调用。
* moveEvent() – 当窗口部件相对于它的父窗口部件已经被移动时被调用。
* closeEvent() – 当用户关闭窗口部件时(或这当close()被调用时)被调用。
这里还有一些不太明显的事件。它们在qevent.h中被列出并且你需要重新实现event()来处理它们。event()的默认实现处理Tab和Shift+Tab(移动键盘焦点)并且其它绝大多数事件给上面提到的一个或更多的特定处理器。
四、Window flag标识
关于QWidget 的flag 的介绍:enum Qt::WindowType flags Qt::WindowFlags 这两个参数参阅官方文档。
Qt 的 WindowFlags 有很多,实际使用时,若不关心窗口层次的话,大可不比太关心这个。比如说在Window 上做应用开发,大可只关注:Qt::Dialog,Qt::Tool,Qt::Window 即可。但若是做嵌入式开发就得好好看看这个属性,整理好这部分属性,有利于窗口管理。
五、几个重要成员函数
bool QWidget::close () [slot]
关闭这个窗口部件。如果窗口部件被关闭,返回真,否则返回假。首先它发送给这个窗口部件一个QCloseEvent。如果它接收这个关闭事件,它就被隐藏了。QWidget::closeEvent()的默认实现是接收这个关闭事件。当最后一个可视的顶级窗口部件被关闭,QApplication::lastWindowClosed()信号被发射。
注意窗口的enum Qt::WidgetAttribute 属性,窗口默认属性是Qt::WA_MacOpaqueSizeGrip,设置上这个属性意味着窗口调用close()只销毁了UI,QWidget内还有很多内存空间没有释放,需调用delete 销毁QWidget 。若需要在调用close时一并销毁窗口可以给窗口设置Qt::WA_DeleteOnClose属性。
bool QWidget::event ( QEvent * e ) [虚保护]
这是主事件处理器,它处理事件e。你可以在子类中被重新实现整个函数,但是我们建议你使用一个特定的事件处理器来替代它。
主事件首先把事件传递给所有已经被安装的事件过滤器。如果没有过滤器中途截取这个事件,它调用一个特定的事件处理器。
键按下和释放事件被处理得和其它事件不同。event()检查Tab和Shift+Tab并且试图适当地移动焦点。如果没有窗口部件被焦点移入(或者键按下不是Tab或Shift+Tab),event()调用keyPressEvent()。
如果它能够把一个事件传递给某个东西,这个函数就返回真,否则如果没有任何东西想要这个事件,返回假。
也可以参考closeEvent()、focusInEvent()、focusOutEvent()、enterEvent()、keyPressEvent()、keyReleaseEvent()、leaveEvent()、mouseDoubleClickEvent()、mouseMoveEvent()、 mousePressEvent()、 mouseReleaseEvent()、moveEvent()、paintEvent()、resizeEvent()、QObject::event()和QObject::timerEvent()。
void QWidget::paintEvent ( QPaintEvent * ) [虚保护]
这个事件处理器可以在子类中被重新实现来接收绘制事件。
绘制事件就是重新绘制这个窗口部件的所有部分的一个请求。它可以是repaint()或update()的结果,或者因为这个窗口部件原来被变暗并且现在已经不再被覆盖了,或者其它很多原因。 很多窗口部件在当它们被请求时,它们很简单地重新绘制整个界面,但是一些比较慢的窗口部件需要通过仅仅绘制被请求的区域QPaintEvent::region()进行优化。这个速度优化不会改变结果,在事件处理过程中,绘制仅仅发生在被改变的区域中。例如,QListView和QCanvas就是这样做的。
Qt也试图通过把多个绘制事件合并为一个来加快绘制速度。当update()被调用几次或者窗口系统发送几次绘制事件,Qt把它们合并为一个比较大区域(请参考QRegion::unite())的一个事件中。repaint()不允许这样优化,所以只要可能我们建议使用update()。
当绘制事件发生,更新区域通常被擦除,所以你正在这个窗口部件的背景上绘制。这里有一些例外并且QPaintEvent::erased()告诉你这个窗口部件是否被擦除。
背景可以通过使用setBackgroundMode()、setPaletteBackgroundColor()或setBackgroundPixmap()来设置。setBackgroundMode()的文档详细描述了背景,我们建议你去读一下。
void QWidget::raise () [槽]
把这个窗口部件升高到它的父窗口部件的栈的顶部。
如果在屏幕上有与这个窗口部件重叠的兄弟,这个窗口部件将在它后来的这些兄弟之前变的可视了。
也可以参考lower()和stackUnder()。
void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [槽]
通过立即调用paintEvent()来直接重新绘制窗口部件,除非更新是失效的或者窗口部件被隐藏。
如果erase为真,Qt在paintEvent()调用之前擦除区域(x,y,w,h)。
如果w是负数,它被width()-x替换,并且如果h是负数,它被height()-y替换。
如果你需要立即重新绘制,我们建议使用repaint(),比如在动画期间。在绝大多数情况下,update()更好,因为它允许Qt来优化速度并且防止闪烁。
警告:如果你在一个函数中调用repaint(),而它自己又被paintEvent()调用,你也许会看到无线循环。update()函数从来不会产生循环。
也可以参考update()、paintEvent()、updatesEnabled和erase()。
QT中QWidget类简介的更多相关文章
- QT中QWidget、QDialog以及MainWindow的区别
参考 http://blog.csdn.net/u011619422/article/details/47311101 QT中QWidget.QDialog以及MainWindow的区别 QWidge ...
- PyQt(Python+Qt)入门:Designer组件属性编辑界面中QWidget类相关属性详解
本文适用人员:本文比较长,适合不理解Qt Designer部件属性的人员阅读或资料查找. 声明: 1.如果有人认为本文是简单的复制粘贴+翻译而成,敬请读本文最后的后记: 2.本文为老猿Python学习 ...
- QT中QWidget、QDialog QMainWindow
继承关系:在Qt中所有的类都有一个共同的基类QObject ,QWidget直接继承与QPaintDevice类,QDialog.QMainWindow.QFrame直接继承QWidget 类. QW ...
- 【转】QT中QWidget、QDialog及QMainWindow的区别
QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己.每一个窗口部件都是矩形的,并且它们按Z轴顺序排列.一个窗口部件 ...
- QT中QWidget、QDialog及QMainWindow的区别
本文转自http://www.cnblogs.com/aqxin/archive/2011/05/23/2054156.html QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基 ...
- qt——QT中QWidget、QDialog及QMainWindow的区别
QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己.每一个窗口部件都是矩形的,并且它们按Z轴顺序排列.一个窗口部件 ...
- (转)QT中QWidget、QDialog及QMainWindow的区别
QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己.每一个窗口部件都是矩形的,并且它们按Z轴顺序排列.一个窗口部件 ...
- <QT之Bug制造机>QT中串口类“QSerialPort”的学习笔记
QT5中已经增加了串口类QSrialPort,可以直接调用API函数进行快速开发. 1. 获取串口信息 Dialog::Dialog(QWidget *parent) : QDialog(parent ...
- Qt中QWidget、QDialog和QMainWindow
QWidget 类是所有用户界面对象的基类.只有一个"页面" QMainWindow 是一个"窗口".含有菜单栏.状态栏.工具栏.停靠窗口.中心窗口 QDial ...
随机推荐
- Google Maps 学习笔记(二)地图天气预报服务 2014.06.04
地图天气预报服务:一,获取天气预报信息:二,解析天气预报信息:三,在地图上加载天气预报信息: Yahoo!提供的天气预报服务采用流行的RSS输出结果,接口地址如下: http://weather.ya ...
- eclipse修改编译路径
右击项目--properties--java build path--点击source,修改最下方的路径即可
- 【Tomcat】使用Eclipse发布项目时,项目启动路径错误。
这种情况下,,通常会去C:\User\[USERNAME]\或者Tomcat路径下面的一个temp文件夹里面找项目文件,由此出现报错. 这时候解决方法为: 双击Eclipse的Servers里面的to ...
- Windows NTService 后台框架封装
对于后台运行的程序,比如基于C/S架构的服务器.各种监控系统的程序.或者是程序额外的功能需要后台运行来实现,在Windows平台中,服务经常会用到,这种对于需要24×7运行的程序是必备的,至少本人经常 ...
- [置顶] WebService调用工具(AXIS2)
package com.metarnet.util; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Meth ...
- js表格排序 & 去除字符串空格
// a:列数 bool:排序升序判断参数 true false Str:支持多列 function newUnitSort(a, bool, str) { var oTable = document ...
- java 实现 一个账号只能在一个地方登陆,其他地方被下线
其实方法有很多的,我这献丑了. 使用理解java 四大作用域. 思路:理解java 四大作用域的关键. 第一个地方登陆: 1.得到请求的SessionId 和 登陆的 用户名 2.把SessionId ...
- C#_C++_SDK_WM_KEYDOWN人物卡顿延迟解决方法
提问者采纳 由Keydown和keyup事件组合,keyDown来判定按下,此时开始移动,KeyUp判定松开,这样可行否? 追问 这是我一开始的写法,但就是因为 键盘重复延迟 导致keydown后会有 ...
- <转> Python的优雅技巧
枚举 不要这么做: 全选复制放进笔记 i = 0 for item in iterable: print i, item i += 1 而是这样: 全选复制放进笔记 for i, item in en ...
- Linux中fork()函数详解(转)
一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...