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 相关文章推荐
SublimeText 2编译python出错的解决方法(The system cannot find the file specified)
Nov 27 Python
Python中文字符串截取问题
Jun 15 Python
python查看zip包中文件及大小的方法
Jul 09 Python
Python3基于sax解析xml操作示例
May 22 Python
异步任务队列Celery在Django中的使用方法
Jun 07 Python
解决在pycharm中显示额外的 figure 窗口问题
Jan 15 Python
在Python中使用Neo4j的方法
Mar 14 Python
python flask解析json数据不完整的解决方法
May 26 Python
十行代码使用Python写一个USB病毒
Jun 21 Python
Django xadmin安装及使用详解
Oct 26 Python
python regex库实例用法总结
Jan 03 Python
python中封包建立过程实例
Feb 18 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下10件你也许并不了解的事情
2008/09/11 PHP
PHP 常用的header头部定义汇总
2015/06/19 PHP
反射调用private方法实践(php、java)
2015/12/21 PHP
自制PHP框架之设计模式
2017/05/07 PHP
php 比较获取两个数组相同和不同元素的例子(交集和差集)
2019/10/18 PHP
JavaScript中__proto__与prototype的关系深入理解
2012/12/04 Javascript
js进行表单验证实例分析
2015/02/10 Javascript
JavaScript中常见获取元素的方法汇总
2015/03/04 Javascript
对于jQuery性能的一些优化建议
2015/08/13 Javascript
jQuery hover事件简单实现同时绑定2个方法
2016/06/07 Javascript
node.js请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE\的解决方法
2016/12/18 Javascript
jQuery实现分页功能(含ajax请求、后台数据、附完整demo)
2017/04/03 jQuery
关于js的三种使用方式(行内js、内部js、外部js)的程序代码
2018/05/05 Javascript
layui 弹出层值回传解决方式
2019/11/14 Javascript
Vue通过配置WebSocket并实现群聊功能
2019/12/31 Javascript
JS指定音频audio在某个时间点进行播放
2020/11/28 Javascript
[02:29]大剑、皮鞭、女装,这届DOTA2勇士令状里都有
2020/07/17 DOTA
linux下安装easy_install的方法
2013/02/10 Python
python通过colorama模块在控制台输出彩色文字的方法
2015/03/19 Python
python添加模块搜索路径方法
2017/09/11 Python
Flask模板引擎之Jinja2语法介绍
2019/06/26 Python
python中dict()的高级用法实现
2019/11/13 Python
python读写Excel表格的实例代码(简单实用)
2019/12/19 Python
使用celery和Django处理异步任务的流程分析
2020/02/19 Python
详解基于Jupyter notebooks采用sklearn库实现多元回归方程编程
2020/03/25 Python
django实现HttpResponse返回json数据为中文
2020/03/27 Python
Python类及获取对象属性方法解析
2020/06/15 Python
手机端用rem+scss做适配的详解
2017/11/15 HTML / CSS
比利时的在线灯具店:Lampen24.be
2019/07/01 全球购物
物业公司采购员岗位职责
2013/12/31 职场文书
创新型城市实施方案
2014/03/06 职场文书
2014年秋季开学演讲稿
2014/05/24 职场文书
大学运动会加油稿200字(5篇)
2014/09/27 职场文书
回复函格式及范文
2015/07/14 职场文书
什么是动态刷新率DRR? Windows11动态刷新率功能介绍
2021/11/21 数码科技
VUE中的v-if与v-show区别介绍
2022/03/13 Vue.js