Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >PyQt 自定义窗口部件(三)

PyQt 自定义窗口部件(三)

作者头像
用户6021899
发布于 2019-08-14 08:40:40
发布于 2019-08-14 08:40:40
61600
代码可运行
举报
运行总次数:0
代码可运行

本篇介绍用如何QPainter()画出一个可以显示混合流体流速的Y形管控件。

Y形管由abci、edcf 以及cihgf三部分组成,内部的颜色由流体的流速决定。各个部分均使用逻辑坐标系绘制。

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from PyQt5.QtWidgets import (QApplication,QFrame, QLabel,QSizePolicy, QSpinBox, QWidget)
from PyQt5.QtGui import QColor,QPainter,QFontMetricsF,QBrush,QLinearGradient,QPolygon,QPolygonF
from PyQt5.QtCore import QPointF, QSize, Qt,pyqtSignal

class YPipeWidget(QWidget):
    signal_valuechanged = pyqtSignal(int,int)
    def __init__(self, leftFlow=0, rightFlow=0, maxFlow=100, parent=None):
        super(YPipeWidget, self).__init__(parent)
        
        self.leftSpinBox = QSpinBox(self)
        self.leftSpinBox.setRange(0, maxFlow)
        self.leftSpinBox.setValue(leftFlow)
        self.leftSpinBox.setSuffix(" l/s")#设置后缀
        self.leftSpinBox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
        self.leftSpinBox.valueChanged.connect(self.valueChanged)
        
        self.rightSpinBox = QSpinBox(self)
        self.rightSpinBox.setRange(0, maxFlow)
        self.rightSpinBox.setValue(rightFlow)
        self.rightSpinBox.setSuffix(" l/s")#设置后缀
        self.rightSpinBox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
        self.rightSpinBox.valueChanged.connect(self.valueChanged)
        self.label = QLabel(self)
        self.label.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
        self.label.setAlignment(Qt.AlignCenter)
        fm = QFontMetricsF(self.font())
        self.label.setMinimumWidth(fm.width(" 999 l/s "))
        self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding))#横向竖向均可放大
        self.setMinimumSize(self.minimumSizeHint())
        self.valueChanged()

    def valueChanged(self):
        a = self.leftSpinBox.value()
        b = self.rightSpinBox.value()
        self.label.setText("{0} l/s".format(a + b))
        self.signal_valuechanged.emit(a,b)
        self.update()

    def values(self):
        return self.leftSpinBox.value(), self.rightSpinBox.value()
    def minimumSizeHint(self):
        return QSize(self.leftSpinBox.width() * 3,self.leftSpinBox.height() * 5)
    def resizeEvent(self, event=None):
        fm = QFontMetricsF(self.font())
        x = (self.width() - self.label.width()) / 2
        y = self.height() - (fm.height() * 1.5)
        self.label.move(x, y)
        y = self.height() / 60.0
        x = (self.width() / 4.0) - self.leftSpinBox.width()
        self.leftSpinBox.move(x, y)
        x = self.width() - (self.width() / 4.0)
        self.rightSpinBox.move(x, y)
    def paintEvent(self, event=None):
        LogicalSize = 100.0
        
        def logicalFromPhysical(length, side):
            return (length / side) * LogicalSize
        
        fm = QFontMetricsF(self.font())
        ymargin = ((LogicalSize / 30.0) +logicalFromPhysical(self.leftSpinBox.height(),self.height()))
        ymax = (LogicalSize - logicalFromPhysical(fm.height() * 2, self.height()))
        width = LogicalSize / 4.0
        #设置Y形管 9 个角点的坐标
        cx, cy = LogicalSize / 2.0, LogicalSize / 3.0
        ax, ay = cx - (2 * width), ymargin
        bx, by = cx - width, ay
        dx, dy = cx + width, ay
        ex, ey = cx + (2 * width), ymargin
        fx, fy = cx + (width / 2), cx + (LogicalSize / 24.0)
        gx, gy = fx, ymax
        hx, hy = cx - (width / 2), ymax
        ix, iy = hx, fy
        painter = QPainter(self)# 创建QPainter实例,注意self!
        painter.setRenderHint(QPainter.Antialiasing)#抗锯齿
        side = min(self.width(), self.height())
        #设置绘图“视口”(使用物理坐标系),参数(整形)分别为左上角的x和y,以及视口的宽和高
        painter.setViewport((self.width() - side) / 2, (self.height() - side) / 2, side, side)
        #设置绘图“窗口”(使用逻辑坐标系),参数(整形)分别为左上角的x和y,以及“窗口”的宽和高
        #之后逻辑坐标系 (Qpainter自动会将逻辑坐标按比例映射到物理坐标)
        painter.setWindow(0, 0, LogicalSize, LogicalSize)
        
        painter.setPen(Qt.NoPen) #无线条
        gradient = QLinearGradient(QPointF(0, 0),QPointF(0, 100))#线性梯度
        gradient.setColorAt(0, Qt.white)
        a = self.leftSpinBox.value()
        gradient.setColorAt(1, (Qt.red if a != 0 else Qt.white)) #流速非零时,左边流体为红色
        painter.setBrush(QBrush(gradient)) #画刷
        #绘制左边多边形(4边形)
        painter.drawPolygon(QPolygonF([QPointF(ax, ay), QPointF(bx, by), QPointF(cx, cy), QPointF(ix, iy)]))
        gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100))
        gradient.setColorAt(0, Qt.white)
        b = self.rightSpinBox.value()
        gradient.setColorAt(1, (Qt.blue if b != 0 else Qt.white)) #流速非零时,右边流体为蓝色
        painter.setBrush(QBrush(gradient))
        #绘制右边多边形(4边形)
        painter.drawPolygon(QPolygonF([QPointF(cx, cy), QPointF(dx, dy),QPointF(ex, ey),QPointF(fx, fy)]))
        #计算混合流体的颜色
        if (a + b) == 0:
            color = QColor(Qt.white)
        else:
            ashare = (a / (a + b)) * 255.0
            bshare = 255.0 - ashare
            color = QColor(ashare, 0, bshare)
        gradient = QLinearGradient(QPointF(0, 0), QPointF(0, 100))
        gradient.setColorAt(0, Qt.white)
        gradient.setColorAt(1, color)
        painter.setBrush(QBrush(gradient))
        
        #绘制下部多边形(5边形)
        painter.drawPolygon(QPolygonF([QPointF(cx, cy),QPointF(fx, fy),QPointF(gx, gy), QPointF(hx, hy),QPointF(ix, iy)]))
        #绘制Y形管边界(黑色粗实线)
        painter.setPen(Qt.black)
        painter.drawPolyline(QPolygonF([QPointF(ax, ay), QPointF(ix, iy),QPointF(hx, hy)]))
        painter.drawPolyline(QPolygonF([QPointF(gx, gy), QPointF(fx, fy), QPointF(ex, ey)]))
        painter.drawPolyline(QPolygonF([QPointF(bx, by), QPointF(cx, cy), QPointF(dx, dy)]))

if __name__ == "__main__":
    import sys
    def valueChanged(a, b):
        print(a, b)
    app = QApplication(sys.argv)
    form = YPipeWidget()
    form.signal_valuechanged.connect(valueChanged)
    form.setWindowTitle("YPipe")
    form.move(0, 0)
    form.show()
    form.resize(400, 400)
    app.exec_()

本篇的例子来自《Python Qt Gui 快速编程 ----PyQt 编程指南》,原文是PyQt4的,现已改为PyQt5 版本。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python可视化编程机器学习OpenCV 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Qt自定义控件之仪表盘的完整实现
基于QT的仪表盘有很多种办法,比如使用QWT或Echart组件,或者基于QT的绘图功能绘制,或者基于美工提供的图片的基础上增加动态效果。然而搞明白QT自定义控件的绘图后,这种实现是最简单的。且定制度高,想要什么效果就可以自己绘制个。这里介绍下Qt自定义控件之仪表盘的完整实现。
杨永贞
2022/10/04
2.3K0
Qt自定义控件之仪表盘的完整实现
30.QT-渐变之QLinearGradient、 QConicalGradient、QRadialGradient
渐变有三种:QLinearGradient、QConicalGradient 、 QRadialGradient 它们都有一个QGradient父类 QGradient父类的常用公共函数有: void QGradient::setSpread ( Spread method ); //设置填充梯度区域外的区域,参数有: // QGradient::PadSpread :填充区域内最接近的停止颜色。这是默认的。 // QGradient::RepeatSpread : 在区域外继续重复填充 // QGrad
诺谦
2018/07/05
1.8K0
Qt5实战第五篇:图形与绘图
Qt5 提供了强大的二维图形绘制功能,通过 QPainter 类,开发者可以在窗口部件或其他绘制设备上进行绘图。此外,Qt 还支持矢量图形、图像处理、动画以及高级绘图功能,使得开发图形界面应用程序变得简单而高效。
china马斯克
2024/12/28
1880
Qt编写自定义控件30-颜色多态按钮
这个控件一开始打算用样式表来实现,经过初步的探索,后面发现还是不够智能以及不能完全满足需求,比如要在此控件设置多个角标,这个用QSS就很难实现,后面才慢慢研究用QPainter来绘制,我记得当时接到这个定制控件任务的时候是2016年,那时候对QPainter的使用还不是很熟悉,也就是从此控件开始,逐步研究QPainter的绘制,把所有的内置函数都使用一遍,最终用的越来越熟悉,使得后来到了心中有坐标,万物皆painter的境界,可能就像武林中所说的打通了任督二脉吧。
feiyangqingyun
2019/08/27
2K0
Qt编写自定义控件30-颜色多态按钮
Qt编写自定义控件10-云台仪表盘
做过安防视频监控的同学都清楚,在视频监控系统软件上都可以看到一个云台控制区域,可以对球机进行下下左右等八个方位的运动控制,还可以进行复位,一般都是美工作图好,然后贴图的形式加入到软件中,好处是程序简单,界面美工,主要取决于美工的美图能力,缺点是对于各种分辨率的适应性稍微差点,需要不同的图片切图贴图,除非默认做好的是大图自适应看不出差别,可能大部分人所在的公司都是小公司,一般美工人员比较少甚至没有,都需要程序员一人负责,甚至一开始就要考虑到各种分辨率的应用场景以及后期可能的换肤换色等。
feiyangqingyun
2019/08/23
1.6K0
Qt编写自定义控件10-云台仪表盘
Qt编写自定义控件4-旋转仪表盘
旋转仪表盘,一般用在需要触摸调节设置值的场景中,其实Qt本身就提供了QDial控件具有类似的功能,本控件最大的难点不在于绘制刻度和指针等,而在于自动计算当前用户按下处的坐标转换为当前值,这个功能想了很久,也看了QDial的源码,他里边写的非常复杂,最后还是参考的我打99分(100分留给自己未来写的书,哈哈!)的Qt书籍《c++ gui qt 4编程》中的篇章才写出来的,关键需要用到atan2将坐标转为值,看来学好数学真的很重要。
feiyangqingyun
2019/08/23
2.1K0
Qt编写自定义控件4-旋转仪表盘
Qt编写自定义控件6-指南针仪表盘
指南针仪表盘,主要用来指示东南西北四个方位,双向对称两个指针旋转,其实就是360度打转,功能属于简单型,可能指针的绘制稍微难一点,需要计算多个点构成多边形,本系列控件文章将会连续发100+篇,一方面为了锻炼自己的毅力+坚持力,一方面为了宣传自己,如果各位对完整的源码有兴趣可以私聊,也欢迎在文章下面评论提出建议,谢谢!
feiyangqingyun
2019/08/23
1.5K0
Qt编写自定义控件6-指南针仪表盘
Qt编写自定义控件58-直方对称图
本控件也非原创控件,是参考网上的代码而来的,对称顾名思义就是将画布平均成上下两部分,将设置的值自动按照画布高度的一半作为参照高度进行绘制,然后增加动态过渡效果,有点类似于声音播放时候的频谱效果,一般都会用多个直方对称图组合成一个控件来实现多个效果,看起来会更美观,背景颜色可以设置成渐变的,柱状条的颜色也可以自行设置。
feiyangqingyun
2019/09/25
7220
Qt编写自定义控件58-直方对称图
Qt编写自定义控件24-图片轮播控件
上一篇文章写的广告轮播控件,采用的传统widget堆积设置样式表做的,这次必须要用到更高级的QPainter来绘制了,这个才是最高效的办法,本控件参考雨田哥的轮播控件,经过大规模的改造而成,相比于原来的广告轮播控件,本控件可以说完爆他,按在地上使劲摩擦。除了可以设置图片路径集合以外,还可以设置对应的提示信息,这个在众多的web轮播图片效果中最常见,比如新闻的标题等,可以更直观的显示当前图片,而且单击图片还可以支持跳转,指示器的位置也能设置左边+中间+右边,指示器的样式更加增加到椭圆条状+圆形+矩形+小圆点+长条状多种可选择,可以说涵盖了各种web轮播图片的效果,还可以设置鼠标悬停暂停轮播,以便看清说明后鼠标移开继续轮播。指示器的宽高颜色等,都是可以自由设定的,这个对于采用QPainter绘制来说,是最好自定义的,无非就是设置对应的画笔QPen和对应的画布QBrush的颜色啦。
feiyangqingyun
2019/08/27
2K0
Qt编写自定义控件24-图片轮播控件
Qt编写自定义控件12-进度仪表盘
进度仪表盘主要应用场景是标识一个任务进度完成的状况等,可以自由的设置范围值和当前值,为了美观还提供了四种指示器(圆形指示器/指针指示器/圆角指针指示器/三角形指示器),各种颜色都可以设置,其中的动画效果采用的QPropertyAnimation类来实现,主要是线性插值法,生成一定规则的数值,用于设定的属性。今天有个朋友需要安卓版本的控件,其实采用qwidget写的控件都可以直接编译就可以到android上,于是直接重新编译了安卓版本,对应的apk已上传到共享文件夹,文末贴出android运行效果图。
feiyangqingyun
2019/08/23
1.5K0
Qt编写自定义控件12-进度仪表盘
PySide6 GUI 编程(43):自定义 QWidget
它在控件需要重新绘制时被调用,例如在窗口被遮挡后重新显示、控件大小改变、或调用 update() 方法时。
bowenerchen
2024/09/15
3902
PySide6 GUI 编程(43):自定义 QWidget
Qt编写自定义控件49-飞机仪表盘
飞行仪表是测定和表示飞机数据的工具,飞机中必不可少的一部分,飞行员根据飞行仪表表示的数据才能正确地做出判断。一般飞机仪表包括高度表+空速表+垂直速率表+姿态仪+航向指示表+转弯协调表。
feiyangqingyun
2019/08/28
2.6K0
Qt编写自定义控件49-飞机仪表盘
Qt编写自定义控件57-直方波形图
直方波形图控件非原创控件,控件大全中大概有20-30个控件非自己原创,而是参考了网上开源的代码,自己加以整理和完善,新增了插件的代码使得可以直接集成到QtDesigner或者QtCreator中。直方波形图,主要就是将外部传入的坐标集合数据进行渐变过渡的绘制,产生一个动态的过渡效果,将设置的坐标集合重新运算+1变成新的坐标集合来绘制,这样看起来绘制不会很死,而是缓慢的过渡。
feiyangqingyun
2019/09/25
1.1K0
Qt编写自定义控件57-直方波形图
Qt编写自定义控件38-高亮按钮
高亮按钮控件,既可以作为类似于交通指示灯使用,也可以作为设备状态指示灯使用,控件内置多套颜色风格,还可以自己设置颜色风格,按钮可以增加文字显示,非常适合需要在状态设备上显示小量的文字展示,按钮还可以开启报警,开启后会红黑闪烁,也可以自定义设置报警的两种颜色,除了默认是圆形外,还可以设置成矩形模式,控件写好了作为独立控件拖动使用,这样的话可以将控件作为一个设备,在地图上拖动,用户只需要开启拖动即可,不需要再自己编码。
feiyangqingyun
2019/08/27
1.7K0
Qt编写自定义控件38-高亮按钮
PyQt5 模拟钟表
本程序由PyQt4官方demo升级而来,各指针会随着系统时间变化而转动。另加入了秒针和圆盘。
用户6021899
2020/02/10
1.1K1
Qt编写自定义控件5-柱状温度计
柱状温度计控件,可能是很多人练手控件之一,基本上都是垂直方向展示,底部一个水银柱,中间刻度尺,刻度尺可以在左侧右侧或者两侧都有,自适应分辨率改动,有时候为了美观效果,可能还会整个定时器来实现动画效果,开启动画效果的缺点就是CPU占用会比较高,前阵子有个好友(贾文涛-涛哥)向我推荐了一个opengl绘制的开源东西,QNanoPainter,东西是个好东西,我个人的理解是直接封装了opengl绘制的qpainter,可以使得绘制全部走GPU,这样就可以大大减轻CPU的负担,非常方便,我自己试了下,方法和绘制逻辑和qpainter有点不一样,暂时没有将所有控件改成QNanoPainter版本,以后看情况吧。
feiyangqingyun
2019/08/23
2.5K0
Qt编写自定义控件5-柱状温度计
Qt编写自定义控件66-光晕时钟
在上一篇文章写了个高仿WIN10系统的光晕日历,这次来绘制一个光晕的时钟,也是在某些网页上看到的效果,时分秒分别以进度条的形式来绘制,而且这个进度条带有光晕效果,中间的日期时间文字也是光晕效果,整体看起来有点科幻的感觉,本控件没有什么技术难点,如果真要有难点的话也就是如何产生这个光晕效果,在使用painter绘制的时候,设置画笔,可以设置brush,brush可以是各种渐变效果,这个就非常强大了,主要有线性渐变、圆形渐变、锥形渐变,这三种渐变用得好,各种效果都得心应手随手拈来。
feiyangqingyun
2019/10/16
1.5K0
Qt编写自定义控件66-光晕时钟
用PyQt实现透明桌面时钟小部件
#!/usr/bin/env python # -*- coding: utf-8 -*- ''' Created on 2012-4-6   @author: wangxiao ''' import sys from PyQt4 import  QtGui, QtCore   from PyQt4.QtCore import Qt from PyQt4.QtCore import QPoint from PyQt4.QtCore import QTimer from PyQt4.QtCore import
Java学习123
2018/05/16
1.1K0
Qt编写自定义控件54-时钟仪表盘
这个控件没有太多的应用场景,主要就是练手,论美观的话比不上之前发过的一个图片时钟控件,所以此控件也是作为一个基础的绘制demo出现在Qt源码中,我们可以在Qt的安装目录下找到一个时钟控件的绘制,甚至还有qml版本,本控件无非就是一个仪表边框加上时钟分钟刻度再加上时分秒指针,打完收工,我是在此基础上增加了可以设置各种颜色,然后鼠标右键可设置四种效果 普通效果/弹簧效果/连续效果/隐藏效果,弹簧效果的意思是秒钟走动的时候,先移动到超过指定位置,然后又重新弹回来,连续效果的意思是将步长减少,一点点的移动,将秒钟的定时器精度调高。还有一个新增的功能是内置了设置系统时间公共槽函数,支持任意操作系统。
feiyangqingyun
2019/09/25
1.5K0
Qt编写自定义控件54-时钟仪表盘
Qt编写自定义控件62-探探雷达
随着移动互联网的盛行,现在手机APP大行其道,每个人的手机没有十几个APP都不好意思说自己是现代人,各种聊天、购物、直播、小视频等APP,有个陌生人社交的APP叫探探,本人用过几次,当然不是去为了找对象,而是纯粹为了好玩研究下他的U设计和软件逻辑流程等,其中有个雷达控件,单击以后可以搜索附近的异性进行配对,这个雷达控件的效果蛮好的,于是手痒琢磨着用Qt来实现一个,毕竟自己写了150多个控件了,已经上瘾了,对各种效果都如鱼得水,看到各种效果都不自然的想到编码思路等。
feiyangqingyun
2019/10/16
8470
Qt编写自定义控件62-探探雷达
相关推荐
Qt自定义控件之仪表盘的完整实现
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验