【PyQt】PyQt学习(三)QWidget介绍

概述

继承关系

QWidget 类是所有 Qt GUI 界面类的基类,是 PyQt 程序中的最小元素,也就是所有可现实的控件的基类。一个继承自 QWidget 的类可以在屏幕上绘制自身,这是因为 QWidget 继承了 QPaintDevice 类,该类用于将控件绘制在屏幕上。每一个可视控件都是矩形的且都按 Z 顺序排序,一个空间的显示会被自己的父类(指定的 parent)和其他控件进行阻挡。

未嵌入到窗口的可视控件称之为窗口,例如 QDialog 和 QMainWindow。

重要属性和功能

位置和大小

QWidget 类最重要的功能是提供了控件的显示,显示依赖于两个属性位置和大小,在 PyQt 框架中,控件坐标系统以左上角为原点,向右为 X 轴的正方向,向下为 Y 轴正方向建立。

每个控件都有一个边框,因此在高度、位置的设置和获取上,都有两种方式,即包含边框和不包含边框。

包含框架的位置获取方法:

  • x():获取相对于父控件的 X 位置(没有父控件则相对于桌面);
  • y():相对于父控件的 Y 位置(没有父控件则相对于桌面);
  • pos():x 和 y 的组合方法,返回QPoint对象。

不包含框架的位置获取方法:

  • geometry().x():获取相对于父控件的 X 位置;
  • geometry().y():获取相对于父控件的 Y 位置;
  • geometry():获取用户区域相对于父控件的位置和尺寸。

包含框架的大小获取方法:

  • frameGeometry().width():获取控件的宽度;
  • frameGeometry().height():获取控件的高度;
  • frameGeometry():获取控件尺寸。

不包含框架的大小获取方法:

  • width():获取控件的宽度;
  • height():获取控件的高度;
  • rect():获取控件宽高。

设置位置和大小

  • resize():设置控件的大小(不包含边框);
  • move():移动控件(包括框架);
  • setFixedSize():设置控件固定尺寸。

除了直接给定控件大小,还可以设置大小的上下限,相关方法介绍如下:

  • minimumwidth():获取最小宽度;
  • minimumheight():获取最小高度;
  • minimumsize():上面两个方法的结合;
  • maxmumwidth():获取最小宽度;
  • maxmumheight():获取最小高度;
  • maxmumsize():上面两个方法的结合方法。

控件层级

没有父窗口小部件的窗口小部件始终是一个独立窗口,对于这些控件,可以调用 setWindowTitle()setWindowIcon() 设置标题栏和图标。QWidget 类本身提供了这些方法,但是如果不是顶级控件,调用这些方法会失效。如下图所示,QGroupBox是父控件,其余的 QLabelQDateEdit 等控件都受它的管理。

父子控件

子控件的生命周期和父控件一致,在创建任何一个控件的时候传递一个 QWidget 子类实例作为新创建的控件的父控件。例如 self.widget_2 = QtWidgets.QWidget(self.centralwidget),在 QWidget 类中提供了几个方法用于管理父子关系

  • childAt():获取在指定坐标位置的子控件;
  • parentWidget():获取指定控件的父控件;
  • childreanRect():获取所有子控件组成的边界矩形。

除了这种父子的层级关系,控件之间在 Z 轴上还有一种层级关系,QWidget 提供了一些方法用来管理这种关系:

  • lower():将控件放到最底层;
  • raise():将控件放到最上层;
  • a.stackunder(b):将 a 控件放到指定控件 b 之下。

绘制自定义控件

由于 QWidgetQPaintDevice 的子类,因此子类可使用 QPainter 类的实例使用一系列绘画操作,所以如果想要创建自己的控件,最好继承自 QWidget 类。

每一个控件都有一个 paintEvent() 方法,在这个函数中执行所有的绘制操作,每当需要重绘控件的时候都会调用该方法。一般的处理方案如下:

def paintEvent(self, a0: QPaintEvent) -> None:  
    ... # 自定义操作
    super(MainWindow, self).paintEvent(a0)

控件尺寸

除了直接指定大小、最大、最小长宽之外,QWidget 还提供了尺寸策略,这个主要用于在布局情况下,多个子控件之间的大小调整,尺寸策略的可选值如下:

大小策略

默认情况下,顶级控件的大小被限制为桌面高度和宽度的 \frac{2}{3}

事件

在 PyQt 中控件和用户的交互一般通过事件,有一个消息队列不断接收程序产生的事件信息,并将其包装为QEvent对象进行分发处理。针对不同类型的QEvent对象,每个控件都有对应的处理函数,比方说 moveEvent() 用于处理窗口移动事件;enterEvent() 用于处理鼠标光标进入事件。

焦点和交互

控制状态就是获取焦点的状态,一个控件只有获取了焦点的控件才能进行交互,针对焦点,QWidget 提供了如下函数进行管理;

  • setFocus():指定控件获取焦点;
  • setFocusPolicy():设置获取焦点的策略;
  • focuswidget():获得子控件中当前聚焦的控件;
  • focusNextChild():聚焦下一个子控件;
  • setTabOrder():设置子控件获取焦点的顺序。

针对交互,QWdiget 也提供了相应的方法:

  • setEnabled():指定控件是否可用;
  • isEnabled():返回控件是否可用;
  • isvisible():代表了控件的最终状态,即使被其他控件遮挡也算看的见;
  • isHidden():代表该控件是否对父控件可见。

功能总结

Context Functions and Properties
窗口函数 show() , hide() , raise() , lower() , close() .
顶级窗口函数 windowModified , windowTitle , windowIcon , isActiveWindow , activateWindow() , minimized , showMinimized() , maximized , showMaximized() , fullScreen , showFullScreen() , showNormal() .
窗口内容 update() , repaint() , scroll() .
位置 pos , x() , y() , rect , size , width() , height() , move() , resize() , sizePolicy , sizeHint() , minimumSizeHint() , updateGeometry() , layout() , frameGeometry , geometry , childrenRect , childrenRegion , adjustSize() , mapFromGlobal() , mapToGlobal() , mapFromParent() , mapToParent() , maximumSize , minimumSize , sizeIncrement , baseSize , setFixedSize()
模式 visible , isVisibleTo() , enabled , isEnabledTo() , modal , isWindow() , mouseTracking , updatesEnabled , visibleRegion() .
外观 style() , setStyle() , styleSheet , cursor , font , palette , backgroundRole() , setBackgroundRole() , fontInfo() , fontMetrics() .
键盘和焦点 focus , focusPolicy , setFocus() , clearFocus() , setTabOrder() , setFocusProxy() , focusNextChild() , focusPreviousChild() .
鼠标和键盘 grabMouse() , releaseMouse() , grabKeyboard() , releaseKeyboard() , mouseGrabber() , keyboardGrabber() .
事件处理 event() , mousePressEvent() , mouseReleaseEvent() , mouseDoubleClickEvent() , mouseMoveEvent() , keyPressEvent() , keyReleaseEvent() , focusInEvent() , focusOutEvent() , wheelEvent() , enterEvent() , leaveEvent() , paintEvent() , moveEvent() , resizeEvent() , closeEvent() , dragEnterEvent() , dragMoveEvent() , dragLeaveEvent() , dropEvent() , childEvent() , showEvent() , hideEvent() , customEvent() . changeEvent() ,
系统函数 parentWidget() , window() , setParent() , winId() , find() , metric() .
菜单 contextMenuPolicy , contextMenuEvent() , customContextMenuRequested() , actions()
交互提示 setToolTip() , setWhatsThis()

往期回顾

  1. 【PyQt】PyQt学习(二)模块介绍+QObject学习
  2. 【PyQt】PyQt学习(一)

文中难免会出现一些描述不当之处(尽管我已反复检查多次),欢迎在留言区指正,相关的知识点也可进行分享,希望大家都能有所收获!!如果觉得我的文章写得还行,不妨支持一下。你的每一个转发、关注、点赞、评论都是对我最大的支持!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容