pyqt5——自定义控件

自定义控件

PyQt5有丰富的组件,但是肯定满足不了所有开发者的所有需求,PyQt5只提供了基本的组件,像按钮,文本,滑块等。如果你还需要其他的模块,应该尝试自己去自定义一些。

自定义组件使用绘画工具创建,有两个基本方式:根据已有的创建或改进;通过自己绘图创建。

Burning widget

这个组件我们会在Nero,K3B,或者其他CD/DVD烧录软件中见到。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial
欢迎加入我的QQ群`923 414 804`与我一起学习
In this example, we create a custom widget.

Author: Jan Bodnar
Website: zetcode.com
Last edited: August 2017
"""

from PyQt5.QtWidgets import (QWidget, QSlider, QApplication,
    QHBoxLayout, QVBoxLayout)
from PyQt5.QtCore import QObject, Qt, pyqtSignal
from PyQt5.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.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.SolidLine)

        qp.setPen(pen)
        qp.setBrush(Qt.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.width(str(self.num[j]))
            qp.drawText(i-fw/2, h/2, 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.Horizontal, self)
        sld.setFocusPolicy(Qt.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()

if __name__ == ‘__main__‘:

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

本例中,我们使用了QSlider和一个自定义组件,由进度条控制。显示的有物体(也就是CD/DVD)的总容量和剩余容量。进度条的范围是1~750。如果值达到了700(OVER_CAPACITY),就显示为红色,代表了烧毁了的意思。

烧录组件在窗口的底部,这个组件是用QHBoxLayoutQVBoxLayout组成的。

class BurningWidget(QWidget):

    def __init__(self):
        super().__init__()        

基于QWidget组件。

self.setMinimumSize(1, 30)

修改组件进度条的高度,默认的有点小。

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

使用比默认更小一点的字体,这样更配。

size = self.size()
w = size.width()
h = size.height()

step = int(round(w / 10.0))

till = int(((w / 750.0) * self.value))
full = int(((w / 750.0) * 700))

动态的渲染组件,随着窗口的大小而变化,这就是我们计算窗口大小的原因。最后一个参数决定了组件的最大范围,进度条的值是由窗口大小按比例计算出来的。最大值的地方填充的是红色。注意这里使用的是浮点数,能提高计算和渲染的精度。

绘画由三部分组成,黄色或红色区域和黄色矩形,然后是分割线,最后是添上代表容量的数字。

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

这里使用字体去渲染文本。必须要知道文本的宽度,这样才能让文本的中间点正好落在竖线上。

def changeValue(self, value):

    self.c.updateBW.emit(value)
    self.wid.repaint()

拖动滑块的时候,调用了changeValue()方法。这个方法内部,我们自定义了一个可以传参的updateBW信号。参数就是滑块的当前位置。这个数值之后还用来于Burning组件,然后重新渲染Burning组件。

原文地址:https://www.cnblogs.com/paisenpython/p/10254657.html

时间: 2024-10-11 02:09:57

pyqt5——自定义控件的相关文章

PyQt5 入门

换了VSCODE开发,感觉比sublime好点,可能是由于第三版老弹框烦人吧.VSCODE看着也挺好看的. 学习 PyQt5 中文教程 0. 安装完之后错误 pip 安装了 pyqt5 from PyQt5.QtWidgets import QApplication, QWidget 这句错误:E0611:No name 'QApplication' in module 'PyQt5.QtWidgets' 搜到是要sip,卸载python5重新安装了sip后再试还是错误,但是直接在命令行运行是好

winform 自定义控件的使用

c#的自定义控件还是很方便的,至少相对于c++而言. 1,当然是建立一个windows 窗体空间库,我这里就是用vs 2015 ,工程名MyControl 第二步.在自定义空间窗体内,拖放这样一组空间.我们发送编辑框的内容给父窗体,然后接受父窗体的发送的内容,显示到listbox 中. 这里会看到我使用了委托和事件,其实,刚入门的我,对于c#里的委托和事件 理解的并不深刻.看到很多地方再用.感觉和c++ 的回调很相似.这里就不纠结了, 后面慢慢理解吧.我们通过委托将子窗体的内容发送到主窗体. n

WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要有三种实现方式: 简单忙碌状态控件BusyBox: Win8/win10效果忙碌状态控件ProgressRing: 弹出异步等待框WaitingBox: 二.简单忙碌状态控件BusyBox 效果图: 通过属性"IsActive"控制控件是否启用,后台C#代码: /// <summary> /

自定义控件和使用的两种基本方法

有时需要一些组合起来的功能性强的控件,为了以后复用简单,还是自己自定义比较方便. 这里以一个自定义的导航栏为例子,在MainActivity里面使用这个控件. 方法一: 设计并编写自定义控件的布局文件,然后在其他布局文件中include. title的布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android

自定义控件学习——防qq侧滑栏

效果 主要步骤: 1. 在xml布局里摆放内容. include    2. 在自定义ViewGroup里, 进行measure测量, layout布局    3. 响应用户的触摸事件    4. int scrollX = (int) (downX - moveX);    5. getScrollX()获取当前滚动到的位置    6. 平滑动画 先看布局 layout_left <?xml version="1.0" encoding="utf-8"?&g

手机卫士11_ 自定义控件_缓存清理_病毒库更新

拷贝安卓源码中的逻辑,可以考虑先创建一个小项目实现以下效果 1,病毒数据库的自动更新(连接网络,然后获取特征码保存到数据库?) ①工程师发现病毒apk,获取到它的特征码发布到服务器上 通过 MD5 或者ASH1获取特征码 ②客户端杀毒软件下载特征码(可能是 JSON串)到本地客户端 (在打开软件的时候还是打开查杀界面的时候?其实都不适合,应该开启一个服务去定期更新数据库,访问病毒更新特征码地址) 定期更新,timer和timertask,一般一个小时更新一次(测试的时候写短一点) 连接服务器:U

PyQt5教程——组件 Ⅱ(八)

这部分的教程将会继续介绍PyQt5的组件.我们这节教程的内容将包括像素图(QPixmap),单行文本框(QLineEdit)和下拉列表框(QComboBox) 像素图(QPixmap) 像素图(QPixmap)是各种用于处理图像的组件中的一个.它是在屏幕上显示图片的最佳选择.在我们代码例子中,我们将使用像素图来在窗口上显示一个图片. #!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial In

自定义控件一般步骤

自定义组合控件的过程 1.自定义一个View 一般来说,继承相对布局,或者线性布局  ViewGroup:   2.实现父类的构造方法.一般来说,需要在构造方法里初始化自定义的布局文件:    3.根据一些需要或者需求,定义一些API方法: ----------------------------------   4.根据需要,自定义控件的属性,可以参照TextView属性: 5.自定义命名空间,例如: 使用eclipse需添加如下命名空间     xmlns:自定义名称=http://sche

pyqt5加载网路图片,不本地下载。

依赖组件: requests class webImg: pass if __name__ == '__main__': import sys from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import (QWidget, QLabel, QVBoxLayout) from PyQt5.QtGui import QPixmap app = QApplication(sys.argv) import requests u