pygame实现非图片按钮效果
作者:冰风漫天 发布时间:2021-08-30 23:21:14
标签:pygame,按钮
本文实例为大家分享了pygame实现非图片按钮效果的具体代码,供大家参考,具体内容如下
按钮类程序
# -*- coding=utf-8 -*-
import threading
import pygame
from pygame.locals import MOUSEBUTTONDOWN
class BFControlId(object):
_instance_lock = threading.Lock()
def __init__(self):
self.id = 1
@classmethod
def instance(cls, *args, **kwargs):
if not hasattr(BFControlId, "_instance"):
BFControlId._instance = BFControlId(*args, **kwargs)
return BFControlId._instance
def get_new_id(self):
self.id += 1
return self.id
CLICK_EFFECT_TIME = 100
class BFButton(object):
def __init__(self, parent, rect, text='Button', click=None):
self.x,self.y,self.width,self.height = rect
self.bg_color = (225,225,225)
self.parent = parent
self.surface = parent.subsurface(rect)
self.is_hover = False
self.in_click = False
self.click_loss_time = 0
self.click_event_id = -1
self.ctl_id = BFControlId().instance().get_new_id()
self._text = text
self._click = click
self._visible = True
self.init_font()
def init_font(self):
font = pygame.font.Font(None, 28)
white = 100, 100, 100
self.textImage = font.render(self._text, True, white)
w, h = self.textImage.get_size()
self._tx = (self.width - w) / 2
self._ty = (self.height - h) / 2
@property
def text(self):
return self._text
@text.setter
def text(self, value):
self._text = value
self.init_font()
@property
def click(self):
return self._click
@click.setter
def click(self, value):
self._click = value
@property
def visible(self):
return self._visible
@visible.setter
def visible(self, value):
self._visible = value
def update(self, event):
if self.in_click and event.type == self.click_event_id:
if self._click: self._click(self)
self.click_event_id = -1
return
x, y = pygame.mouse.get_pos()
if x > self.x and x < self.x + self.width and y > self.y and y < self.y + self.height:
self.is_hover = True
if event.type == MOUSEBUTTONDOWN:
pressed_array = pygame.mouse.get_pressed()
if pressed_array[0]:
self.in_click = True
self.click_loss_time = pygame.time.get_ticks() + CLICK_EFFECT_TIME
self.click_event_id = pygame.USEREVENT+self.ctl_id
pygame.time.set_timer(self.click_event_id,CLICK_EFFECT_TIME-10)
else:
self.is_hover = False
def draw(self):
if self.in_click:
if self.click_loss_time < pygame.time.get_ticks():
self.in_click = False
if not self._visible:
return
if self.in_click:
r,g,b = self.bg_color
k = 0.95
self.surface.fill((r*k, g*k, b*k))
else:
self.surface.fill(self.bg_color)
if self.is_hover:
pygame.draw.rect(self.surface, (0,0,0), (0,0,self.width,self.height), 1)
pygame.draw.rect(self.surface, (100,100,100), (0,0,self.width-1,self.height-1), 1)
layers = 5
r_step = (210-170)/layers
g_step = (225-205)/layers
for i in range(layers):
pygame.draw.rect(self.surface, (170+r_step*i, 205+g_step*i, 255), (i, i, self.width - 2 - i*2, self.height - 2 - i*2), 1)
else:
self.surface.fill(self.bg_color)
pygame.draw.rect(self.surface, (0,0,0), (0,0,self.width,self.height), 1)
pygame.draw.rect(self.surface, (100,100,100), (0,0,self.width-1,self.height-1), 1)
pygame.draw.rect(self.surface, self.bg_color, (0,0,self.width-2,self.height-2), 1)
self.surface.blit(self.textImage, (self._tx, self._ty))
主要给按钮实现了:
1.鼠标悬停效果
2.按钮点击效果
3.文本绘制效果
4.点击后事件触发效果
5.按钮的隐藏和显示控制
使用方法:
btn = BFButton(my_surface,my_rect,text=my_label,click=my_method)
在事件响应处
btn.update(event)
在绘图处
btn.draw()
下面附一个例子
# -*- coding=utf-8 -*-
import pygame
from bf_button import BFButton
pygame.init()
screencaption = pygame.display.set_caption('bf control')
screen = pygame.display.set_mode((400,400))
def do_click1(btn):
pygame.display.set_caption('i click %s,ctl id is %s' % (btn._text,btn.ctl_id))
btn.text = 'be click'
def do_click2(btn):
btn.visible = False
def do_click3(btn):
pygame.quit()
exit()
button1 = BFButton(screen, (120,100,160,40))
button1.text = 'Play'
button1.click = do_click1
button2 = BFButton(screen, (120,180,160,40),text='Hide',click=do_click2)
button3 = BFButton(screen, (120,260,160,40),text='Quit',click=do_click3)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
button1.update(event)
button2.update(event)
button3.update(event)
screen.fill((255,255,255))
button1.draw()
button2.draw()
button3.draw()
pygame.display.update()
例子里有两个按钮
第一个按钮事件是修改界面标题和按钮上的文字
第二个按钮事件是隐藏自己
第三个按钮事件是退出
为方便按钮管理,其实可以定一个ButtonGroup类
class BFButtonGroup(object):
def __init__(self):
self.btn_list = []
def add_button(self, button):
self.btn_list.append(button)
def make_button(self, screen, rect, text='Button', click=None):
button = BFButton(screen, rect,text=text,click=click)
self.add_button(button)
def update(self, event):
for button in self.btn_list: button.update(event)
def draw(self):
for button in self.btn_list: button.draw()
这样使用的时候只需要对ButtonGroup进行update和draw
# -*- coding=utf-8 -*-
import pygame
from bf_button import BFButton,BFButtonGroup
pygame.init()
screencaption = pygame.display.set_caption('bf control')
screen = pygame.display.set_mode((400,400))
def do_click1(btn):
pygame.display.set_caption('i click %s,ctl id is %s' % (btn._text,btn.ctl_id))
btn.text = 'be click'
def do_click2(btn):
btn.visible = False
def do_click3(btn):
pygame.quit()
exit()
btn_group = BFButtonGroup()
btn_group.make_button(screen, (120,100,160,40),text='Play',click=do_click1)
btn_group.make_button(screen, (120,180,160,40),text='Hide',click=do_click2)
btn_group.make_button(screen, (120,260,160,40),text='Quit',click=do_click3)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
btn_group.update(event)
screen.fill((255,255,255))
btn_group.draw()
pygame.display.update()
来源:https://blog.csdn.net/zhangenter/article/details/89609946


猜你喜欢
- 前言最近这两天在看自己之前写的代码,所以正好把用过的东西整理一下,单例模式,在日常的代码工作中也是经常被用到,所以这里把之前用过的不同方式实
- 自己在学习过程中也遇到了类似的问题:比如,后台是想做成这样子的:但是实际则是这样的:解决方法:通过隐藏表单控件<input type=
- 只能远程协助的方式。我特意做了一个脚本,用电话指导客户在SSMS里执行一下脚本就可以了1.0的数据库跟1.1的数据库的区别是1.1的数据库里
- SQL1: --1、查看表空间的名称及大小 SELECT t.tablespace_name, round(SUM(bytes / (102
- mixins混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。当组件使用混合对象时
- 一、题目描述本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。X 星球的高科技实验室中整齐地堆放着某批珍贵金属原料。每
- Microsoft SQL Server 2008通过与Microsoft Office的深度集成,为所有人提供了可用的商业智能,以合适的价
- 1.intersect为取多个查询结果的交集;2.查询两个基本时间段内表记录的SQL语句;select * from shengjibiao
- 对于金额的显示,大多情况下需要保留两位小数,比如下面的(表格采用 element-ui):在vue.js中,对文本的处理通常是通过设置一系列
- 微信小程序开发内测一个月.数据传递的方式很少.经常遇到页面销毁后回传参数的问题,小程序中并没有类似Android的startActivity
- JavaScript 代码一般最常见的语法格式就是定义函数 function xxx(){/*code...*/},经常有这样的一大堆函数定
- url标记为变量通过把 URL 的一部分标记为 <variable_name> 就可以在 URL 中添加变量。标记的 部分会作为
- python数据化运营数据化运营的核心是运营,所有数据工作都是围绕运营工作链条展开的,逐步强化数据对于运营工作的驱动作用。数据化运营的价值体
- TensorFlow 2.0之后动态分配显存import tensorflow as tfconfig = tf.compat.v1.Con
- 时区的概念与转换首先要知道时区之间的转换关系,其实这很简单:把当地时间减去当地时区,剩下的就是格林威治时间了。 例如北京时间的18:00就是
- 本文实例讲述了wxPython主框架的简单用法,分享给大家供大家参考。具体如下:程序代码如下:import wx class MyApp(w
- pymysql 是 python 用来操作MySQL的第三方库,下面具体介绍和使用该库的基本方法。1.建立数据库连接通过 connect 函
- “博客就像一本书”这话其实几个月前深圳FB时就有扯到,这也不是什么新概念,也许本身就应该是这样。打个比方,当你拿到一本未看过的书时,理论上你
- 目录一、conftest.py的特点二、conftest.py的使用场景三、conftest.py的生效范围四、conftest.py的的s
- 一,开篇分析Hi,大家!今天这系列文章主要是说说如何开发基于“JavaScript”的插件式开发,我想很多人对”插件“这个词并不陌生,有的人