Qt扫盲-QWidget理论使用总结

QWidget理论使用总结

  • 一、概述
  • 二、顶层 控件 和子 控件
  • 三、复合控件
  • 四、自定义控件和绘制
  • 五、大小提示和大小策略
  • 六、事件
  • 七、一组函数和属性
  • 八、QWidget样式表
  • 九、透明度和双缓冲
  • 十、创建半透明窗口

一、概述

widget 是用户界面的最小单位:它从window系统接收鼠标、键盘和其他事件,并在屏幕上显示自己。每个组件都是矩形的,并且按z轴顺序排列(就是窗口在屏幕里面层次的位置)。一个 控件 会被它的父 控件 和它前面的 控件 剪切。(其实就是被遮挡的意思)。

QWidget 是Qt里面其他控件的公共基类。

没有嵌入到父窗口中的控件称为窗口。通常,窗口有一个边框和一个标题栏,不过也可以使用适当的窗口标志创建没有这两个装饰的窗口)。在Qt中,QMainWindow 和 QDialog 的各种子类是最常见的窗口类型。

每个 控件 的构造函数都接受一到两个标准参数:

QWidget *parent = nullptr
  • QWidget *parent = nullptr 是新widget的父组件。如果它是nullptr(默认值),新 控件 将是一个窗口。如果不是,它将是parent的子元素,并受其父元素几何形状的限制(除非指定Qt::Window作为窗口标志)。
Qt::WindowFlags f = 0 
  • Qt::WindowFlags f = 0 (在可用的地方)设置窗口标志;默认值适用于几乎所有窗口组件,但如果要获得一个没有窗口系统框架的窗口,则必须使用特殊的标志。

QWidget有许多成员函数,但其中一些几乎没有直接功能;例如,QWidget有一个font属性,但它自己从不使用它,因为他也作为其他窗口的基类。其子类才提供了真正的功能,例如QLabel、QPushButton、QListWidget和QTabWidget等。

二、顶层 控件 和子 控件

没有父窗口的窗口始终是一个独立窗口(顶级窗口组件)。对于这些窗口组件,setWindowTitle() 和 setWindowIcon() 分别设置标题栏和图标。就像下图就能看出来是什么意思,设置窗口的图标和标题栏。

在这里插入图片描述

非窗口 控件 是子控件 ,显示在它们的父 控件 中。Qt中的大多数控件主要作为子控件使用。例如,可以将按钮显示为顶层窗口,但大多数人更喜欢将按钮放在其他 控件 中,如QDialog。
在这里插入图片描述

上图显示了一个QGroupBox小 控件 用于在QGridLayout提供的布局中保存各种子小 控件 。QLabel子 控件 已被概述以表明其完整尺寸。

三、复合控件

当一个小 控件 被用作一个 容器 来分组许多子小 控件 时,它被称为复合小 控件 。因为QWidget可以做容器来承载控件的。这些可以通过构建具有所需视觉属性的窗口组件(例如QFrame,QGroupBox)来创建,并向其中添加子窗口组件,通常通过布局来管理。上图使用的QGroupBox 了一个使用Qt Designer创建的复合组件。其实就是说用类似 QWidget 或者 QFrame 来作为其他控件的承载控件。其实可以理解为由父控件和子控件构成一起的控件可看成复合控件。

还可以通过继承标准窗口小 控件 (如QWidget或QFrame)并在子类的构造函数中添加必要的布局和子窗口小 控件 来创建复合窗口小 控件 。Qt提供的许多示例都使用这种方法,Qt教程中也介绍了这种方法。

四、自定义控件和绘制

由于QWidget是QPaintDevice的子类,可以使用子类来显示使用一系列绘制操作和QPainter类的实例组成的自定义内容。绘制就是自定义控件的一大利器,我们可以用绘制的方式绘制控件的外观,交互的话就可以用 鼠标事件或者在自定义控件里面添加对应的响应控件也可以响应,绘制主要是影响的外观。绘制的话也是绘制的背景,不会影响这个 QWidget内部的子控件。

这种方法与 Graphics View Framework 使用的canvas风格的方法不同,后者是由应用程序将项目添加到场景中,然后由框架自身渲染。

每个 控件 都在其 paintEvent() 函数中执行所有绘制操作。 每当控件需要重绘时,无论是由于某些外部更改还是应用程序请求重绘时,都会调用这个方法。我们需要做的就是重写这个函数就可以啦,就行下面的时钟例子,就用的绘制方式。

在这里插入图片描述

更为酷炫的,像这种的也是通过绘制的方式来制作的。
在这里插入图片描述

五、大小提示和大小策略

在实现新窗口组件时,几乎总是需要重新实现 sizeHint(),为窗口组件提供一个合理的默认大小,并使用 setSizePolicy() 设置正确的大小策略。

默认情况下,没有提供大小提示的复合 控件 将根据其子 控件 的空间需求进行调整。

size策略允许你为布局管理系统提供良好的默认行为,以便其他 控件 可以轻松地包含和管理你的 控件 。默认大小策略表明size提示表示窗口组件的首选大小,这对于许多窗口组件来说通常已经足够了。

注意:顶级 控件 的大小被限制为桌面高度和宽度的2/3。如果这些边界不够用,可以手动 resize() 控件 。

六、事件

QWidget 的 事件也是非常重要的,Qt的窗口相关事件系统基本上体现在 QWidget 的 基础函数里面,这些函数都可以让我们自己重写,然后扩展功能。

控件 响应通常由用户操作引起的事件。Qt通过调用特定的事件处理程序函数和包含每个事件信息的QEvent子类实例来向 控件 传递事件。

如果控件只包含子 控件 ,则可能不需要实现任何事件处理程序。如果要检测子 控件 中的鼠标点击,则在控件的mousePressEvent() 中调用子控件的 underMouse() 函数。
Scribble示例实现了一组更广泛的事件来处理鼠标移动、按钮按下和窗口大小调整。

您需要为自己的控件提供行为和内容,但下面是与QWidget相关的事件的简要概述,从最常见的开始:

事件名功能
paintEvent()每当控件需要重绘时,都会调用这个函数,每个显示自定义内容的小控件都必须实现它。使用QPainter进行绘制只能在paintEvent()或由paintEvent()调用的函数中进行。
resizeEvent()resizeEvent() 在控件被调整大小后被调用。
mousePressEvent()当鼠标指针在控件内部按下鼠标按钮,或者控件使用grabMouse()抓取鼠标时,会调用mousePressEvent()。在不松开鼠标的情况下按下鼠标,实际上与调用grabMouse()是一样的。
mouseReleaseEvent()mouseReleaseEvent() 在鼠标按键松开时调用。当widget接收到相应的鼠标按下事件时,它会接收鼠标释放事件。这意味着,如果用户在widget内按下鼠标,然后在释放鼠标按钮之前将鼠标拖动到其他地方,则widget将接收release事件。但有一个例外:如果鼠标按钮按下时出现一个弹出菜单,这个弹出菜单会立即窃取鼠标事件。
mouseDoubleClickEvent()mouseDoubleClickEvent() 在用户双击widget时被调用。如果用户双击,widget会接收到一个鼠标按压事件、一个鼠标释放事件、(一个鼠标点击事件) 、第二个鼠标按下事件、这个事件以及最后一个鼠标释放事件。(如果在操作过程中鼠标没有保持稳定,也可能会接收到一些鼠标移动事件。) 在第二次点击到来之前,无法区分是点击还是双击。(这就是为什么大多数GUI书籍建议双击是单击的扩展,而不是触发另一个动作的原因之一。)

接受键盘输入的控件需要重新实现以下几个事件处理程序。

事件名功能
keyPressEvent()每当按键被按下时,都会调用keyPressEvent()方法,当按键按下时间长到自动重复时,也会调用keyPressEvent()方法。只有当Tab和Shift+Tab键不被焦点改变机制使用时,它们才会被传递给widget。要强制小控件处理这些键,必须重新实现QWidget::event()。
focusInEvent()focusInEvent()在小控件获得键盘焦点时被调用(假设您已经调用了setFocusPolicy())。表现良好的控件以一种清晰而谨慎的方式表明它们拥有键盘焦点。
focusOutEvent()focusOutEvent()在小控件失去键盘焦点时被调用。

你可能还需要重新实现一些不太常见的事件处理程序:

事件名功能
mouseMoveEvent()mouseMoveEvent()会在鼠标移动而鼠标按钮按住不放时调用。这在拖放操作中很有用。如果调用setMouseTracking(true),即使没有按下任何按钮,也会得到鼠标移动事件。(参见拖放参考线。)
keyReleaseEvent()keyReleaseEvent()方法会在按键被释放时以及按键被按下时(如果按键是自动重复的)被调用。在这种情况下,widget将在每次重复时收到一对按键释放和按键按下事件。只有当Tab和Shift+Tab键不被焦点改变机制使用时,它们才会被传递给widget。要强制小控件处理这些键,必须重新实现QWidget::event()。
wheelEvent()每当用户在widget获得焦点时转动鼠标滚轮时,都会调用wheelEvent()。
enterEvent()enterEvent()在鼠标进入控件的屏幕空间时被调用。(这不包括组件的任何子组件拥有的屏幕空间。)
leaveEvent()当鼠标离开控件的屏幕空间时,会调用leaveEvent()。如果鼠标进入一个子控件,它不会导致leaveEvent()。
moveEvent()enterEvent()会在控件相对于其父控件被移动时调用。
closeEvent()closeEvent()在用户关闭控件时(或调用close()时)被调用。

在QEvent::Type的文档中还描述了一些相当模糊的事件。要处理这些事件,需要直接重新实现event()。

event()的默认实现处理Tab和Shift+Tab(移动键盘焦点),并将大多数其他事件传递给上面更专门的处理程序之一。

七、一组函数和属性

功能相关相关函数
窗口功能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()
  • 窗口功能
    其实就是 控制窗口的 显示隐藏,关闭,以及窗口在屏幕里面的 Z-index 上移、下沉。
  • 顶层窗口
    控制窗口最大,最小化,全屏,激活、设置窗口图标或者标题等
  • 窗口内容
    窗口内容的刷新,重新绘制,滚动等等。
  • 窗口几何
    窗口的长宽大小、坐标位置等信息
  • 模式
    窗口的显示、隐藏、使能等
  • 观感
    窗口的样式,外观,字体、颜色等等
  • 键盘焦点功能
    就是输入的 焦点管理
  • 系统功能
    获取窗口的句柄,与Windows交互要多些

八、QWidget样式表

除了每个平台的标准窗口样式外,还可以根据样式表中指定的规则设置窗口小部件的样式。此功能使我们能够自定义特定部件的外观,以向用户提供有关其用途的视觉提示。例如,可以为一个按钮设置特定的样式,以表明它执行了破坏性操作。Qt提供的就是 QSS 样式表。

QSS 其实是Qt样式表,就是一种美化界面的方式。Qt样式表是Qt界面的一种强大的机制,可以让我们自定义窗口组件的外观。Qt样式表的概念、术语和语法很大程度上受到HTML层叠样式表(CSS)的启发。功能和CSS的基本一样,大家应该也是有CSS 的基本基础,那写QSS就很容易的。下面就是我对QSS的相关笔记

✔️ Qt扫盲-QSS概述 🏤
✔️ Qt扫盲-QSS语法概述 ♻️
✔️ Qt Designer配置QSS交互使用 ✈️
✔️ Qt扫盲-QSS定制Qt Widget控件 🌟
✔️ Qt扫盲-QSS帮助手册使用 ✨
✔️ Qt扫盲-QSS示例代码 🌵

九、透明度和双缓冲

自Qt 4.0以来,QWidget自动对其绘制进行双缓冲,因此不需要在paintEvent()中编写双缓冲代码以避免闪烁。

从Qt 4.1开始,Qt::WA_ContentsPropagated部 件属性已经被弃用。相反,只要没有设置Qt::WA_PaintOnScreen,父部件的内容就会默认传播到每个子部件。

我们可以编写自定义部件来利用这一特性,方法是更新不规则区域(以创建非矩形的子部件),或者使用小于完整alpha的组件绘制颜色。下图显示了如何微调自定义小部件的属性和属性以实现不同的效果。
在这里插入图片描述

在上图中,构建了一个移除区域的半透明矩形子部件,并将其添加到父部件(显示pixmap的QLabel)。然后,设置不同的属性和widget属性来实现不同的效果:

  • 左边的小部件没有其他属性或设置小部件属性。这个默认状态适合大多数使用透明度、形状不规则或者不使用不透明的画笔覆盖整个区域的自定义部件。
  • 中心部件设置了autoFillBackground属性。此属性与依赖widget提供默认背景的自定义部件一起使用,这些部件不会用不透明的画笔绘制整个区域。
  • 右边的部件设置了Qt::WA_OpaquePaintEvent部件属性。这表示部件将用不透明的颜色覆盖整个区域。小部件的区域最初是未初始化的,在图中以红色对角网格模式表示,该模式穿过覆盖的区域。WA_OpaquePaintArea属性对于需要快速绘制自己的专门化内容且不需要默认填充背景的部件非常有用。

要用简单的背景颜色快速更新自定义窗口组件,如实时绘图或绘图窗口组件,最好定义一个合适的背景颜色(使用带有QPalette::Window 的 setBackgroundRole()),设置 autoFillBackground 属性,并仅在窗口组件的 paintEvent() 中实现必要的绘图功能。

为了快速更新不断用不透明内容覆盖整个区域的自定义窗口组件(例如视频流窗口组件),最好设置窗口组件的Qt::WA_OpaquePaintEvent,避免与重绘窗口组件背景相关的任何不必要的开销。

如果窗口组件同时设置了Qt::WA_OpaquePaintEvent属性和autoFillBackground属性,则Qt::WA_OpaquePaintEvent属性优先。根据您的需求,您可以选择其中任何一个。

从Qt 4.1开始,父组件的内容也会传播到标准Qt组件。如果父部件以非标准的方式装饰,这可能会导致一些意想不到的结果,如下图所示。
在这里插入图片描述

在不借助于子类的情况下,定制标准Qt窗口组件的绘制行为的范围比定制窗口组件的范围要小一些。通常,标准窗口组件的期望外观可以通过设置其 autoFillBackground 属性来实现。

十、创建半透明窗口

从Qt 4.5开始,可以在支持合成的窗口系统上创建具有半透明区域的窗口。

要在顶级部件中启用此功能,请使用 setAttribute() 设置其Qt::WA_TranslucentBackground属性,并确保其背景在希望部分透明的区域中使用非不透明颜色绘制。
平台注意事项:

  • X11:此功能依赖于支持ARGB视觉效果的X服务器和合成窗口管理器的使用。
  • Window:窗口组件需要设置 Qt::FramelessWindowHint 窗 口标志,才能使半透明工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/91204.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity游戏源码分享-精品即时战略游戏_官网60美刀素材

Unity游戏源码分享-精品即时战略游戏_官网60美刀素材 下载地址:https://download.csdn.net/download/Highning0007/88204017

Jmeter-压测时接口按照顺序执行-临界部分控制器

文章目录 临界部分控制器存在问题 临界部分控制器 在进行压力测试时,需要按照顺序进行压测,比如按照接口1、接口2、接口3、接口4 进行执行 查询结果是很混乱的,如果请求次数少,可能会按照顺序执行,但是随着次数增加&a…

《零基础实践深度学习》(第2版)学习笔记,(二)机器学习和深度学习综述

文章目录 1. 人工智能、机器学习、深度学习的关系2. 机器学习2.1 实现原理2.2 如何实施 3. 深度学习神经网络核心概念 1. 人工智能、机器学习、深度学习的关系 **人工智能(Artificial Intelligence,AI)**是研发用于模拟、延伸和扩展人的智能…

helm安装harbor + nerdctl 制作push 镜像

参考 文章:Helm部署Harbor_helm harbor_风向决定发型丶的博客-CSDN博客 安装好后使用 nerd containerd对接harbor_containerd 容器 insecure-registries 配置_柠是柠檬的檬的博客-CSDN博客 推送镜像 Containerd 对接私有镜像仓库 Harbor - 知乎 接下来我们来…

“一日之际在于晨”,欢迎莅临WAVE SUMMIT上午场:Arm 虚拟硬件早餐交流会

8月16日,盛夏的北京将迎来第九届WAVE SUMMIT深度学习开发者大会。在峰会主论坛正式开启前,让我们先用一份精美的元气早餐,和一场“Arm虚拟硬件交流会”,唤醒各位开发小伙伴的开发魂! 8月16日,WAVE SUMMIT大…

【注解使用】使用@Autowired后提示:Field injection is not recommended(Spring团队不推荐使用Field注入)

问题发生场景: 在使用 IDEA 开发 SpringBoot 项目时,在 Controller 类中使用注解 Autowired 注入一个依赖出现了警告提示,查看其他使用该注解的地方同样出现了警告提示。这是怎么回事?由于先去使用了SpringBoot并没有对Spring进行…

三、性能测试场景设计

性能测试场景设计 一、引言:如果公司要求你去做性能测试,遇到这些场景,我们要如何设计?二、6种常见设计方法1、普通性能场景设计2、负载测试性能场景3、压力测试场景4、面向目标性能场景 一、引言:如果公司要求你去做性…

W6100-EVB-PICO 做UDP Server进行数据回环测试(七)

前言 前面我们用W6100-EVB-PICO 开发板在TCP Client和TCP Server模式下,分别进行数据回环测试,本章我们将用开发板在UDP Server模式下进行数据回环测试。 UDP是什么?什么是UDP Server?能干什么? UDP (User Dataqram P…

海量数据迁移,亚马逊云科技云数据库服务为大库治理提供新思路

1.背景 目前,文档型数据库由于灵活的schema和接近关系型数据库的访问特点,被广泛应用,尤其是游戏、互联网金融等行业的客户使用MongoDB构建了大量应用程序,比如游戏客户用来处理玩家的属性信息;又如股票APP用来存储与时…

Jmeter常用功能-参数化介绍

JMeter也有像LR中的参数化,本篇就来介绍下JMeter的参数化如何去实现。 参数化:录制脚本中有登录操作,需要输入用户名和密码,假如系统不允许相同的用户名和密码同时登录,或者想更好的模拟多个用户来登录系统。 这个时…

RabbitMQ简单使用

RabbitMq是一个消息中间件:它接收消息、转发消息。你可以把它理解为一个邮局:当你向邮箱里寄出一封信后,邮递员们就能最终将信送到收信人手中。 RabbitMq、消息相关术语如下: 生产者:生产者只发送消息,发…

React(5)

1.受控组件案例 1.1之前的影院案例改写 import React, { Component } from react import axios from axios import BetterScroll from better-scroll import ./css/02_tab.cssexport default class Cinema extends Component {constructor() {super();this.state {cinemaLis…

Jmeter进阶使用:BeanShell实现接口前置和后置操作

一、背景 我们使用Jmeter做压力测试或者接口测试时,除了最简单的直接对接口发起请求,很多时候需要对接口进行一些前置操作:比如提前生成测试数据,以及一些后置操作:比如提取接口响应内容中的某个字段的值。举个最常用…

只需要自动售货机,商业模式立马大变样!

随着互联网、大数据和人工智能的蓬勃发展,商业模式正以前所未有的方式融合,其中自动售货机作为新零售模式的一颗璀璨明珠,正引领着购物体验的革命。这个巧妙的结合将消费者的便利、数据的智能分析以及科技的创新融为一体,重新定义…

Mysql:Access denied for user ‘root‘@‘localhost‘ (using password:YES)解决方案

最近在配置Maven以及Mybatis时,连接localhost数据库时出现无法连接,用cmd测试时报错:Access denied for user ‘ODBC’‘localhost’ (using password: NO),这个意思就是不允许远程访问,一开始笔者进入mysql试了一下是…

Untiy Json和Xml的序列化和反序列化

Json的序列化和反序列化 1.定义数据类 [Serializable] public class ZoomPoint {// 点名称, 将作为Key被字典存储public string name;// 轴心X坐标public Vector2 pivot Vector2.one / 2;// 放大倍率,小于1是为缩小倍率,小于0是取绝对值,不…

机器学习中基本的数据结构说明

数据维度或数据结构 当我们在机器学习或深度学习的领域内处理数据,我们通常会遇到四种主要的数据结构:标量,向量,矩阵和张量。理解这些基本数据结构是非常重要的,因为它们是机器学习算法和神经网络的核心。下面是对这…

NLPR、SenseTime 和 NTU 加速自动视频纵向编辑

视频人像编辑技术已经在电视、视频和电影制作中得到了应用,并有望在不断发展的网真场景中发挥关键作用。最先进的方法已经可以逼真地将同源音频合成为视频。现在,来自北京模式识别国家实验室(NLPR)、商汤科技研究和南洋理工大学的…

go.sum are different when using go mod vendor/download

本地Golang配置 今天本地编译一个项目,遇到以下错误 PS D:\Code\Golang\jiankunking\k8s-ext> go mod tidy go: downloading github.com/huaweicloud/huaweicloud-sdk-go-obs v3.23.4incompatible verifying github.com/gin-gonic/ginv1.7.3: checksum mismat…