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传递参数方式小结
Apr 17 Python
在Python的Django框架中使用通用视图的方法
Jul 21 Python
Python实现将16进制字符串转化为ascii字符的方法分析
Jul 21 Python
详解Python3 中hasattr()、getattr()、setattr()、delattr()函数及示例代码数
Apr 18 Python
python+pandas分析nginx日志的实例
Apr 28 Python
Python面向对象之反射/自省机制实例分析
Aug 24 Python
python存储16bit和32bit图像的实例
Dec 05 Python
Python API 自动化实战详解(纯代码)
Jun 11 Python
python 判断三个数字中的最大值实例代码
Jul 24 Python
python定时任务 sched模块用法实例
Nov 04 Python
python获取本周、上周、本月、上月及本季的时间代码实例
Sep 08 Python
Django rest framework如何自定义用户表
Jun 09 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
在PWS上安装PHP4.0正式版
2006/10/09 PHP
php学习之数据类型之间的转换代码
2011/05/29 PHP
ThinkPHP3.1查询语言详解
2014/06/19 PHP
thinkphp特殊标签用法概述
2014/11/24 PHP
php三元运算符知识汇总
2015/07/02 PHP
php微信开发之谷歌测距
2018/06/14 PHP
Jquery 动态循环输出表格具体方法
2013/11/23 Javascript
Jquery操作radio的简单实例
2014/01/06 Javascript
jquery简单实现幻灯片的方法
2015/08/03 Javascript
js获取当前周、上一周、下一周日期
2017/03/19 Javascript
深入理解vue2.0路由如何配置问题
2017/07/18 Javascript
vue组件jsx语法的具体使用
2018/05/21 Javascript
NodeJS搭建HTTP服务器的实现步骤
2018/10/12 NodeJs
基于JavaScript判断两个对象内容是否相等
2020/01/10 Javascript
通过实例解析chrome如何在mac环境中安装vue-devtools插件
2020/07/10 Javascript
跟老齐学Python之有容乃大的list(4)
2014/09/28 Python
详解如何用OpenCV + Python 实现人脸识别
2017/10/20 Python
http请求 request失败自动重新尝试代码示例
2018/01/25 Python
python Opencv将图片转为字符画
2021/02/19 Python
使用Python+wxpy 找出微信里把你删除的好友实例
2019/02/21 Python
python面向对象实现名片管理系统文件版
2019/04/26 Python
解决pyshp UnicodeDecodeError的问题
2019/12/06 Python
关于Tensorflow分布式并行策略
2020/02/03 Python
python等差数列求和公式前 100 项的和实例
2020/02/25 Python
css3+伪元素实现鼠标移入时下划线向两边展开的效果
2017/04/25 HTML / CSS
在线学习西班牙语、法语或其他语言:Babbel.com
2018/02/07 全球购物
乌克兰最大的家用电器和电子产品连锁店:Eldorado
2019/10/02 全球购物
俄罗斯设计师家具购物网站:The Furnish
2019/12/01 全球购物
澳洲最大的时尚奢侈品电商平台:Cettire
2020/06/15 全球购物
毕业证丢失证明
2014/01/15 职场文书
珍爱生命演讲稿
2014/05/10 职场文书
2014年度党员自我评议
2014/09/13 职场文书
婚内房产协议书范本
2014/10/02 职场文书
2015年建党94周年演讲稿
2015/03/19 职场文书
食品药品安全责任书
2015/05/11 职场文书
Python+Appium实现自动抢微信红包
2021/05/21 Python