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正则表达式操作指南(re使用)
Sep 06 Python
在Debian下配置Python+Django+Nginx+uWSGI+MySQL的教程
Apr 25 Python
Python编程之属性和方法实例详解
May 19 Python
利用Python yagmail三行代码实现发送邮件
May 11 Python
Python 爬取携程所有机票的实例代码
Jun 11 Python
OPENCV去除小连通区域,去除孔洞的实例讲解
Jun 21 Python
ERLANG和PYTHON互通实现过程详解
Jul 05 Python
Python将二维列表list的数据输出(TXT,Excel)
Apr 23 Python
Jmeter HTTPS接口测试证书导入过程图解
Jul 22 Python
详解python tcp编程
Aug 24 Python
Anaconda的安装与虚拟环境建立
Nov 18 Python
python进行二次方程式计算的实例讲解
Dec 06 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桌面中心(三) 修改数据库
2007/03/11 PHP
php实现无限级分类实现代码(递归方法)
2011/01/01 PHP
PHP Session 变量的使用方法详解与实例代码
2013/09/11 PHP
PHP生成随机数的方法实例分析
2015/01/22 PHP
CodeIgniter自定义控制器MY_Controller用法分析
2016/01/20 PHP
Smarty变量用法详解
2016/05/11 PHP
Mac系统完美安装PHP7详细教程
2017/06/06 PHP
PHP的cookie与session原理及用法详解
2019/09/27 PHP
基于PHP的微信公众号的开发流程详解
2020/08/07 PHP
js精度溢出解决方案
2012/12/02 Javascript
js实现的复制兼容chrome和IE
2014/04/03 Javascript
AMD异步模块定义介绍和Require.js中使用jQuery及jQuery插件的方法
2014/06/06 Javascript
全面解析DOM操作和jQuery实现选项移动操作代码分享
2016/06/07 Javascript
Vue.js学习教程之列表渲染详解
2017/05/17 Javascript
JavaScript之排序函数_动力节点Java学院整理
2017/06/30 Javascript
Angular模板表单校验方法详解
2017/08/11 Javascript
基于JavaScript实现五子棋游戏
2020/08/26 Javascript
浅谈vue项目4rs vue-router上线后history模式遇到的坑
2018/09/27 Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
2018/11/10 Javascript
js闭包的9个使用场景
2020/12/29 Javascript
[29:10]Ti4 冒泡赛第二天 NEWBEE vs Titan 3
2014/07/15 DOTA
[00:32]2018DOTA2亚洲邀请赛EG出场
2018/04/03 DOTA
python定时采集摄像头图像上传ftp服务器功能实现
2013/12/23 Python
一篇文章读懂Python赋值与拷贝
2018/04/19 Python
用Python写一个自动木马程序
2019/09/17 Python
Django ORM实现按天获取数据去重求和例子
2020/05/18 Python
如何利用python进行时间序列分析
2020/08/04 Python
详解python os.path.exists判断文件或文件夹是否存在
2020/11/16 Python
PyTorch中clone()、detach()及相关扩展详解
2020/12/09 Python
从零实现一个自定义html5播放器的示例代码
2017/08/01 HTML / CSS
一套带网友答案的.NET笔试题
2016/12/06 面试题
土木工程师岗位职责
2013/11/24 职场文书
《永远的白衣战士》教学反思
2014/04/25 职场文书
个人考核材料
2014/05/15 职场文书
庆祝国庆节标语
2014/10/09 职场文书
MySQL 数据类型选择原则
2021/05/27 MySQL