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选择排序算法实例总结
Jul 01 Python
Python处理JSON数据并生成条形图
Aug 05 Python
Python错误提示:[Errno 24] Too many open files的分析与解决
Feb 16 Python
用 Python 连接 MySQL 的几种方式详解
Apr 04 Python
pycharm使用matplotlib.pyplot不显示图形的解决方法
Oct 28 Python
在cmd中查看python的安装路径方法
Jul 03 Python
python批量修改图片尺寸,并保存指定路径的实现方法
Jul 04 Python
树莓派安装OpenCV3完整过程的实现
Oct 10 Python
Python3安装pip工具的详细步骤
Oct 14 Python
python UDF 实现对csv批量md5加密操作
Jan 01 Python
解决python绘图使用subplots出现标题重叠的问题
Apr 30 Python
Python自动化工具之实现Excel转Markdown表格
Apr 08 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
将RTF格式的文件转成HTML并在网页中显示的代码
2006/10/09 PHP
Smarty Foreach 使用说明
2010/03/23 PHP
PHP中的流(streams)浅析
2015/07/02 PHP
jQuery基础知识filter()和find()实例说明
2010/07/06 Javascript
jquery插件jquery倒计时插件分享
2013/12/27 Javascript
js解决弹窗问题实现班级跳转DIV示例
2014/01/06 Javascript
nodejs开发环境配置与使用
2014/11/17 NodeJs
自己动手手写jQuery插件总结
2015/01/20 Javascript
jquery通过closest选择器修改上级元素的方法
2015/03/17 Javascript
javascript控制层显示或隐藏的方法
2015/07/22 Javascript
实例讲解jquery与json的结合
2016/01/07 Javascript
Vue.js每天必学之指令系统与自定义指令
2016/09/07 Javascript
JS实现简单的选择题测评系统代码思路详解(demo)
2017/09/03 Javascript
vue实现与安卓、IOS交互的方法
2018/11/02 Javascript
详解Vue源码之数据的代理访问
2018/12/11 Javascript
vue iview的菜单组件Mune 点击不高亮的解决方案
2019/11/01 Javascript
[07:37]DOTA2-DPC中国联赛2月2日Recap集锦
2021/03/11 DOTA
python删除过期文件的方法
2015/05/29 Python
ansible作为python模块库使用的方法实例
2017/01/17 Python
python3爬取淘宝信息代码分析
2018/02/10 Python
Python批处理更改文件名os.rename的方法
2018/10/26 Python
Python设计模式之备忘录模式原理与用法详解
2019/01/15 Python
对python实现合并两个排序链表的方法详解
2019/01/23 Python
numpy基础教程之np.linalg
2019/02/12 Python
Python实现多线程/多进程的TCP服务器
2019/09/03 Python
python实现WebSocket服务端过程解析
2019/10/18 Python
纯css3(无图片/js)制作的几个社交媒体网站的图标
2013/03/21 HTML / CSS
澳大利亚最大的在线美发和美容零售商之一:My Hair Care & Beauty
2019/08/24 全球购物
国际贸易专业求职信
2014/06/04 职场文书
社区党建工作汇报材料
2014/10/27 职场文书
旷课检讨书范文
2015/01/27 职场文书
秋菊打官司观后感
2015/06/03 职场文书
教师节获奖感言
2015/07/31 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
thinkphp 获取控制器及控制器方法
2021/04/16 PHP
go语言中GOPATH GOROOT的作用和设置方式
2021/05/05 Golang