QWidget

QWidget

最近在学习Qt,每次阅读官方英文API都只读取自己需要的一部分,但是面对庞大的英文,老是觉得获取信息像大海捞针一样困难。于是我决定从头到尾好好读一读英文介绍,然后根据自己的理解,把它翻译为中文,一方面可以增加自己的理解能力,同时也方便英文和我一样不好的同学,我会尽量按照原文来翻译,如果其中某些语句让你觉得有些晦涩甚至难以理解时,可以直接转到原版进行阅读,或者您觉得有更好的表述方法,都可以告诉我,我会改正,提高翻译质量。如果有一些错误,还请大家批评指正。

注:这里的widget我们可以理解为子窗口,window可以理解独立的窗口。

QWidget类是所有的用户接口对象的基类

  • widget是用户界面最基本的组成部分:它接收来自于windows系统的鼠标、键盘以及其他事件,然后将它自己绘制在屏幕上。每一个widget都是矩形形状,以Z-order顺序排列。一个widget会被它的父窗口或者在它前面的widgets所截断。
  • 如果一个widget没有被嵌入到另外一个widget中,那么这个widget就叫做window,即一个独立的窗口。尽管我们可以通过设置window flags创建一个没有任何修饰的window,但是通常情况下,一个window都有一个边框和一些菜单栏等。在Qt中,QMainWindow以及QDialog的子类都是最为常见的window类型。

一个widget的构造函数可以接受一个或者两个标准参数:

  • QWidget *parent = 0 ,为新创建的widget指定其父widget。如果parent为0(默认值),那么这个新widget就会变成一个独立的window。如果parent不为0,那么新创建的widget是parent的一个子窗口,但是此时我们新创建的widget的形状会受其父窗口形状的约束。(除非你指定这个新创建的widget的window flag为Qt::Window
  • Qt::WindowFlags f = 0,这个参数用来设置新创建的widget的window flags(例如是否有最大化按钮等)。默认的参数几乎对所有的widget都是适用的。但是如果你需要一个没有边框的widget,你必须使用特定的flag。

Tips: QWidget有很多成员函数,但是有一些成员函数并不会被使用。例如,QWidget有font(字体)属性,但是基本上不会调用这个函数。

顶级widget和子widget

  • 一个没有父widget的widget是一个独立的window,即是一个顶级widget。对于这些widget,setWindowTitle()函数和setWindowIcon()分别设置窗口的标题和图标。
  • 非window类型的widget是子widget,在父widget中显示。Qt中的大多数widget主要是作为子widget。例如,我们可以把一个按钮作为一个顶级窗口,但是大多数人倾向于把他们的按钮放在widget里面,例如把按钮放在QDialog(对话框类)中。

  • 上图中展示了把一个QGroupBox作为widget来容纳QGridLayout中的各种各样的子widget。QLabel被设置为自适应大小
  • 如果你想用一个QWidget来容纳子widget,通常情况下你应该给父QWidget添加一个layout(布局)。更多信息参见Layout Management

复合型Widget

  • 如果要把一个widget作为一个容器来存放一组子widget,这个widget就称之为复合型widget。可以通过构造一个带有可视属性的widget-一个QFrame来实现。例如,通常我们通过该widget的layout(布局)来添加一个子widget。上图中的

    widget便是通过Qt Designer创建的。

  • 复合型的widget也可以是标准widget的一个子类,例如QWidget或者QFrame,然后在这个子类中添加必要的layout(布局)和子widget。Qt中的许多例子以及教程中的例子中的复合型widget都是使用该方法创建的。

自定义widget和绘制方式

  • 因为QWidget是QPaintDevice的一个子类,因此QWidget可以通过实例化一个QPainter的对象,然后使用一系列的绘制方式来显示自定义的内容。该方法与Graphics View Framework(我猜指的是通过拖拽控件来制作一个特定窗口的方法)的canvas-style approach(画布风格方法)完全不同。在Graphics View Framework中,每一个被应用程序添加的控件都由framework自身来渲染。
  • 每一个widget的绘制操作都由自己的paintEvent()来执行。无论何时,只要有一些变化发生或者是应程序的要求而导致这个widget需要被重新绘制时,就会调用这个函数。
  • 这个模拟时钟的例子展示了一个简单的窗口是如何处理绘制事件的。

Size Hints 和Size Policies

  • 当实例化了一个新的widget的时候,重载SizeHint()函数使得窗口有一个合理的默认大小,重载setSizePolicy()使得该窗口有正确的大小策略,这两个方法都是非常有用的。
  • size policy使得layout management system(布局管理系统)拥有良好的默认大小变化管理依据。这使得其他的widget更加容易管理和容纳你的widget。默认的size policy表示widget的大小可以自由变化,一般倾向于采用sizeHint()返回的大小,这对大多数的widget来说已经足够好了。
  • 顶级widget的大小一般约束为桌面大小长度和宽度的的2/3,但我们也可以通过resize()函数来手动改变大小。

Events(事件)

  • 用户的行为引起了widget对事件的响应。Qt通过实例化QEvent的子类的一个对象,该对象包括每个事件的相关信息,然后通过调用对应的事件处理函数将事件传送给widget。
  • 如果你的widget中只有些许widget,你很有可能不需要实现事件处理函数。如果你想在一个子widget中捕捉鼠标点击事件,只需要在这个子widget中的mousePressEvent()中调用underMouse()函数即可。
  • Scribble实现了更多的有关于鼠标移动、按钮点击和窗口重设大小的事件处理过程。
  • 你需要给自己的widget添加一些行为和内容,如下是一些简单的和QWidget有关的事件概览,我们从最常见的说起:

    paintEvent(),只要widget需要重新绘制就会被调用。每一个自定义的widget都需要实现这个函数。使用QPainter进行绘制只能发生在一个PaintEvent()中,或者是以paintEvent()的形式调用它。

    resizeEvent(),当widget大小被重新设置的时候就会被调用

    mouseDoubleClickEvent() ,当用户在widget中双击鼠标就会被调用。如果用户双击,widget会收到一个mouse press 事件,一个 mouse release 事件,(一个mouse click 事件)和另外一个mouse press 事件,一个 mouseDoubleclick 事件,和一个mouse release 事件。如果在双击过程中发生了鼠标抖动,就会收到一个mouse move 事件。在没有收到第二次点击鼠标的事件前是不可能区分鼠标单击事件和鼠标双击事件的。(这就是为什么大多数GUI书推荐把双击事件作为单击事件的一个扩展而不是定义为另外一个不同的操作)

  • 如果widget接受键盘输入,则需要实现一些其他的事件处理函数:

    keyPressEvent(),用户按下一个键时就会被调用,如果长按一个键,这个函数会被重复调用。如果焦点变化机制没有使用TabShift+Tab键,那么这两个键仅仅会传递给Widget。如果要强行使你的widget处理这两个键的信息,则需要实现QWidget::event()

    focusInEvent(),如果widget获得键盘焦点,该函数就会被调用。(假定你提前调用了setFocusPolicy()函数),功能良好的widget意味着它们会以明确的方式获得焦点。

    focusOutEvent(),widget失去焦点时该函数就会被调用。

  • 也许你还需要实现一些不太常见的事件处理函数:

    mouseMoveEvent(),当你按下鼠标,并且移动的时候该函数会被调用。在拖拽操作中这个函数非常有用。如果你调用了setMouseTracking(true),那么即使鼠标没有被按下,但是只要鼠标在移动,这个函数就会被调用。(见 Drag and Drop板块)

    keyReleaseEvent(),一个按键被松开时,或者持续按住一个键(这个键必须是自动重复的)时该函数就会被调用。如果是第二种情况,那么widget会在按键每次重复时收到一对key release和key press事件。如果焦点变化机制没有使用TabShift+Tab键,那么这两个键仅仅会传递给Widget。如果要强行使你的widget处理这两个键的信息,则需要实现QWidget::event()

    wheelEvent(),鼠标滑轮滚动时该函数被调用

    enterEvent(),鼠标进入该widget所在屏幕区域时被调用(该widget的屏幕区域不包括其子widget的屏幕区域

    leaveEvent(),鼠标离开widget所在屏幕区域时被调用,但是如果鼠标进入了子widget屏幕区域时该函数不会被调用

    moveEvent(),widget相对于其父widget被移动时调用该函数

    closeEvent(),用户关闭widget时或者调用close()函数时该函数被调用

  • 还有一些鲜为人知的事件,详见QEvent::Type,如果要处理这些事件,你还需要亲自实现event
  • 默认的event会处理Tab和Shift+Tab键(用来改变键盘焦点),同时也会传递上述的一个或者多个事件。但不包括所说的那些鲜为人知的事件,这就是为什么你需要自己亲自实现event的原因了。

to be continue……

时间: 2024-11-06 23:02:02

QWidget的相关文章

QWidget的六个刷新函数(居然有QWidget::erase函数,且并不产生绘制事件)

Qt paintevent事件 一.主要理解一下几个方法和属性: 1.QWidget * QScrollView::viewport () const 2.void QWidget::paintEvent ( QPaintEvent * ) [虚 保护] 3.void QWidget::repaint ( int x, int y, int w, int h, bool erase = TRUE ) [槽] 4.void QWidget::update () [槽] 5.void QWidget

QDialog QMainwindow QWidget QFrame不同时候用法.

继承关系:在Qt中所有的类都有一个共同的基类QObject ,QWidget直接继承与QPaintDevice类,QDialog.QMainWindow.QFrame直接继承QWidget 类. QWidget类是所有用户界面对象的基类.窗口部件(QWidget)是用户界面的一个基本单元:它从窗口系统接收鼠标,键盘和其他事件,并且在屏幕上绘制自己.每个窗口部件都是矩形的,并且它们按Z轴顺时针排列.一个窗口部件可以把他的父窗口部件或者它前面的窗口部件盖住一部分. QMainWindow 类提供一个

QWidget类中默认是忽略inputMethodEvent事件(要获取输入的内容就必须使用这个事件)

因为项目的需要以及主管的要求,准备将工程移植到Qt中,这样就可以比较容易的实现跨平台了.因为之前工程是在windows下开发的,第一个平台又是mobile所以除了底层框架之外其他的都是使用的windows的API以及编程模式,现在要移植到Qt中,第一个要面临的问题就是如何将windows的消息机制很好的转换为Qt中的处理机制.windows中是消息,Qt中是事件和信号.槽,其实原理都是一样的. 1.常用事件 因为所有和界面相关的类都是继承自QWidget类,所以QWidget类有的时间和方法,在

QTabWiget Change Color 改变颜色(每个QWidget都有一个自己的调色板palette,设置它的颜色,然后setAutoFillBackground即可)

Qt中的QTabWiget 类提供了一个便签控件,但是这个控件默认初始化的颜色是白色,和原窗口的颜色不同,看起来非常的违和,所以我们希望将其的背景颜色设为当前窗口的背景颜色.我们所要做的就是先将应用程序窗口的背景颜色取出来,然后再赋给QTabWiget 类的每个标签,比如说我们有tab1和tab2两个标签,要改变其背景颜色可用如下代码: ui.tab1->setPalette(QWidget::palette().color(this->backgroundRole())); ui.tab1-

Qt中各个widget前后位置的设定(在Qt中,所有问题都要一分为二,QWidget体系和QGraphicsWidget体系)

这两天在总结一些以往project中遇到的问题,正好别组有同事问我关于Qt中各个widget窗口的前后位置是如何定义的,这里就总结一下: 在Qt中,所有问题都要一分为二,讨论两种不同的情况:一个是最常用的QWidget体系,而另外一个则是QGraphicsWidget体系. ①:在常用的QWidget体系中,设置前后位置是主要是用raise(),underStack(),hide()函数. 理论为:在Qt中每个widget窗口都维持着自己的一个创建栈(widget's stack.),栈里边存放

QWidget与HWND的互相转换

QWidget与HWND的互相转换 在编写Windows的应用程序时,我们有时不可避免地要与Windows平台固有的Win32 API打交道,但是Win32 API里面常常用到的HWND等诸多句柄QT并没有.QT作为一款优秀的跨平台GUI库,不可能未作考虑,那么需要互相转换的时候该如何做呢? HWND转QWidget 1 2 3 QWidget *myWidget; HWND hwnd; myWidget=QWidget::find(hwnd);   QWidget转HWND 1 2 3 QWi

PyQt5在QWidget窗体中显示Qwidget的自定义类

[概览] 1.显示原生Qwidget 1)不使用布局(绝对定位) 2)使用布局 2.显示Qwidget的自定义类 1)不使用布局(绝对定位)       2)使用布局 [知识点] 1.显示原生Qwidget 1)不使用布局(绝对定位) 这种情况下,原生QWidget部件在实例化时必须带parent参数,当然parent = self,即:  self.widget = QWidget(self) 1 class MyWindow(QWidget): 2 def __init__(self, pa

Qt: QWidget、QMainWindow、QDialog和QFrame的区别

继承关系: 在Qt中所有的类都有一个共同的基类QObject ,QWidget直接继承与QPaintDevice类,QDialog.QMainWindow.QFrame直接继承QWidget 类. QWidget: QWidget类是所有用户界面对象的基类.窗口部件(QWidget)是用户界面的一个基本单元:它从窗口系统接收鼠标,键盘和其他事件,并且在屏幕上绘制自己.每个窗口部件都是矩形的,并且它们按Z轴顺时针排列.一个窗口部件可以把他的父窗口部件或者它前面的窗口部件盖住一部分. QMainWi

setCentralWidget就可以把Qwidget设置为QMainWindow的主窗口

前面说的return app.exec() 这句话是用来使程序进入事件循环,除了直接递交的事件外,所有的事件都要在这个循环中被一层一层的分发,最后找到相应的处理函数来处理事件. 顶级窗口和顶级窗口是存在两个不同的事件循环中的,比如说QMainWindow和QWidget,想让一个顶级窗口中的事件能够在另外一个顶级窗口中响应,必须把两个顶级窗口合并,比如setCentralWidget就可以把Qwidget设置为QMainWindow的主窗口. http://blog.csdn.net/ftwor

Qt中事件处理的方法(三种处理方法,四种覆盖event函数,notify函数,event过滤,事件处理器。然后继续传递给父窗口。可观察QWidget::event的源码,它是虚拟保护函数,可改写)

一.Qt中事件处理的方式 1.事件处理模式一 首先是事件源产生事件,最后是事件处理器对这些事件进行处理.然而也许大家会问, Qt中有这么多类的事件,我们怎么样比较简便的处理每个事件呢?设想,如果是每个事件都对应同一个事件处理器,在该事件处理器中对不同的事件进行分类处理,这样的弊端有两点:第一,导致该事件处理器过于臃肿复杂:第二,这样不便于扩展,当系统新增加事件类型或者是我们需要使用到自定义事件时,就不得不修改Qt的源码来达到目的.所以Qt设计者的做法是针对不同类型的事件提供不同的事件处理器与之对