python3+PyQt5实现自定义流体混合窗口部件

yipeiwu_com5年前Python基础

本文通过Python3+PyQt5实现自定义部件–流体混合窗口部件。通过逻辑(窗口)坐标绘制而成。调用setWindow,所有的绘制工作都会根据逻辑坐标系发生。

#!/usr/bin/env python3

from PyQt5.QtCore import (QPointF, QSize, Qt,pyqtSignal)
from PyQt5.QtWidgets import (QApplication,
 QFrame, QLabel,
 QSizePolicy, QSpinBox, QWidget)
from PyQt5.QtGui import QColor,QPainter,QFontMetricsF,QBrush,QLinearGradient,QPolygon,QPolygonF

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
 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)
 painter.setRenderHint(QPainter.Antialiasing)
 side = min(self.width(), self.height())
 painter.setViewport((self.width() - side) / 2,
    (self.height() - side) / 2, side, side)
 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))
 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))
 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))
 painter.drawPolygon(QPolygonF(
  [QPointF(cx, cy),QPointF(fx, fy),QPointF(gx, gy), QPointF(hx, hy),QPointF(ix, iy)]))

 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设计】。

相关文章

python使用socket向客户端发送数据的方法

本文实例讲述了python使用socket向客户端发送数据的方法。分享给大家供大家参考。具体如下: import socket, sys port = 55555 host = 'l...

Python3分析处理声音数据的例子

将音频文件拷贝到程序所在目录即可。 如下所示: #!/usr/bin/env python # encoding: utf-8 """ @Company:华中科技大学电气学院聚变与等...

跟老齐学Python之网站的结构

跟老齐学Python之网站的结构

很早很早的时候,computer这个东西习惯于被称之为计算机,因为它的主要功能是完成一些科学计算的东西,我记得自己鼓捣它的时候,就是计算,根本就没有想到它有早一日还可以用来做别的。后来另...

Python+opencv+pyaudio实现带声音屏幕录制

基于个人的爱好和现实的需求,决定用Python做一个屏幕录制的脚本。因为要看一些加密的视频,每次都要登录,特别麻烦,遂决定用自己写的脚本,将加密视频的播放过程全程录制下来,这样以后看自己...

利用Python进行异常值分析实例代码

利用Python进行异常值分析实例代码

前言 异常值是指样本中的个别值,也称为离群点,其数值明显偏离其余的观测值。常用检测方法3σ原则和箱型图。其中,3σ原则只适用服从正态分布的数据。在3σ原则下,异常值被定义为观察值和平均值...