news 2026/5/10 12:20:13

Python PyQt6教程十-自定义控件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python PyQt6教程十-自定义控件

这是PyQt6教程。本教程适合初学者和中级程序员。阅读本教程后,您将能够编写非平凡的PyQt6应用程序。

代码示例可在本站下载:教程源代码

目录

  • 引言
  • 日期和时间
  • 第一个工程
  • 菜单与工具栏
  • 布局管理
  • 事件和信号
  • 对话框
  • 控件
  • 拖放
  • 绘画
  • 自定义控件
  • 俄罗斯方块

自定义控件

lPyQt6有一套丰富的控件。然而,没有一个工具包可以提供程序员在应用程序中可能需要的所有控件。工具包通常只提供最常见的控件,如按钮、文本小部件或滑块。如果需要一个更专业的控件,我们必须自己创建。

自定义控件是使用工具包提供的绘图工具创建的。有两种基本可能性:程序员可以修改或增强现有的控件,也可以从头开始创建自定义控件。

PyQt6 烧录控件


这是一个我们可以在Nero、K3B或其他CD/DVD刻录软件中看到的控件。

#!/usr/bin/python """ ZetCode PyQt6 tutorial In this example, we create a custom widget. Author: Jan Bodnar Website: zetcode.com """ from PyQt6.QtWidgets import (QWidget, QSlider, QApplication, QHBoxLayout, QVBoxLayout) from PyQt6.QtCore import QObject, Qt, pyqtSignal from PyQt6.QtGui import QPainter, QFont, QColor, QPen import sys class Communicate(QObject): updateBW = pyqtSignal(int) class BurningWidget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setMinimumSize(1, 30) self.value = 75 self.num = [75, 150, 225, 300, 375, 450, 525, 600, 675] def setValue(self, value): self.value = value def paintEvent(self, e): qp = QPainter() qp.begin(self) self.drawWidget(qp) qp.end() def drawWidget(self, qp): MAX_CAPACITY = 700 OVER_CAPACITY = 750 font = QFont('Serif', 7, QFont.Weight.Light) qp.setFont(font) size = self.size() w = size.width() h = size.height() step = int(round(w / 10)) till = int(((w / OVER_CAPACITY) * self.value)) full = int(((w / OVER_CAPACITY) * MAX_CAPACITY)) if self.value >= MAX_CAPACITY: qp.setPen(QColor(255, 255, 255)) qp.setBrush(QColor(255, 255, 184)) qp.drawRect(0, 0, full, h) qp.setPen(QColor(255, 175, 175)) qp.setBrush(QColor(255, 175, 175)) qp.drawRect(full, 0, till - full, h) else: qp.setPen(QColor(255, 255, 255)) qp.setBrush(QColor(255, 255, 184)) qp.drawRect(0, 0, till, h) pen = QPen(QColor(20, 20, 20), 1, Qt.PenStyle.SolidLine) qp.setPen(pen) qp.setBrush(Qt.BrushStyle.NoBrush) qp.drawRect(0, 0, w - 1, h - 1) j = 0 for i in range(step, 10 * step, step): qp.drawLine(i, 0, i, 5) metrics = qp.fontMetrics() fw = metrics.horizontalAdvance(str(self.num[j])) x, y = int(i - fw/2), int(h / 2) qp.drawText(x, y, str(self.num[j])) j = j + 1 class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): OVER_CAPACITY = 750 sld = QSlider(Qt.Orientations.Horizontal, self) sld.setFocusPolicy(Qt.FocusPolicy.NoFocus) sld.setRange(1, OVER_CAPACITY) sld.setValue(75) sld.setGeometry(30, 40, 150, 30) self.c = Communicate() self.wid = BurningWidget() self.c.updateBW[int].connect(self.wid.setValue) sld.valueChanged[int].connect(self.changeValue) hbox = QHBoxLayout() hbox.addWidget(self.wid) vbox = QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox) self.setLayout(vbox) self.setGeometry(300, 300, 390, 210) self.setWindowTitle('Burning widget') self.show() def changeValue(self, value): self.c.updateBW.emit(value) self.wid.repaint() def main(): app = QApplication(sys.argv) ex = Example() sys.exit(app.exec()) if __name__ == '__main__': main()

在我们的示例中,我们有一个和一个自定义控件。滑块控制自定义控件。此控件以图形方式显示介质的总容量和可用空间。我们自定义控件的最小值为1,最大值为OVER_capacity。如果我们达到值MAX_CAPACITY,我们就开始用红色绘制。这通常表示过度烧录。

刻录控件放置在窗口底部。这是通过使用一个和一个来实现的

class BurningWidget(QWidget): def __init__(self): super().__init__()

刻录控件是基于基础控件的。

self.setMinimumSize(1, 30)

我们更改控件的最小大小(高度)。默认值对我们来说有点小。

font = QFont('Serif', 7, QFont.Weight.Light) qp.setFont(font)

我们使用比默认字体更小的字体。这更符合我们的需要。

size = self.size() w = size.width() h = size.height() step = int(round(w / 10)) till = int(((w / OVER_CAPACITY) * self.value)) full = int(((w / OVER_CAPACITY) * MAX_CAPACITY))

我们动态地绘制控件。窗口越大,烧录控件就越大,反之亦然。这就是为什么我们必须计算绘制自定义控件的窗口大小。该参数决定了要绘制的总大小。此值来自滑块控件。这是整个地区的一部分。该参数决定了我们开始用红色绘制的点。直到满
实际绘图由三个步骤组成。我们画黄色或红黄相间的矩形。然后我们绘制垂直线,将控件划分为几个部分。最后,我们得出表示介质容量的数字。

metrics = qp.fontMetrics() fw = metrics.horizontalAdvance(str(self.num[j])) x, y = int(i - fw/2), int(h / 2) qp.drawText(x, y, str(self.num[j]))

我们使用字体度量来绘制文本。我们必须知道文本的宽度,以便将其居中放置在垂直线周围。

def changeValue(self, value): self.c.updateBW.emit(value) self.wid.repaint()

当我们移动滑块时,会调用该方法。在方法内部,我们发送一个带有参数的自定义信号。该参数是滑块的当前值。该值稍后用于计算要绘制的Burning控件的容量。然后重新绘制自定义控件。

在PyQt6教程的这一部分中,我们创建了一个自定义控件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 22:12:09

ExplorerPatcher:重新定义Windows 11桌面体验的强大工具

ExplorerPatcher:重新定义Windows 11桌面体验的强大工具 【免费下载链接】ExplorerPatcher 项目地址: https://gitcode.com/gh_mirrors/exp/ExplorerPatcher 还在为Windows 11的新界面感到不适应吗?ExplorerPatcher这款开源神器能够让你在保留新…

作者头像 李华
网站建设 2026/5/6 16:09:50

突破性技术:KTransformers框架下多模态大模型优化实战

突破性技术:KTransformers框架下多模态大模型优化实战 【免费下载链接】ktransformers A Flexible Framework for Experiencing Cutting-edge LLM Inference Optimizations 项目地址: https://gitcode.com/gh_mirrors/ktr/ktransformers KTransformers作为业…

作者头像 李华
网站建设 2026/5/2 18:29:39

腾讯开源Hunyuan-7B:256K超长上下文+快慢思考模式重塑行业应用

腾讯开源Hunyuan-7B:256K超长上下文快慢思考模式重塑行业应用 【免费下载链接】Hunyuan-7B-Pretrain 腾讯开源大语言模型Hunyuan-7B-Pretrain,支持256K超长上下文,融合快慢思考模式,具备强大推理能力。采用GQA优化推理效率&#x…

作者头像 李华
网站建设 2026/5/3 8:50:12

全栈数字治理解决方案:基于SpringBoot的智慧社区与乡村振兴大数据AI平台

一、项目概述智慧社区数字基座是一套深度融合物联网感知、大数据分析与人工智能决策的综合性社区治理与服务平台。平台以“数据智能”为核心驱动力,旨在通过构建社区级数字孪生体,全面提升基层治理的精细化水平、公共服务的便捷化程度与社区生活的安全宜…

作者头像 李华
网站建设 2026/5/1 0:26:49

ComfyUI-MultiGPU完全部署手册:突破显存限制的终极解决方案

ComfyUI-MultiGPU完全部署手册:突破显存限制的终极解决方案 【免费下载链接】ComfyUI-MultiGPU This custom_node for ComfyUI adds one-click "Virtual VRAM" for any GGUF UNet and CLIP loader, managing the offload of layers to DRAM or VRAM to ma…

作者头像 李华
网站建设 2026/5/9 0:24:57

水下场景3D重建技术突破:SeaThru-NeRF如何应对光线折射与散射挑战

作为一名技术侦探,今天我要带大家探讨水下3D重建领域最棘手的两个技术难题——光线折射导致的模型失真和水体散射造成的图像模糊。你是否曾发现,用传统NeRF方法处理水下照片时,重建出来的模型总是比例失调、纹理模糊?这背后隐藏着…

作者头像 李华