前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PyQt 自定义窗口部件(一)

PyQt 自定义窗口部件(一)

作者头像
用户6021899
发布2019-08-14 16:45:55
1.1K0
发布2019-08-14 16:45:55
举报

本篇以一个例子来介绍如何通过子类化QWidget或其它内置窗口部件来创建自定义的窗口部件。

程序的功能是用彩色的多个自定义Label来可视化一个二维数组。彩色Label与左边的行号Label、顶部的列号Label,以及右边自定义的colorbar一起,组成了一个相对复杂的自定义的复合控件。

示例代码如下:

代码语言:javascript
复制
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QColor,QPainter,QBrush,QLinearGradient
from PyQt5.QtCore import Qt, pyqtSignal
import numpy as np

def x2RGB(x,LSL=0, USL=1.0):#颜色映射
    r=(x-LSL)/(USL-LSL)
    if r>1:
        return (255, 255, 255)
    elif r>=0.75:
        return (255, int(255*(1-r)*4), 0)
    elif r>=0.5:
        return (int(255*(r-0.5)*4), 255, 0)
    elif r>=0.25:
        return (0, 255, int(255*(0.5-r)*4))
    elif r>=0:
        return (0, int(255*r*4), 255)
    else:
        return (0,0,0)
    
class MapItem(QLabel):
    
    clicksignal = pyqtSignal(int, int, float)
    def __init__(self,row,col, value, LSL =0 , USL = 1, text='', parent=None):
        super().__init__(parent)
        self.row = row
        self.col = col
        self.value = value
        self.setText(text)
        self.LSL = LSL
        self.USL = USL
        self.setBackgroundColor()
        self.setFrameShape(QFrame.Box)
        self.setLineWidth(0)
        #self.setMinimumSize (10,6)
        #self.setMaximumSize (20,12)
    def getRGB(self):
        return x2RGB(self.value, self.LSL,self.USL)
    
    def setBackgroundColor(self):
        self.setStyleSheet("QLabel{background:rgb(%d,%d,%d,250);}"% self.getRGB())
    def enterEvent(self,event):
        #self.setText("%3.3f" % self.value)
        self.setLineWidth(1)
    def leaveEvent(self,event):
        #self.clear()
        self.setLineWidth(0)
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            #pos = event.pos() #QPoint
            #self.cx , self.cy = pos.x(),pos.y()
            self.clicksignal.emit(self.row,self.col,self.value)

class ColorBar(QWidget):#渐变色彩带
    def __init__(self, parent = None):
        super().__init__(parent)
        self.setSize()
        self.currentValue =None
    def setSize(self, width=20, height=500):
        self.width = width
        self.height = height
        self.update()
    def paintEvent(self,QPaintEvent):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing);
        painter.setRenderHint(QPainter.SmoothPixmapTransform)
        painter.save()
        linearGradient = QLinearGradient(0, 0, 0,self.height)
        linearGradient.setColorAt(0.0,Qt.red)
        linearGradient.setColorAt(0.25,Qt.yellow)
        linearGradient.setColorAt(0.5,Qt.green)
        linearGradient.setColorAt(0.75,Qt.cyan)
        linearGradient.setColorAt(1.0,Qt.blue)
        painter.setBrush(QBrush(linearGradient))
        
        painter.drawRect(0,0,self.width,self.height)
        
 
class Map(QWidget):
    def __init__(self, array =np.random.randn(40,25), parent = None):
        super().__init__(parent)
        self.array = array
        self.rows, self.cols = self.array.shape
        #self.setSL(self.array.min(), self.array.max())
        self.setSL(-3.0, 3.0)
        
        gl = QGridLayout()
        gl.setSpacing(0)# 零间距
        for i in range(self.rows):
            rowLabel = QLabel(str(i+1))
            rowLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
            gl.addWidget(rowLabel,i+1,0)
            
            for j in range(self.cols):
                colLabel = QLabel(str(j+1))
                colLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
                gl.addWidget(colLabel, 0, j+1)
                item = MapItem(i+1, j+1,self.array[i,j], self.LSL, self.USL)
                item.clicksignal.connect(self.on_item_clicked)
                gl.addWidget(item,i+1,j+1)
           
            separator = QLabel()
            separator.setFixedWidth(15)
            gl.addWidget(separator, 1, self.cols+1, self.rows,1)
            self.colorbar = ColorBar()
            gl.addWidget(self.colorbar, 1, self.cols+2, self.rows,1)
            
            USL_label =QLabel(str(round(self.USL,2)))
            USL_label.setAlignment(Qt.AlignTop | Qt.AlignLeft)
            gl.addWidget(USL_label, 1, self.cols+3, 1,1)
            LSL_label =QLabel(str(round(self.LSL,2)))
            LSL_label.setAlignment(Qt.AlignBottom | Qt.AlignLeft)
            gl.addWidget(LSL_label, self.rows, self.cols+3, 1,1)
            target_label =QLabel(str(round((self.USL+self.LSL)/2.0, 2)))
            target_label.setAlignment(Qt.AlignBottom | Qt.AlignLeft)
            gl.addWidget(target_label, (self.rows+1)//2, self.cols+3, 1,1)
        self.setLayout(gl)
        self.setMinimumSize (600,500)
        self.setWindowTitle("自定义控件示例")
    def setSL(self, LSL =0, USL =1):
        self.LSL = LSL
        self.USL = USL
    def on_item_clicked(self, row, col, value):
        print(row, col, value)
        self.colorbar.currentValue = value
        self.colorbar.update()
    def resizeEvent(self,event):
        print(self.width(),self.height())
        self.colorbar.setSize(20,self.height())
       
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ui = Map()
    ui.show()
    sys.exit(app.exec_())
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档