PyQt重绘事件处理函数paintEvent

news2024/11/16 13:53:19

PyQt中的重绘和Windows编程中的重绘差不多,但是Qt的重绘更有特色,更加智能。基础部件类QWidget提供的paintEvent函数是一个纯虚函数,继承它的子类想用它,就必须重新实现它。下列4种情况会发生重绘事件:

(1)当窗口部件第一次显示时,系统会自动产生一个绘图事件。

(2)repaint()与update()函数被调用时。

(3)当窗口部件被其他部件遮挡,然后又再次显示出来时,就会对隐藏的区域产生一个重绘事件。

(4)重新调整窗口大小时。

paintEvent()是一个虚函数槽,子类可以对父类的paintEvent进行重写。当调用update()、repaint()的时候,paintEvent()会被调用,另外,当界面有任何改变的时候,paintEvent()也会被调用,这种界面的改变包括界面从隐藏到显示,界面尺寸改变,当然界面内容改变的时候也会被调用。paintEvent()是已经被高度优化过的函数,它本身已经自动开启并实现了双缓冲(X11系统需要手动开启双缓冲),因此Qt中重绘不会引起任何闪烁。有了paintEvent的知识,现在再来看看update()和repaint()。update()和repaint()是一类的,需要重绘的对象主动去调用,然后重绘。update()和repaint()调用之后,都会调用paintEvent().repaint(),被调用之后立即执行重绘,因此repaint()是最快的,紧急情况下需要立刻重绘的可以使用repaint()。但是调用repaint()的函数不能放到paintEvent中调用。举个例子:有一个继承自QWidget的子类MyWidget,在子类中对paintEvent进行重写。我们在MyWidget::myrepaint()中调用repaint()。但是,myrepaint()又被重写的paintEvent()调用。这样调用repaint()的函数又被paintEvent()调用,由于repaint()是立即重绘,而且repaint()在调用paintEvent之前几乎不做任何优化操作,而会造成死循环,即先调用repaint(),继而调用paintEvent(),paintEvent()反过来又调用repaint()...,如此造成死循环。update()跟repaint()比较,update()更加有优越性。update()调用之后并不是立即重绘,而是将重绘事件放入主消息循环中,由main()的event loop来统一调度(其实也是比较快的)。update()在调用paintEvent()之前还做了很多优化,如果update()被调用了很多次,最后这些update()会合并到一个大的重绘事件加入消息队列中,最后只有这个大的update()被执行一次。同时也避免了repaint()中所提到的死循环。因此,一般情况下,我们调用update()就够了,跟repaint()比起来,update()是推荐使用的。

打个比方,QPainter相当于Qt中的画家,能够绘制各种基础图形,拥有绘图所需的画笔、画刷、字体。绘图常用的工具画笔类QPen、画刷类QBrush和字体类QFont都继承自QPainter。QPen用于绘制几何图形的边缘,由颜色、宽度、线风格等参数组成;QBrush用于填充几何图形的调色板,由颜色和填充风格组成;QFont用于文本绘制,由字体属性组成。

QPaintDevice相当于Qt中的画布、画家的绘图板,所有的QWidget类都继承自QPaintDevice。通常我们把绘图操作只需放在paintEvent函数中即可。在QWidget类中,paintEvent的声明如下:

def paintEvent(self, a0: QtGui.QPaintEvent) -> None: ...

我们只需在QWidget的子类中重写paintEvent方法来实现画图,即把绘图函数放在paintEvent中调用,比如:

def paintEvent(self, evt):

    painter = QPainter(self)

    painter.drawLine(0, 0, 100,50); #画线函数

现在不熟悉这些绘图函数没关系,后面会详述,不过我们可以来看其效果。

【例8.1】第一个PyQt画图程序

(1)启动PyCharm,新建一个工程,工程名是PythonProject。

(2)启动Qt Designer,新建一个Dialog without Buttons对话框。从控件工具箱中拖拉一个按钮到对话框上,然后添加clicked信号的槽函数onc1。把这个界面设计的结果保存到mydlg.ui文件中,关闭Qt Designer。为了节省篇幅,在本章下面的实例中,这个过程就不再赘述了,代码也只演示paintEvent中的代码。

(3)回到PyCharm,转换mydlg.ui文件,在main.py中添加如下代码:

import sys
from PyQt5.QtGui import QPainter, QColor
from mydlg import Ui_Dialog
from PyQt5.QtWidgets import *

class CMainDlg(QDialog, Ui_Dialog):
    def __init__(self):
        super(CMainDlg, self).__init__()
        self.clr=255;
        self.setupUi(self)

    def paintEvent(self, evt):
        painter = QPainter(self)
        color = QColor()    			#建立一个颜色对象
        color.setRed(self.clr)   	#把颜色设为红色
        painter.setPen(color);  		#设置画笔的颜色
        w = self.size().width(); 	#获取窗口宽度
        h = self.size().height(); 	#获取窗口高度
        painter.drawLine(0, 0, w // 2, h); 	#画线函数
        painter.drawLine(w // 2, h,w,0);   	#画线函数

    def onc1(self):  		#按钮的clicked信号的槽函数
        if self.clr==255:
            self.clr=0;  		#黑色
        else:
            self.clr=255; 	#红色
        self.update();  		#更新窗口,此时将触发paintEvent函数的自动调用

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = CMainDlg()
    window.show()
    sys.exit(app.exec())

在paintEvent函数中,我们定义了一个颜色对象color,并通过成员变量self.clr来设置具体的颜色值,然后通过setPen函数设置画笔的颜色。接着,获取对话框的客户区的宽度和高度,最后调用画线函数drawLine来画两条线。只要窗口或部件需要被重绘,paintEvent函数就会被调用。每个要显示输出的窗口部件都必须实现它。为了在窗口重绘时能显示我们绘制的图形,所以要把绘图函数放在paintEvent中。而在按钮的clicked信号的槽函数中,我们设置了不同的self.clr值,最后使用update函数更新窗口,此时将自动触发paintEvent函数的调用。

(4)按【Shift+F10】快捷键运行工程,运行结果如图8-1所示。

 

图8-1

本文节选自《PyQt 5从入门到精通》,内容发布获得作者和出版社授权。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

全网最全的Salesforce营销云管理员认证考点梳理!

Marketing Cloud管理员认证适用于在Marketing Cloud套件中具有设置和维护各种模块(Studios/Builders)和功能的经验的营销专业人员。Salesforce建议备考者拥有3到6个月的Marketing Cloud管理员和数字营销人员实践经验。 营销云管理员认证 考试内容&#…

IOS发布:App Store Connect Operation Error。SDK Version Issue.

错误描述: App Store Connect Operation Error SDK Version Issue. This app was built with the iOS 15.0 SDK. all iOS apps submitted to the App Store must be built with the iOS 16.1 SDK or later, included in Xcode 14.1 or later. 问题原因&#xf…

ESP32 的多种睡眠模式以及如何让 ESP32 进入深度睡眠模式

ESP32 因其 BLE 兼容性功能以及更低的成本而受到广泛关注。它还带有 32 个 GPIO 引脚和一个 32 位双核 CPU。虽然,它提供了很多功能,但在正常使用模式下似乎很耗电。当应用程序由市电供电时,没有急事,但是当它们由电池供电时,我们必须非常注意 ESP32 的功耗。 ESP32 提供…

SQL使用技巧(6)HIVE开窗函数

专题:SQL使用技巧——实践是检验SQL函数的唯一标准 一.构建数据二.排序开窗三.sum开窗(重点内容)3.1累加与求和3.2窗口表达式3.3场景模拟 四.count开窗4.1计数规则4.2计数与排序 五.max和min开窗六.lead和lag开窗七.first_value和last_value开…

RabbitMq创建交换机和队列

1. 网页登录 IP:1572 2. 输入登录账号密码 admin admin 3. 点击Exchanges 添加交换机Platform_AlarmEngineInterface 和Rg_Platform_AlarmEngineInterface ,Type选择topic 4. 添加队列 VIDEO_Alarm_platform、watch_ftp、RG_VIDEO_Alarm_platform、RG_VIDEO_…

远程进入服务器界面黑屏如何处理?

​  远程登录服务器出现黑屏是很常见的问题,可能是由于多种原因引起的。但不管是哪种原因,当远程连接成功,进入桌面显示黑屏都会让用户感到困扰,无法正常使用服务器。下面我们将为您介绍一些常见的解决方法。 1. 重启远程桌面服…

js深拷贝和浅拷贝

👉十分钟学会 前端面试题 js 深拷贝与浅拷贝_前端深拷贝和浅拷贝面试题_Mar-30的博客-CSDN博客 目录 背景: 概念:核心是创建新地址 方法: 浅拷贝: Object.assign() 方法:Object.assign(拷贝的对象&am…

k8s证书过期

[rootmaster1 ~]# kubectl get nodes Unable to connect to the server: x509: certificate has expired or is not yet valid: current time 1.master服务器: # 备份 kubernetes配置 cp -r /etc/kubernetes /etc/kubernetes_bak # 检测证书过期 kubeadm certs…

数智荣耀丨美格智能荣登2023年度中国数智转型标杆企业榜

5月31日,2023数智产业领袖峰会在北京召开,本届大会由智次方—物联网智库主办,大会以大模型时代的“破”与“立”为主题,汇聚产业领袖、专家学者、投资机构、创新企业等各界精英,共同探讨企业如何利用新技术实现“破圈”…

【地平线X3M平台点亮sensor出现问题的分析】

转自地平线论坛经验 1. IC通讯失败的问题以及排查方法。 外界的图像数据一般是通过sensor感知,然后通过mipi接口进入到地平线X3M这款AI芯片的视频处理模块,模块对视频图像做比如放大、缩小、旋转等处理。 问题:IC通讯失败,错误…

手机MT4平台怎么样?手机版MT4平台使用教程教学

外汇是一个全球化的去中心化交易市场,与股票这样只提供一种报价的集中交易不同,在外汇市场中,货币的报价都不是单一的,意味着不同的外汇交易平台的报价会有所不同。以前外汇交易散户是很难进入市场的,参与者主要是银行…

功能强大UI美观的视频答题猜歌闯关娱乐微信小程序源码

正文: 功能强大UI美观的视频答题猜歌闯关娱乐微信小程序源码下载 后台管理资源本地化带数据和视频教程,这是一款拥有后端的闯关娱乐小程序。支持个人小程序和企业小程序上线运营功能强大齐全,带数据本地化(数据在自己服务器自己管理无需担心第三方失效…

【TCP 协议3】提高效率的五大机制

文章目录 前言一、滑动窗口与高速重传1, 什么是滑动窗口2, 什么是高速重传2.1, ack 丢包2.2, 数据丢包 二、流量控制1, 什么是流量控制 三、拥塞控制1, 什么是拥塞控制 四、延迟应答1, 什么是延迟应答 五、捎带应答1, 什么是捎带应答 总结 前言 各位读者好, 我是小陈, 这是我的…

Ansible基础3——playbook

文章目录 一、基本了解二、编写playbook2.1 单剧本2.2 多剧本2.3 特权升级2.4 语法优化 三、模块查找 一、基本了解 为什么要写playbook? 前面我们可以使用临时命令对受控机进行操作,但当有重复性的工作时就不能这么玩了,因为你要一遍遍的去执…

攻防世界-easy_RSA

题目如下:在一次RSA密钥对生成中,假设p473398607161,q4511491,e17 求解出d 1. RSA算法介绍 RSA算法是一种非对称加密算法,由三位计算机科学家Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出并命名。 它采用一…

Vue 基础组件二次封装的高级技巧及方法,能更优雅的进行二次封装组件(props 属性和 event 事件的透传、子组件插槽暴露、第三方组件方法继承)

前言 本人持续开源了Vue2基于ElementUi&AntdUi再次封装的Tui基础组件和Vue3基于Element-plus再次封装的TuiPlus基础组件,在组件封装的过程中提取了 props 属性和 event 事件的透传、子组件插槽暴露等,借此总结一下!!大佬略过!…

把VS Code打造成后端开发的宇宙IDE,也挺爽

本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注! 作者:维生素P|慕课网优质作者 工欲善其事必先利其器,提高程序员的开发效率必须要有一个好的开发工具。而一旦提到开发工具&#xff…

深度解析Linux读写锁逻辑

一、Linux为何会引入读写锁? 除了mutex,在linux内核中,还有一个经常用到的睡眠锁就是rw semaphore(后文简称为rwsem),它到底和mutex有什么不同呢?为何会有rw semaphore?无他&#x…

[Mysql_DB]自动写入系统时间——注意低版本数据库操作

创建商品表包含字段create_time和update_time,并设置默认值为当前时间 实例 使用 CREATE TABLE 语句来创建一个商品表,并为其添加 create_time 和 update_time 字段,同时将这两个字段的默认值设置为当前时间。以下是一个示例: CREATE TABLE …

最新版本 Stable Diffusion 开源 AI 绘画工具之文本转换(Embedding)以及脚本(Script)高级使用篇

✨ 目录 🎈 文本转换 / Textual Inversion🎈 自定义Embedding / Textual Inversion🎈 脚本 / Script🎈 脚本 / Prompt matrix🎈 脚本 / X/Y/Z plot 🎈 文本转换 / Textual Inversion 这个功能其实就是将你…