wxPython和pycairo练习记录1

给粒子物理萌新的Geant4保姆级入门:从看懂B1示例代码到跑通第一个模拟 本文为粒子物理初学者提供Geant4的保姆级入门指南,从解析B1示例代码到跑通第一个模拟。详细介绍了环境准备、代码解析、可视化系统实战及扩展模拟的方法,帮助新手快速掌握Geant4的基本概念和工具包使用。 阅读详情

wxPython和pycairo练习记录1

学习,分为学和习,学完了不练习,让大脑觉得不重要,会忘记。所以,我决定练习并记录 wxPython 和 pycairo 的代码编写,如果你也想试试请自行配置环境。

wxPython官网:https://www.wxpython.org/
pycairo官网:https://cairographics.org/pycairo/

本机环境:
WIN10
Python(3.8.7)
wxPython(4.1.1 msw (phoenix) wxWidgets 3.1.5) pycairo(1.21.0)

因为没有相关完整项目经验,所以不能把全局都设计好,先从基本的迭代。把可能经常需要用到的,几乎不会变的公共部分先写出来,主要参考zetcode的wxPython教程https://zetcode.com/wxpython/ 。

1.1 导入模块

把练习代码放到一个模块,测试不同的练习只改动这里的模块名。

import wx
import wx.lib.wxcairo
import cairo
import example # 用来编写练习代码的模块

1.2 设置全局变量

感觉很多概念都是用来避免命名冲突的,局部变量、全局变量、闭包、内置变量、类属性、对象属性,当然作用还有便于权限控制,降低耦合。

说到属性,很多教程解释类属性和对象属性的区别,就是讲在哪声明,讲在哪存储,讲怎么调用,看了也还是不理解。后来终于找到一个能看懂的说法,类属性就是跟类绑定的属性,对象属性就是跟对象绑定的属性。

非重点的内容可以先当作常识,不然很快就会沿着各种分支偏离目标,例如为什么要避免使用全局变量?

class cv:
    """
    常量,用类属性避免使用全局变量
    """
    # 刷新定时器 id
    TIMER_ID = 1
    # 刷新间隔时间 毫秒, FPS (frames per second) 就是 1000 // SPEED
    SPEED = 10
    # 面板尺寸
    BOARD_WIDTH = 800
    BOARD_HEIGHT = 600

1.3 主面板编写

数据的更新和图像的重新绘制分开处理,如响应坦克更新位置操作,只更新位置数据,在重新绘制的时候,读取新的位置数据并绘制坦克。

class Board(wx.Panel):
    def __init__(self, parent):
        super(Board, self).__init__(parent=parent, style=wx.WANTS_CHARS) # wx.WANTS_CHARS 可接收键盘事件
        self.SetDoubleBuffered(True) # 双缓冲,防止闪烁
        self.InitVariables()
        self.BindEvent()

1.4 完整代码

用一个定时器刷新数据和图像,初始公共部分仅绘制黑色背景。

# -*- coding: utf-8 -*-
import wx
import wx.lib.wxcairo
import cairo
import example # 用来编写练习代码的模块


class cv:
    """
    常量,用类属性避免使用全局变量
    """
    # 刷新定时器 id
    TIMER_ID = 1
    # 刷新间隔时间 毫秒, FPS (frames per second) 就是 1000 // SPEED
    SPEED = 10
    # 面板尺寸
    BOARD_WIDTH = 800
    BOARD_HEIGHT = 600


class Board(wx.Panel):
    def __init__(self, parent):
        super(Board, self).__init__(parent=parent, style=wx.WANTS_CHARS) # wx.WANTS_CHARS 可接收键盘事件
        self.SetDoubleBuffered(True) # 双缓冲,防止闪烁
        self.InitVariables()
        self.BindEvent()

    def InitVariables(self):
        # 初始化变量
        self.InitSceneObjects()
        # 设置定时器
        self.timer = wx.Timer(owner=self, id=cv.TIMER_ID)
        self.timer.Start(cv.SPEED)

    def InitSceneObjects(self):
        # 初始化场景中对象变量,如坦克实例、计分栏初始分数等
        self.sceneObjects = []

    def BindEvent(self):
        # 绑定事件
        self.Bind(wx.EVT_TIMER, self.OnTimer, id=cv.TIMER_ID)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)

    def OnTimer(self, e):
        # 处理更新事件,定时更新变量,刷新重绘
        for so in self.sceneObjects:
            so.Update()

        self.CheckStrategies()
        self.Refresh() # 重绘,执行OnPaint

    def CheckStrategies(self):
        # 碰撞检测等
        pass

    def OnPaint(self, e):
        # 处理重绘事件
        dc = wx.PaintDC(window=self) # device context,设备上下文,相当于画布或虚拟的屏幕,
        ctx = wx.lib.wxcairo.ContextFromDC(dc) # 获取 cairo.Context 对象,同上

        self.DrawBackground(ctx)
        self.DrawSceneObjects(ctx)

    def DrawBackground(self, ctx):
        # 填充黑色背景
        ctx.set_source_rgb(0, 0, 0)
        ctx.paint()

    def DrawSceneObjects(self, ctx):
        # 绘制要显示的对象,如坦克、计分栏等
        pass

    def OnKeyDown(self, e):
        # 处理键盘按下事件
        pass

    def OnKeyUp(self, e):
        # 处理键盘弹起事件
        pass


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)
        Board(parent=self)
        self.Center() # 窗口在屏幕居中


def main():
    app = wx.App()
    frame = MyFrame(parent=None, title="cairotest", size=(cv.BOARD_WIDTH, cv.BOARD_HEIGHT))
    frame.Show()
    app.MainLoop()


if __name__ == "__main__":
    main()

1.5 拆分公共部分

上面的文件,作为单独的文件运行没有问题,但是我们还要进一步分离出变化和不变化的部分。
期望的结果是,只需要在example中写练习用的代码,其他基础部分都不变。而example中需要继承cv和Board,那么需要把cv和Board单独分离到一个文件作为模板,另外还需要一个文件写主要执行流程。

# -*- coding: utf-8 -*-
# main.py

import wx
from example import cv, Board


class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)
        Board(parent=self)
        self.Center() # 窗口在屏幕居中


def main():
    app = wx.App()
    frame = MyFrame(parent=None, title="cairotest", size=(cv.BOARD_WIDTH, cv.BOARD_HEIGHT))
    frame.Show()
    app.MainLoop()


if __name__ == "__main__":
    main()

# -*- coding: utf-8 -*-
# board.py

import wx
import wx.lib.wxcairo


class cv:
    """
    常量,用类属性避免使用全局变量
    """
    # 刷新定时器 id
    TIMER_ID = 1
    # 刷新间隔时间 毫秒, FPS (frames per second) 就是 1000 // SPEED
    SPEED = 10
    # 面板尺寸
    BOARD_WIDTH = 800
    BOARD_HEIGHT = 600


class Board(wx.Panel):
    def __init__(self, parent):
        super(Board, self).__init__(parent=parent, style=wx.WANTS_CHARS) # wx.WANTS_CHARS 可接收键盘事件
        self.SetDoubleBuffered(True) # 双缓冲,防止闪烁
        self.InitVariables()
        self.BindEvent()

    def InitVariables(self):
        # 初始化变量
        self.InitSceneObjects()
        # 设置定时器
        self.timer = wx.Timer(owner=self, id=cv.TIMER_ID)
        self.timer.Start(cv.SPEED)

    def InitSceneObjects(self):
        # 初始化场景中对象变量,如坦克实例、计分栏初始分数等
        self.sceneObjects = []

    def BindEvent(self):
        # 绑定事件
        self.Bind(wx.EVT_TIMER, self.OnTimer, id=cv.TIMER_ID)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)

    def OnTimer(self, e):
        # 处理更新事件,定时更新变量,刷新重绘
        for so in self.sceneObjects:
            so.Update()

        self.CheckStrategies()
        self.Refresh() # 重绘,执行OnPaint

    def CheckStrategies(self):
        # 碰撞检测等
        pass

    def OnPaint(self, e):
        # 处理重绘事件
        dc = wx.PaintDC(window=self) # device context,设备上下文,相当于画布或虚拟的屏幕,
        ctx = wx.lib.wxcairo.ContextFromDC(dc) # 获取 cairo.Context 对象,同上

        self.DrawBackground(ctx)
        self.DrawSceneObjects(ctx)

    def DrawBackground(self, ctx):
        # 填充黑色背景
        ctx.set_source_rgb(0, 0, 0)
        ctx.paint()

    def DrawSceneObjects(self, ctx):
        # 绘制要显示的对象,如坦克、计分栏等
        pass

    def OnKeyDown(self, e):
        # 处理键盘按下事件
        pass

    def OnKeyUp(self, e):
        # 处理键盘弹起事件
        pass

# -*- coding: utf-8 -*-
# example.py
# 这个例子我修改了窗口尺寸和添加了smilebasic文字显示

import wx
import wx.lib.wxcairo
import cairo
import board


class cv(board.cv):
    """
    常量,用类属性避免使用全局变量
    """
    # 面板尺寸
    BOARD_WIDTH = 600
    BOARD_HEIGHT = 400


class Board(board.Board):
    def DrawBackground(self, ctx):
        super().DrawBackground(ctx)

        text = "SmileBasic"
        ctx.set_font_size(40)
        _, _, w, h, _, _ = ctx.text_extents(text)
        x = (cv.BOARD_WIDTH - w) // 2
        y = (cv.BOARD_HEIGHT - h) // 2

        # 文字是以首个字左下角坐标定位,而矩形是以左上角定位,y轴相差文字的高度,不需要考虑线条宽度。
        # 另外PaintDC是不含标题栏的。
        ctx.rectangle(x - 10, y - 10 - h, w + 20, h + 20)
        ctx.set_source_rgb(1, 0, 0)
        ctx.stroke()

        ctx.move_to(x, y)
        ctx.set_source_rgb(1, 1, 1)
        ctx.show_text(text)

1.6 效果

在这里插入图片描述

【OpenCV实战】简洁易懂的车牌号识别Python+OpenCV实现“超详解”(含代码) 简洁易懂的车牌号识别Python实现(含代码)1、整体思路2、代码详解 1、整体思路 2、代码详解 阅读详情

相关推荐

eDP接口信号组成认识

eDP接口信号主要由Main Link、AUXCH与HPD三部分组成,如下图所示。 Main Link:表示主通道,用来传输各类型视频数据和音频数据; AUX CH:表示辅助通道,用于传输低带宽需求的数据,以及链路管理和设备控制信号; HPD:表示热插拔检测通道。 Main Link南1~4对数据线组成,每对数据线都是一对差分线。对于一款液晶屏而言,Main Link具体需几对数据线,这取决于屏幕的分辨率和彩色位数。 在该通道中传送的信号有视频像素信号、视频定时信号、视频格式信号、比特/像素及

精诚所至 2万+

python画曲线代码_在Python里画曲线

在Python里画曲线,常常用到wx.DC(设备上下文)和wx.Pen画笔,有可能需要下面的资源:wx.BufferedDC:用于缓存一套绘画命令,直到命令完整并准备在屏幕上绘画。这防止了显示中不必要的闪烁。wx.BufferedPaintDC:和wx.BufferedDC一样,但是只能用在一个wx.PaintEvent的处理中。仅临时创建该类的实例。wx.ClientDC:用于在一个窗口对象上绘...

weixin_39578867的博客 482

教程: 将 SolidWorks 设计导出为 ROS 的 URDF

请按照以下步骤应用自定义徽标纹理:创建徽标材质文件:techniquepass材质名称:测试/材质颜色属性:环境、漫反射、镜面和发射都设置为白色(1 1 1 1),这意味着该材质看起来完全是白色的。纹理 在表面应用纹理图像 logo.png。将材质文件复制到 gazebo matrial:复制徽标图像:将 “徽标 ”替换为机器人上徽标所在位置的适当参考值。按照以上步骤,您就可以在 Gazebo 中为机器人添加自定义材质和纹理,包括徽标。

机器人控制与仿真应用 2459

python wxpython 学习示例 (1) 参考收藏

提示:python wxpython 学习示例 (1) 参考收藏 文章目录前言一、python wxpython 学习示例 (1) 参考收藏1.python wxpython hello word2.python wxpython Small editor3.python wxpython Small editor + Menu+ about +exit4.python wxpython Small editor + Menu+ about +exit + output5.python wxpython.

weixin_43709139的博客 3514

西南科技大学模拟电子技术实验七(集成运算放大器的非线性应用)预习报告

将电位器Rp调至中心位置,用双综示波器观察并绘制方波U0的波形,测量其幅值和频率;将电位器RP调至中心位置,用示波器观察并绘制锯齿波U0的波形,记录;示波器基线调零,Ui输入1000HZ、幅值为2V的正弦信号,观察并记录Ui与U0波形,读出图中波形跳变时的Ui临界值;用万用表电位器RP调至预测结果位置,用示波器观察并描绘三角波输出U0及方波输出uo’,测其幅值、频率及Rp值,记录之。示波器基线调零,U输入1000HZ、幅值为2V的正弦信号,观察UI与U0波形。理论算法公式:当Ui

Welcome To My6n Blog 3937

第六节 LLaVA模型数据处理源码解读(input_ids/labels/attention_mask/image,上篇)

本篇文章直接介绍llava模型数据加工部分,整体结构说明llava多模态模型输入数据格式,其中包含input_ids/labels/attention_mask与image格式,并给出对应代码位置与整个数据加工流程。最重要,通过debug给出数据解释与代码解读,也通过一个真实数据给出模型输入格式说明。当你阅读完此篇文章,绝对透彻理解llava数据加工过程与内容。显然,一篇博客是无法呈现整个数据细节,我将继续下篇博客呈现数据细节处理。result = input.ne(3) # torch.ne函数调用。

weixin_38252409的博客 3196

VS2019配置wxWidgets v3.1.5开发环境

编译wxWidgets库 如果只是使用wxWidgets DLL库可以省略编译这一步,直接下载编译好的库 http://wxwidgets.org/downloads/ 点击"Download Windows Binarires" 需要下载Header Files, Development Files供开发使用 下载Release DLLs给发布程序使用 下载源码包,需要要git,否则第三方库源码为空,比如expat, zlib等。不嫌麻烦也可以一个一个在wxWidgets的githu

Hansel的专栏 3168

用 ABAP 驾驭 OAuth 2.0:从 Authorization Code 到 SAML Bearer 的全栈落地指南

ABAP平台OAuth 2.0客户端开发实践 本文为SAP开发者详细解析ABAP平台内置OAuth 2.0客户端的使用方法,涵盖四种授权流的最佳实践: 授权流选择: Authorization Code:适用于用户交互场景 SAML 2.0 Bearer:适合已有SAML体系的企业 Client Credentials:系统间通信 Password Credentials:过渡方案(不推荐) 配置流程: 通过SE80定义Client Profile 使用SOAUTH2_CLIENT/OA2C_CONFIG配

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 309

[祖传代码] 我在python3下用wxpython作GUI(1)先来做一个有菜单栏的小应用

我想通过一些例子,学习wxpython。这篇博客是根据官方文档 https://wiki.wxpython.org/Getting Started 模仿的一些例子,如果还想查看更多官方文档,可以参考:https://wiki.wxpython.org/。 安装wxpython :: windows 命令行下执行下面的命令,其中 U 表示安装并升级 pip install -U wxpython ...

uncompleted code —— 代码片段 537

QT如何使用CTK插件搭建应用程序框架?

CTK框架,QT框架,插件系统

cs821984831的博客 736

使用静态库在嵌入式系统中进行开发

静态库是一种包含预编译对象代码的文件,它可以与应用程序链接在一起,并在编译时将库的代码复制到最终的可执行文件中。静态库是包含预编译对象代码的文件,可以与应用程序链接在一起,并在编译时将库的代码复制到最终的可执行文件中。需要注意的是,由于嵌入式系统的资源限制,开发人员应该仔细选择需要包含在静态库中的功能,并避免引入不必要的依赖关系。需要注意的是,由于嵌入式系统的资源限制,开发人员应该仔细选择需要包含在静态库中的功能,并避免引入不必要的依赖关系。的静态库文件,可以在嵌入式系统的应用程序中使用它了。

ZrElixir的博客 205

Python wxPython基本教程

Python wxPython在资源上比较小,而且官方文档也不好找,wxPython在python 2.x和python 3.x安装上有区别: 以下为python3.x安装为例: 1.网上下载whl文件安装:路径:https://wxpython.org/Phoenix/snapshot-builds/ 文件名解释: wxPython_Phoenix-3.0.3.dev2812+b3485d

Xy-Huang的博客 1万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

wxPython和pycairo练习记录10

一开始考虑不全面,后面写的时候就只有一个心思,烂代码,完成就好。代码创建控件实例是个痛苦的过程,因为做的基本都是重复的事,能用循环的最好写进循环,熟悉控件后推荐用 wxFromBuilder。

SmileBasic的博客 568

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

wxPython和pycairo练习记录2

因为要实现图像的显示和交互,今天添加两个基础的图像容器类。

SmileBasic的博客 971

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

wxPython和pycairo练习记录8

经过障碍物的编写,发现需要停止前进并重新梳理一下。1.新的检测项加入时,已经在向混乱发展。是时候用上封装变化的编程工具,用策略模式或状态模式重写。2.显示,在基类引入层级和优先级,不同层低层级先绘制,同层高优先级先绘制。3.范围的碰撞和本身的碰撞的作用顺序。还有像已经实现的碉堡,只有一个外层碰撞区域,如果要多加几层呢,最外层出现坦克,射速为1,再近一层射速为5,最近一层射速达到20。

SmileBasic的博客 387

wxPython和pycairo练习记录3

现在的感觉像是学武功的人,对着一本秘籍瞎练,没有师父,也没有参照,不知对错。之前写的有很多混乱的地方,比如主 fps 对对象 fps 的作用,比如 MovieClip 对象 surface 的宽高及对继承方法 GetWidth 的影响,等等没有影响现有结果的地方。唯一检验的标准是,实现出想要的效果。这次想实现的是,在四个角生成敌方坦克,自动行驶,相互碰撞转向。...

SmileBasic的博客 354

wxPython和pycairo练习记录6

这次想要实现障碍物。

SmileBasic的博客 330

wxPython和pycairo练习记录17

按理说素材图片虽然是位图但因为是纯色,手动缩放显示都没问题,不知道为什么会这样,网上解释说是"Cairo 默认使用线性插值算法进行缩放操作,而线性插值会导致图像像素的颜色被平滑地混合,从而造成图像的模糊效果。不要当过程完美主义者,很容易自我攻击。素材中的 characters.gif,用 wx.Image 加载后,调用 GetAlpha 方法发现得到不正确的透明通道值,而且 HasAlpha 得到的结果是 False,因为没有正确解释透明通道数据,RGB 数据也错了,加载后整个图片都变成了粉色。

SmileBasic的博客 897

wxPython和pycairo练习记录9

想要实现的效果是,同时按下多个方向,无论松开或按下其他键,总是响应剩余最近按下的键,这里直接用列表存储处在按下状态的按键代码。测试 wxPython 按下多个方向后松开最近按下的,之前保持按住的会失效。那就不能靠按键直接改变坐标,只改变速度方向,然后坐标的计算移动交给定时器刷新。射击按键行为也交给定时器,只改变状态,不执行操作。效果看起来还不错。之后可以看到,坦克和砖墙碰撞时的回弹问题也没有了。...

SmileBasic的博客 449

wxPython和pycairo练习记录13

之前虽然通过设置窗口样式去掉了标题栏,但是背景看起来还是有些碍眼。通过 SetTransparent 只能调整整体透明度,文字和背景都透明了。希望实现的效果是背景透明,而文字不透明。

SmileBasic的博客 560

wxPython和pycairo练习记录19

pygame.mixer.Channel 这里的声道和音频文件的声道含义不一样,这里的声道是指播放通道,0 为第一个声道。在 wxPython 中 wx.adv.Sound 只能播放 WAV 格式的文件,或者在 UI 中调用 wx.media.MediaCtrl 控件,但素材里的音频还有 OGG 格式的,没法用 wxPython 在后台播放。测试的时候,只有设置同步播放 wx.adv.SOUND_SYNC 才有声音,后面再修改,所有代码都完成了如果还是这样就再创建一个线程来播放声音。

SmileBasic的博客 1044

wxPython和pycairo练习记录12

过年在家刷视频号直播时发现弹幕互动游戏,挺有意思的,刚好诠释了反射的用法。想要自己也做一个弹幕游戏,于是就有了这个基本的需求,先让弹幕滚动显示出来,直播时可以当作小挂件。

SmileBasic的博客 434

wxPython和pycairo练习记录4

继续写碰撞检测。

SmileBasic的博客 306

wxPython和pycairo练习记录11

了解事件机制是学习 wxPython 绕不过去的坎,结合各种资料和个人理解整理了一下,如果有问题请留言指出。

SmileBasic的博客 587

wxPython和pycairo练习记录14

继续之前的坦克游戏。碰撞检测技术像什么四叉树、凸包,看不懂啊,所以先从成熟的 pygame 框架里抠出几个能用到的。之前写坦克游戏并没有明确组合多个 Sprite 对象,还是先只考虑独立的 Sprite 吧。这样,需要用到和改写的方法只有 `collide_rect、collide_rect_ratio、collide_circle、collide_circle_ratio、collide_mask`。

SmileBasic的博客 263

wxPython和pycairo练习记录7

继续写障碍,选几个典型的来写。有个问题,有调用图片文件的类,每次生成新实例,都重新加载一次图片。应该把素材统一加载为全局变量,具体使用只需要引用素材变量。积重难返,记住这个教训,以后写其他的再注意吧。...

SmileBasic的博客 503
上一篇: 去国外卖友链赚差价?
下一篇: wxPython和pycairo练习记录2
SmileBasic
博客等级 码龄5年 347粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值