pygame实现非图片按钮效果


Posted in Python onOctober 29, 2019

本文实例为大家分享了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()

例子里有两个按钮

第一个按钮事件是修改界面标题和按钮上的文字
第二个按钮事件是隐藏自己
第三个按钮事件是退出

pygame实现非图片按钮效果

为方便按钮管理,其实可以定一个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()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 执行字符串表达式函数(eval exec execfile)
Aug 11 Python
Python的Bottle框架中获取制定cookie的教程
Apr 24 Python
使用PDB简单调试Python程序简明指南
Apr 25 Python
Python发送email的3种方法
Apr 28 Python
Python算法应用实战之栈详解
Feb 04 Python
基于python list对象中嵌套元组使用sort时的排序方法
Apr 18 Python
python3 unicode列表转换为中文的实例
Oct 26 Python
Python实现查找最小的k个数示例【两种解法】
Jan 08 Python
基于Python的ModbusTCP客户端实现详解
Jul 13 Python
Tensorflow 多线程与多进程数据加载实例
Feb 05 Python
tensorflow 实现自定义梯度反向传播代码
Feb 10 Python
python实现图像全景拼接
Mar 27 Python
线程安全及Python中的GIL原理分析
Oct 29 #Python
pygame实现贪吃蛇游戏(下)
Oct 29 #Python
python TK库简单应用(实时显示子进程输出)
Oct 29 #Python
pygame实现贪吃蛇游戏(上)
Oct 29 #Python
利用Python小工具实现3秒钟将视频转换为音频
Oct 29 #Python
pygame实现打字游戏
Feb 19 #Python
Python 实现自动导入缺失的库
Oct 29 #Python
You might like
PHP改进计算字符串相似度的函数similar_text()、levenshtein()
2014/10/27 PHP
PHP文件上传判断file是否己选择上传文件的方法
2014/11/10 PHP
php+ajax实现无刷新分页
2015/11/18 PHP
php运行报错Call to undefined function curl_init()的最新解决方法
2016/11/20 PHP
Laravel登录失败次数限制的实现方法
2020/08/26 PHP
javascript 选择文件夹对话框(web)
2009/07/07 Javascript
window.onload 加载完毕的问题及解决方案(上)
2009/07/09 Javascript
jQuery拖动div、移动div、弹出层实现原理及示例
2014/04/08 Javascript
jquery常用特效方法使用示例
2014/04/25 Javascript
如何用JavaScript实现动态修改CSS样式表
2016/05/20 Javascript
JavaScript订单操作小程序完整版
2017/06/23 Javascript
js实现简单数字变动效果
2017/11/06 Javascript
基于substring()和substr()的使用以及区别(实例讲解)
2017/12/28 Javascript
Vue中使用方法、计算属性或观察者的方法实例详解
2018/10/31 Javascript
关于layui的下拉搜索框异步加载数据的解决方法
2019/09/28 Javascript
JS控制GIF图片的停止与显示
2019/10/24 Javascript
Vue Object 的变化侦测实现代码
2020/04/15 Javascript
vue-router的hooks用法详解
2020/06/08 Javascript
python用于url解码和中文解析的小脚本(python url decoder)
2013/08/11 Python
探究Python中isalnum()方法的使用
2015/05/18 Python
python实现将内容分行输出
2015/11/05 Python
使用python实现省市三级菜单效果
2016/01/20 Python
Linux 下 Python 实现按任意键退出的实现方法
2016/09/25 Python
Python元组操作实例分析【创建、赋值、更新、删除等】
2017/07/24 Python
python解析多层json操作示例
2019/12/30 Python
Jupyter notebook 远程配置及SSL加密教程
2020/04/14 Python
阿玛瑞酒店中文官方网站:Amari.com
2018/02/13 全球购物
跑步、骑行和铁人三项的高性能眼镜和服装:ROKA
2018/07/06 全球购物
船舶专业个人求职信范文
2014/01/02 职场文书
社区中秋节活动方案
2014/01/29 职场文书
关于青春的演讲稿三分钟
2014/08/22 职场文书
私营公司诉讼代理委托书范本
2014/09/13 职场文书
2015年春节标语口号
2014/12/09 职场文书
安全教育日主题班会
2015/08/13 职场文书
培训心得体会怎么写
2016/01/25 职场文书
详解Laravel框架的依赖注入功能
2021/05/27 PHP