实战wxPython:051- 自定义控件

2023-11-07

前面系列文章中,我们介绍了wxPython提供各种的各种控件,在一般情况下可以满足我们开发应用的各种需求。但是在一些情况下,比如对按钮的美化,一个可以显示CPU占用率的控件等等。这首就需要自定义的控件,才能满足要求。

自定义控件可以通过两种方式创建:一种是通过修改或增强现有控件,另一种是我们使用GDI直接创建。下面我们将分别演示采用这两种方式如何在wxPython中实现一个自定义控件。

一、简单的超链接控件

创建一个超链接控件,我们基于
wx.lib.stattext.GenStaticText 控件来构建它,控件的字体用蓝色显示。点击该控件时将调用默认浏览器打开指定的网址。

import wx
from wx.lib.stattext import GenStaticText
import webbrowser

class MyLink(GenStaticText):
    
    def __init__(self, *args, **kw):
        super(MyLink, self).__init__(*args, **kw)

        self.font1 = wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, True, 'Verdana')
        self.font2 = wx.Font(11, wx.SWISS, wx.NORMAL, wx.BOLD, False, 'Verdana')

        self.SetFont(self.font2)
        self.SetForegroundColour("#0000ff")

        self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
        self.Bind(wx.EVT_MOTION, self.OnMouseEvent)

    def SetUrl(self, url):
        self.url = url

    def OnMouseEvent(self, e):
        if e.Moving():
            self.SetCursor(wx.Cursor(wx.CURSOR_HAND))
            self.SetFont(self.font1)
        elif e.LeftUp():
            webbrowser.open_new(self.url)
        else:
            self.SetCursor(wx.NullCursor)
            self.SetFont(self.font2)

        e.Skip()

class SampleHyperlink(wx.Frame):

    def __init__(self, *args, **kw):
        super(SampleHyperlink, self).__init__(*args, **kw)

        self.InitUi()

    def InitUi(self):
        self.SetTitle("实战wxPython: 自定义控件演示")
        self.SetSize(400, 240)

        panel = wx.Panel(self)

        vbox = wx.BoxSizer(wx.VERTICAL)
        hbox = wx.BoxSizer(wx.HORIZONTAL)

        st = GenStaticText(panel, label="连接到Web站点:")
        st.SetFont(wx.Font(11, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, "Verdana"))
        hbox.Add(st, flag=wx.LEFT, border=20)

        link_wid = MyLink(panel, label="bing")
        link_wid.SetUrl("https://cn.bing.com")
        hbox.Add(link_wid, flag=wx.LEFT, border=20)

        vbox.Add(hbox, flag=wx.TOP, border=30)
        panel.SetSizer(vbox)

        self.Centre()

def main():
    app = wx.App()
    sample = SampleHyperlink(None)
    sample.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()

上面的例子中我们使用已有控件,没有绘制任何新的东西,做了一点修改,构建了一个超链接控件。

from wx.lib.stattext import GenStaticText
import webbrowser

导入我们需要的模块,webbrowser 是 python 的标准模块,使用它在默认浏览器中打开超链接。

self.SetFont(self.font2)
self.SetForegroundColour("#0000ff")

修改控件中字体和字体的颜色

if e.Moving():
     self.SetCursor(wx.Cursor(wx.CURSOR_HAND))
     self.SetFont(self.font1)

如果鼠标移到链接上方时,我们显示文本下划线,并将鼠标设置为手型。

elif e.LeftUp():
     webbrowser.open_new(self.url)

如果点击链接,将在默认浏览器打开超链接控件所关联的网址。

 图1:自定义超链接演示

二、一个显示资源使用率的控件

在一些应用中,会需要监测系统资源,温度,内存消耗,CPU使用率等等。如果仅单纯地使用文字(比如CPU 60%),则显得不那么直观,如果使用一定定制化的控件,以直观的图形方式来显示,则会更加一目了然。

import wx

class MyCPU(wx.Panel):
    
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, size=(80, 110))
        self.parent = parent
        self.SetBackgroundColour("black")
        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnPaint(self, e):
        
        dc = wx.PaintDC(self)
        dc.SetDeviceOrigin(0, 100)
        dc.SetAxisOrientation(True, True)

        pos = self.parent.GetParent().GetParent().sel
        rect = pos / 5

        for i in range(1,21):
            if i>rect:
                dc.SetBrush(wx.Brush("#075100"))
                dc.DrawRectangle(10, i * 4, 30, 5)
                dc.DrawRectangle(41, i * 4, 30, 5)
            else:
                dc.SetBrush(wx.Brush("#36ff27"))
                dc.DrawRectangle(10, i * 4, 30, 5)
                dc.DrawRectangle(41, i * 4, 30, 5)

class SampleMyCPU(wx.Frame):

    def __init__(self, *args, **kw):
        super(SampleMyCPU, self).__init__(*args, **kw)

        self.InitUi()

    def InitUi(self):
        self.SetTitle("实战wxPython: 自定义控件演示")
        self.SetSize(400, 240)

        self.sel = 0

        panel = wx.Panel(self)
        centerPanel = wx.Panel(panel)

        self.cpu = MyCPU(centerPanel)

        hbox = wx.BoxSizer(wx.HORIZONTAL)

        self.slider = wx.Slider(panel, value=self.sel, maxValue=100, size=(-1,100), style=wx.VERTICAL|wx.SL_INVERSE)
        self.slider.SetFocus()

        hbox.Add(centerPanel, 0, wx.LEFT|wx.TOP, 20)
        hbox.Add(self.slider, 0, wx.LEFT|wx.TOP, 30)

        self.Bind(wx.EVT_SCROLL, self.OnScroll)

        panel.SetSizer(hbox)

        self.Centre()

    def OnScroll(self, e):
        self.sel = e.GetInt()
        self.cpu.Refresh()

def main():
    app = wx.App()
    sample = SampleMyCPU(None)
    sample.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()

上面的例子里,我们创建一个控件,它继承自wx.Panel。在其上绘制了一些矩形,矩形的颜色取决于滑块控件的值,可以为深绿或者亮绿。

dc.SetDeviceOrigin(0, 100)
 dc.SetAxisOrientation(True, True)

上面的例子里,我们创建一个控件,它继承自wx.Panel。在其上绘制了一些矩形,矩形的颜色取决于滑块控件的值,可以为深绿或者亮绿。

dc.SetDeviceOrigin(0, 100)
 dc.SetAxisOrientation(True, True)

将坐标系设置为笛卡尔坐标系,让绘制更加直观。

pos = self.parent.GetParent().GetParent().sel
rect = pos / 5

获取sizer的值。一列有20个小矩形,滑块的变化范围为0到100 。rect参数保存将滑块值转变成需要用亮绿色绘制的矩形数目。

 for i in range(1,21):
     if i>rect:
         dc.SetBrush(wx.Brush("#075100"))
         dc.DrawRectangle(10, i * 4, 30, 5)
         dc.DrawRectangle(41, i * 4, 30, 5)
     else:
         dc.SetBrush(wx.Brush("#36ff27"))
         dc.DrawRectangle(10, i * 4, 30, 5)
         dc.DrawRectangle(41, i * 4, 30, 5)

这里我们绘制了40个矩形,每列20个。如果矩形数目大于rect的值,用暗绿色绘制,否则用亮绿色绘制。

 图2:自定义控件之CPU占用率演示

三、本文知识点

  • 什么时候需要自定义控件。
  • 创建自定义控件的两种方式。
  • 使用EVT_PAINT事件。

前一篇:实战wxPython:050 - 动态添加和删除控件

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实战wxPython:051- 自定义控件 的相关文章

随机推荐

  • Vue 项目中引入 element-ui 报 Cannot find module ‘babel-preset-es2015‘

    解决方法1 因为报的是module缺失 所以直接下载该模块即可 npm install babel preset es2015 save dev 解决方法2 出现这种问题可能是因为之前element ui全部引入了 按需引入能解决该问题 先
  • windows补丁下载地址

    https support microsoft com zh cn help 4041678 windows 7 update kb4041678
  • 每天学python- 罗马数字转整数

    题目描述 罗马数字包含以下七种字符 I V X L C D 和 M 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如 罗马数字 2 写做 II 即为两个并列的 1 12 写做 XII 即为 X II
  • 论文学习——Tune-A-Video

    Tune A Video One Shot Tuning of Image Diffusion Models for Text to Video Generation Abstract 本文提出了一种方法 站在巨人的肩膀上 在大规模图像数据
  • LeetCode:214. 最短回文串

    给定一个字符串 s 你可以通过在字符串前面添加字符将其转换为回文串 找到并返回可以用这种方式转换的最短回文串 示例 1 输入 s aacecaaa 输出 aaacecaaa 示例 2 输入 s abcd 输出 dcbabcd 提示 0 lt
  • 结构体学习笔记

    结构体笔记 声名结构的形式 struct point int x int y p1 p2都是point 里面有x和y struct point p1 p2 struct int x int y p1 p2 p1 p2都是一种无名结构 里面有
  • C++的一些概念 面向对象程序的基本特点

    本节主要介绍一些基本概念 有关于面向对象程序的基本特点 Markdown和扩展Markdown简洁的语法 抽象 对某一类对象的共同属性和行为进行概括 形成类 首先注意问题的本质和描述 其次是实现的过程或细节 数据抽象 描述某类对象的属性或状
  • Network、互联网、Internet和Web的区别和联系

    1 首先Network是最广的 就是汉语里面最广的 网络 如各种电网 神经网络等 2 其次 是互联网 因特网和其他类似的由计算机相互连接而成的大型网络系统都可算是互联网 Internet是互联网中最大的一个 3 再者 是Internet 中
  • powershell新手向,新建、删除文件及对文件添加内容

    一 在当前目录下 新建文件 New item空格1 文件名 doc 文件类型后缀doc txt等 New item 1 doc 删除文件 remove item空格1 文件名 doc 文件类型后缀doc txt等 remove item 1
  • C#——初识Console

    1 console writeline 显示的信息 参数为 想要在用户界面显示的信息 参数的形式可以用到 和占位符 连接符 字符串 变量 在加号两边有一边是字符串 那么 就起到了连接的作用 例如 console writeline 您好 n
  • break停止for....in和for....of循环?

    break可以停止for循环 那么是否可以停止for in和for of循环 for in let names id 1 name sdf id 2 name sdf for var i in names if i id 1 break c
  • Mysql中Unsigned和Zerofill数据型的使用(细节也很重要啊)

    一 今天开同事在使用Mysql的时候 错误使用了Unsigned和Zerofill了 大概是不是蛮懂这两个使用场景吧 很多东西 细节都是很重要的 不能随便用的 decimal是浮点型 使用Unsigned是错误的 二 什么是unsigned
  • 如何使用transformers的trainer.train()函数如何训练自定义Bert的下游模型,并进行评估

    要使用 Transformers 中的 Trainer 训练自定义的 BERT 下游模型 并进行评估 需要进行以下步骤 准备数据集 将原始数据集转换为适合 BERT 模型训练的格式 例如使用 tokenizer 对文本进行编码 将标签转换为
  • 尼姆游戏(聪明版/傻瓜式•人机对战)(代码优化/修复错漏/友好显示)

    对之前发的 练习 尼姆游戏 作了优化 代码精简 修正错漏 添加了玩家选择 微调了输出显示 不能更改前面发的 重发于此 CSDNapp更新到最新版本后 不可以对已发博文作出修改了 修改错漏则只能重发博文 浪费资源啊 练习 尼姆游戏 添加了玩家
  • axios访问后台404_使用 axios 后台无法接收到数据的解决方案

    如果想看排错思路的 可以看完踩坑经历 想直接要结果的 可以直接看解决方案 踩坑经历 最近我在使用 SSM Vue 做自己的小项目 Dao层 和 Service层 之类的代码已经写好了 就差 Controller层 和 Vue 的视图层还没有
  • jdk17安装及环境变量的配置

    jdk17安装及环境变量的配置 跳转oracle官方页面 点击直接下载Windowsjdk17 1 点击下载好的文件 然后下一步 2 在该页面中可以更改jdk的安装目录 默认是C盘 3 安装成功 安装成功之后 对其进行环境变量的配置 4 我
  • RFID系统在物流仓储中的应用

    RFID系统是一种无线识别技术 最近成为物流仓储行业的热门话题 本文将介绍RFID系统在物流仓储中的应用 包括如何使用RFID标签进行物流管理 如何使用RFID技术提高仓库的安全性 并细述RFID技术在物流仓储中的优势 除此之外 本文还会探
  • 华为od机考真题-报数游戏

    while 1 try m int input if 1 gt m or m gt 100 print ERROR else 模拟1 100的圈 nums
  • keil使用指南

    keil使用指南 1 项目的创建 头文件 1 项目的创建 1 首先创建文件夹 2 打开keil软件而后 创建新项目 并定位到1创建的文件夹 3 创建文件 并将文件添加到项目中 4 勾选hex文件生成 5 项目demo编写与编译 编译当前所在
  • 实战wxPython:051- 自定义控件

    前面系列文章中 我们介绍了wxPython提供各种的各种控件 在一般情况下可以满足我们开发应用的各种需求 但是在一些情况下 比如对按钮的美化 一个可以显示CPU占用率的控件等等 这首就需要自定义的控件 才能满足要求 自定义控件可以通过两种方