wxPython 环形百分比(通过pycairo实现)

需要安装pycario库

pip install pycairo

下面是实现

import cairo
import wx
from io import BytesIO
from PIL import Image
import math

class AnnularPercent(wx.Panel):

    def __init__(self, parent,value:float ,id=wx.ID_ANY, pos=wx.DefaultPosition, size=(100,100), style=wx.TAB_TRAVERSAL, name=wx.PanelNameStr):
        super().__init__(parent, id=id, pos=pos, size=size, style=style, name=name)
        #百分比的值
        self.value=int(value)
        #环的宽度
        self.barSize=16
        #背景颜色
        self.backgroundColour=(1,1,1)
        #环的颜色
        self.barColour=(0,0,1)
        #标题
        self.title=''
        #创建环形百分比的位图
        bitmap = self.OnDraw(self.value,self.barSize)
        self.sBitmap = wx.StaticBitmap(self,bitmap=bitmap)
        #百分比的文本
        self.percentText = wx.StaticText(self.sBitmap,label=str(self.value)+'%',style=wx.ALIGN_CENTER)
        self.percentText.SetBackgroundColour(wx.WHITE)
        self.percentText.SetFont(wx.Font(12,wx.FONTFAMILY_DEFAULT,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_NORMAL))
        self.Update()
        position=(int(size[0]/2-self.percentText.GetSize()[0]/2),int(size[1]/2-self.percentText.GetSize()[1]/2))
        self.percentText.Move(position[0],position[1])
               
    

    def OnDraw(self,value:float,width:int):
        mem_stream = BytesIO()
        ims = cairo.ImageSurface(cairo.FORMAT_ARGB32, self.GetSize()[0], self.GetSize()[1])
        cr = cairo.Context(ims)
        # 设置背景颜色
        cr.set_source_rgb(self.backgroundColour[0], self.backgroundColour[1], self.backgroundColour[2]) 
        cr.paint()  # 应用颜色设置到整个Surface上
        #设置画笔宽度
        cr.set_line_width(width)
        #将画笔移动到的位置
        cr.translate(self.GetSize()[0]/2, self.GetSize()[1]/2)
        #设置画笔颜色
        cr.set_source_rgb(0.9411, 0.9411, 0.9294)
        #画一个圆
        cr.arc(0, 0, self.GetSize()[0]/2-cr.get_line_width()/2, 0, 2*math.pi)
        cr.stroke_preserve()
        #清除上下文路径
        cr.new_path()
        #设置画笔颜色
        cr.set_source_rgb(self.barColour[0],self.barColour[1],self.barColour[2])
        #旋转-90度
        cr.rotate(-0.5*math.pi)
        #以画笔为中心设置一个圆的路径
        cr.arc(0, 0, self.GetSize()[0]/2-cr.get_line_width()/2, 0, value*math.pi)
        #根据路径绘画
        cr.stroke_preserve()
        #将图案以内存流的方式存储
        ims.write_to_png(mem_stream)
        # 可以选择将内存流的位置重置为开始处
        mem_stream.seek(0)
        #从流中读取图片
        image = Image.open(mem_stream)
        #设置wx_Image的长宽
        wx_image = wx.Image(image.width, image.height)
        #设置图片
        wx_image.SetData(image.convert('RGB').tobytes())
        #转换
        bitmap = wx_image.ConvertToBitmap()
        return bitmap
        

    def SetValue(self,value:float):
        """
        设置百分比的值

        Args:
            value (float): 百分比的值
        """
        self.value=int(value)
        bitmap = self.OnDraw(value/100*2,self.barSize)
        self.sBitmap.SetBitmap(bitmap)
        self.percentText.SetLabel(self.title+str(value)+'%')
        self.Update()
        position=(int(self.GetSize()[0]/2-self.percentText.GetSize()[0]/2),int(self.GetSize()[1]/2-self.percentText.GetSize()[1]/2))
        self.percentText.Move(position[0],position[1])
    
    def SetFontSize(self,size:int):
        """
        设置百分比的字体大小

        Args:
            size (int): 字体大小
        """
        self.percentText.SetFont(wx.Font(size,wx.FONTFAMILY_DEFAULT,wx.FONTSTYLE_NORMAL,wx.FONTWEIGHT_NORMAL))
        self.Update()
        position=(int(self.GetSize()[0]/2-self.percentText.GetSize()[0]/2),int(self.GetSize()[1]/2-self.percentText.GetSize()[1]/2))
        self.percentText.Move(position[0],position[1])
    
    def SetBarSize(self,size:int):
        """
        设置环的宽度

        Args:
            size (int): 宽度
        """
        self.barSize=size
        bitmap = self.OnDraw(self.value/100*2,self.barSize)
        self.sBitmap.SetBitmap(bitmap)
    
    def SetImageBackgroundColour(self,R:int,G:int,U:int):
        """
        设置背景颜色

        Args:
            R (int): _description_
            G (int): _description_
            U (int): _description_
        """
        self.backgroundColour=(R/255,G/255,U/255)
        self.percentText.SetBackgroundColour(wx.Colour(R,G,U))
        bitmap = self.OnDraw(self.value/100*2,self.barSize)
        self.sBitmap.SetBitmap(bitmap)  
    
    def SetTitle(self,title:str):
        """
        设置标题

        Args:
            title (str): 标题
        """
        self.title=title+'\n'
        self.percentText.SetLabel(self.title+str(self.value)+'%')
        self.Update()
        position=(int(self.GetSize()[0]/2-self.percentText.GetSize()[0]/2),int(self.GetSize()[1]/2-self.percentText.GetSize()[1]/2))
        self.percentText.Move(position[0],position[1])

    def SetFontColour(self,colour:wx.Colour):
        self.percentText.SetForegroundColour(colour)
    
    def SetBarColour(self,R:int,G:int,U:int):
        """
        设置环的颜色

        Args:
            R (int): _description_
            G (int): _description_
            U (int): _description_
        """
        self.barColour=(R/255,G/255,U/255)
        bitmap = self.OnDraw(self.value/100*2,self.barSize)
        self.sBitmap.SetBitmap(bitmap)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值