KezMenu 0.3.6
pip install KezMenu
发布时间:
一个简单且基础的Pygame库,用于快速开发菜单界面
导航
未验证详情
这些详情尚未由PyPI验证项目链接
元信息
- 许可证: GNU通用公共许可证 (GPL) (GPL)
- 作者: keul
- 标签 python, pygame, menu, kezmenu, library
分类
- 开发状态
- 目标受众
- 许可证
- 操作系统
- 编程语言
- 主题
项目描述
KezMenu
一个基于Pygame的简单且基础的模块,用于快速开发菜单界面。
简介
此模块基于Pygame社区中PyMike的原始工作(有关更多信息,请参阅EzMeNu项目)。由于在使用Mike的版本库时发现了一些问题,我发布了这个版本,修复了一些问题,并添加了新功能。
- 您可以使用此模块做什么?
您可以轻松地绘制菜单界面,并使用鼠标或箭头键选择选项。
示例和用法
以下是一个使用此库的完整示例。即使我们使用Python doctest格式,这也不是一个政治上正确的自动化测试,因为我们将在等待用户输入时进行测试,并且没有对结果进行实际测试(不,这不是真的,但没有主要功能在这里真正测试)。
也许有一天我会用更好的Python测试来完善它!
然而... 此页面的代码是一个工作示例。如果您对doctests一无所知,只知道您可以通过下载源代码,进入kezmenu目录并输入以下命令来运行此代码:
python tests.py
如果您已在系统上安装了库,您可以使用Python解释器运行示例程序。
import kezmenu
kezmenu.runTests()
初始化所有Pygame组件
首先,我们需要启用Pygame环境
>>> import pygame >>> from pygame.locals import * >>> import pygame.font >>> pygame.font.init() >>> screen = pygame.display.set_mode((640,480), 0, 32)
KezMenu通过在pygame.Surface实例上绘制菜单来工作;更好的(更简单的)选择是在屏幕上绘制菜单(使用pygame.display模块的方法获得的另一个Surface实例,如pygame.display.set_mode),因为在Pygame中无法知道从屏幕左上角到blitten表面的偏移量。
如果您不打算在菜单上使用鼠标,仅依赖上下键,这并不重要。要禁用鼠标,只需将KezMEnu实例的mouse_enabled属性设置为False。
在下面的第一个示例中,我们将使用屏幕内部的Surface来绘制菜单。所以,我们首先创建这个Surface
>>> surface = pygame.Surface( (400,400), flags=SRCALPHA, depth=32 ) >>> surface.fill( (150,150,150,255) ) <rect(0, 0, 400, 400)>
现在我们可以在屏幕上绘制Surface。我们将重复这个步骤几次,所以最好创建我们的第一个虚拟函数(这些函数在这个测试环境中并不真正有用)
>>> def blitSurface(): ... screen.blit(surface, (50,50) ) ... pygame.display.update()
因此,我们可以第一次调用它
>>> blitSurface()
这是一个图形测试,所以我们需要延迟自动操作,并使用户能够查看结果,然后再进行操作。我们在继续之前等待用户输入。
为此,我们创建了一个第二个愚蠢的函数,我们稍后会经常调用它
>>> click_count = 0 >>> def waitForUserAction(msg='???'): ... global click_count ... click_count+=1 ... pygame.display.set_caption("Example %s - %s" % (click_count, msg)) ... while True: ... for event in pygame.event.get(): ... if event.type==KEYDOWN: ... return
好吧,让我们第一次调用它
>>> waitForUserAction("An empty, dark surface")
我们仅在屏幕上显示了一个填充深色的Surface。
KezMenu
现在是时候创建我们的KezMenu实例了
>>> from kezmenu import KezMenu >>> menu = KezMenu()
为了绘制我们之前创建的菜单,我们还需要为测试创建另一个虚拟函数
>>> def drawMenu(): ... surface.fill( (150,150,150,255) ) ... menu.draw(surface) ... blitSurface() ... pygame.display.flip()
这是创建菜单的有效方法,但我们只能获得一个空菜单(因此对用户不可见)。
>>> drawMenu() >>> waitForUserAction("You see no difference")
您没有看到示例1中的变化,不是吗?如果我们以这种方式创建菜单,我们需要在运行时填充我们的选项。您可以通过修改options属性来执行此操作。
在定义选项之前,我们需要知道菜单动作必须执行什么
>>> option_selected = None >>> def option1(): ... global option_selected ... option_selected = 1 >>> menu.options = ( {'label': 'First option!', 'callable': option1}, )
如您所见,选项成员必须是一个字典的元组。这些字典必须包含(至少)label和callable参数;其他参数可以指定用于高级使用(见EFFECTS.txt)。
label是要为菜单选项绘制的字符串,而callable是要在选择时调用的函数、对象、方法等。
由于我们将菜单绘制在不在(0,0)屏幕位置的Surface中,如果我们想以后使用鼠标控制,我们需要指定screen_topleft_offset属性
>>> menu.screen_topleft_offset = (50,50) >>> drawMenu() >>> waitForUserAction("Our first option!")
这样我们就告诉菜单,所有坐标都必须从屏幕左上角开始计算偏移量。
直接将屏幕对象传递给menu.draw方法更为常见,所以在我们所有的其他示例中,我们将放弃使用Surface对象。
>>> surface = None
将动作链接到菜单选择的途径
手动更改options属性很简单(并且可能很有用),但最常见的方法是在创建菜单时直接创建选项。为了使测试更完整,我们需要添加一些其他的可调用函数!
>>> def option2(): ... global option_selected ... option_selected = 1 >>> def option3(): ... global option_selected ... option_selected = 1>>> import sys >>> def optionX(p): ... global option_selected ... option_selected = p
现在创建一个新的菜单实例
>>> menu = KezMenu( ... ["First option!", option1], ... ["sEcond", option2], ... ["Again!", option3], ... ["Lambda", lambda: optionX(71)], ... ["Quit", sys.exit], ... )
您可以通过提供一个包含我们的label和callable属性的元组的列表快速创建菜单条目。初始化方法会执行魔法并将这些值以正确的方式保存。
>>> type(menu.options[0]) == dict True >>> menu.options[1]['callable'] <function option2 at ...> >>> [x['label'] for x in menu.options] ['First option!', 'sEcond', 'Again!', 'Lambda', 'Quit']
如上所述,我们不再使用Surface对象,因此我们可以稍微简化我们的虚拟函数
>>> def drawMenu(): ... screen.fill( (150,150,150,255) ) ... menu.draw(screen) ... pygame.display.flip()
现在我们刷新我们的窗口
>>> drawMenu() >>> waitForUserAction("All our options")
了解操作如何与菜单项相关联非常重要。我们必须创建成对的标签和可调用对象,而不调用它们!就像上面一样,你必须将可调用函数传递给KezMenu函数,而不应该自己调用它。
我们还可以将对象的函数、Python标准可调用对象(如上面的sys.exit)作为可调用参数使用。
如果你还需要将参数传递给可调用对象怎么办?上面的lambda函数将向你展示如何做到这一点!
自定义菜单GUI:颜色、字体等
最后一个例子中显示的菜单有点丑。离屏幕边界太近,非选中元素使用的颜色也很丑。你也可以为已经创建的菜单修改这些属性
>>> menu.position (0, 0) >>> menu.position = (30,50) >>> menu.position (30, 50) >>> drawMenu() >>> waitForUserAction("Not soo near to border now...")
现在菜单在屏幕上的位置更合适了。
让我们修改一些字体属性,但首先让我谈谈菜单的尺寸。菜单尺寸的数据始终可以通过使用width和height属性来获取
>>> menu.width 126 >>> menu.height 115
这些值与菜单中的标签显示有关,也受字体使用(及其尺寸)的影响
>>> new_font = pygame.font.Font(None, 38) >>> menu.font = new_font >>> drawMenu() >>> waitForUserAction("Bigger font")
这个更大的字体有不同的尺寸,所以整个菜单的尺寸也增加了
>>> menu.width 154 >>> menu.height 135
现在来谈谈颜色
>>> menu.color = (255,255,255,100) >>> menu.focus_color = (255,255,0) >>> drawMenu() >>> waitForUserAction("...and better colors")
正如你所见,我们可以轻松地操作字体颜色和选中项的字体。
用我们的KezMenu做些有用的事情
你注意到我们之前的例子都是静态截图,没有可能的交互。
要使用我们的菜单进行一些真正的示例,我们需要使用KezMEnu.update方法,并传递pygame捕获的pygame.Event实例。因为菜单通常是一种等待用户决策的方式,所以不再需要waitForUserAction虚拟函数。
>>> click_count+=1 >>> pygame.display.set_caption("Example %s - %s" % (click_count, "Use the KezMenu freely")) >>> while True: ... events = pygame.event.get() ... menu.update(events) ... drawMenu() ... if option_selected: ... break >>> option_selected is not None True
现在,option_selected变量包含与所选选项相关的可调用对象的返回值。
注意:如果你在运行此测试时选择退出选项,你将得到一个假测试失败。这不是KezMenu的错误,但在Python测试中这是正常的:sys.exit调用会引发一个SystemExit异常,在测试中会被以不同的方式处理。
好了,例子就到这里了!
但KezMenu还有一些效果!你可以在EFFECTS.txt文件中找到有关菜单效果的示例。
再见!
>>> pygame.quit()
玩转KezMenu的效果
简介
从版本0.3.0开始,KezMenu的内部结构变化很大。其中之一是每行都有自己的pygame.font.Font来使用。
这将给我们提供大量关于菜单条目显示效果的自由。
>>> import pygame >>> from pygame.locals import * >>> import pygame.font >>> pygame.font.init() >>> screen = pygame.display.set_mode((640,480), 0, 32) >>> screen.fill( (50,50,50,255) ) <rect(0, 0, 640, 480)>>>> click_count = 0 >>> def waitForUserAction(msg='???'): ... global click_count ... click_count+=1 ... pygame.display.set_caption("Example %s - %s" % (click_count, msg)) ... while True: ... for event in pygame.event.get(): ... if event.type==KEYDOWN: ... return>>> def updateCaption(msg='???'): ... global click_count ... click_count+=1 ... pygame.display.set_caption("Example %s - %s" % (click_count, msg))>>> from kezmenu import KezMenu >>> def drawMenu(): ... screen.fill( (50,50,50,255) ) ... menu.draw(screen) ... pygame.display.flip()>>> option_selected = 0 >>> def optSelected(): ... global option_selected ... option_selected=1>>> menu = KezMenu( ... ["First option!", optSelected], ... ["sEcond", optSelected], ... ["Again!", optSelected], ... ["Lambda", optSelected], ... ["Quit", optSelected], ... ) >>> menu.font = pygame.font.Font(None, 20) >>> menu.color = (255,255,255) >>> menu.position = (10,10)
让我们显示当前菜单的高度
>>> menu.height 70
这里又是一个标准菜单。
>>> drawMenu() >>> waitForUserAction("The same boring menu")
现在我们想为'sEcond'条目使用更大的字体
>>> menu.options[1]['font'] = pygame.font.Font(None, 26) >>> drawMenu() >>> waitForUserAction("Bigger entry 2")
让我们知道,手动修改菜单选项可能会导致菜单本身的某些错误,因为KezMenu实例没有注意到参数的变化
>>> menu.height 70
所以即使我们显示了一个新绘制的菜单,保存的尺寸也没有改变。这是不好的。我们可以简单地调用一个内部KezMenu方法来修复这个问题,通常KezMenu对象会为我们调用这个方法
>>> menu._fixSize() >>> menu.height 74
这篇介绍只是KezMenu效果内部实现方式的冰山一角。
KezMenu可用的效果
这里有一个可用效果的列表和用法示例。使用enableEffect方法启用效果,并且必须用于现有效果,否则会引发KeyError。
>>> menu.enableEffect('not-existing-effect-just-for-raise-error') Traceback (most recent call last): ... KeyError: "KezMenu don't know an effect of type not-existing-effect-just-for-raise-error"
在所有下面的例子中,我们需要一个计时器,所以可以使用pygame.time.Clock
>>> clock = pygame.time.Clock()
要启用效果,我们必须使用enableEffect方法,并将效果名称传递给它,可选地传递一些关键字参数。
重要事项:效果可以(有时)组合使用!
raise-line-padding-on-focus
此效果会在时间流逝的过程中提高聚焦元素的上下填充。最后一个元素的填充只会提高顶部填充。第一个元素的填充只会提高底部填充。
- 填充
默认:10px。将被添加到所选菜单条目上下方的像素数。
- enlarge_time
默认:500毫秒。达到最大填充所需的时间(以秒为单位)。
>>> updateCaption('raise-line-padding-on-focus') >>> option_selected = 0 >>> menu.enableEffect('raise-line-padding-on-focus') >>> while True: ... time_passed = clock.tick() / 1000. ... events = pygame.event.get() ... menu.update(events, time_passed) ... drawMenu() ... if option_selected: ... break
我们可以用新的自定义值调用此效果
>>> updateCaption('raise-line-padding-on-focus (custom)') >>> option_selected = 0 >>> menu.enableEffect('raise-line-padding-on-focus', padding=30, enlarge_time=1.) >>> while True: ... time_passed = clock.tick() / 1000. ... events = pygame.event.get() ... menu.update(events, time_passed) ... drawMenu() ... if option_selected: ... break >>> menu.disableEffect('raise-line-padding-on-focus')
raise-col-padding-on-focus
此效果会在时间流逝的过程中提高聚焦元素左侧的填充。
- 填充
默认:10px。将被添加到所选菜单条目左侧的像素数。
- enlarge_time
默认:500毫秒。达到最大填充所需的时间(以秒为单位)。
>>> updateCaption('raise-col-padding-on-focus') >>> option_selected = 0 >>> menu.enableEffect('raise-col-padding-on-focus') >>> while True: ... time_passed = clock.tick() / 1000. ... events = pygame.event.get() ... menu.update(events, time_passed) ... drawMenu() ... if option_selected: ... break
我们可以用新的自定义值调用此效果
>>> updateCaption('raise-col-padding-on-focus (custom)') >>> option_selected = 0 >>> menu.enableEffect('raise-col-padding-on-focus', padding=20, enlarge_time=3.) >>> while True: ... time_passed = clock.tick() / 1000. ... events = pygame.event.get() ... menu.update(events, time_passed) ... drawMenu() ... if option_selected: ... break >>> menu.disableEffect('raise-col-padding-on-focus')
enlarge-font-on-focus
此效果将按给定倍数提高所选菜单元素的字体大小。Pygame的Font类有一个限制(不是一个错误):在字体创建后无法获取字体数据(家族、大小)。
因此,为了使用此效果,需要将所有字体数据传递给init方法,并将创建一个新字体(标准菜单的‘font’属性将被覆盖)。
- font
必需。字体名称或路径,与传递给Pygame Font构造函数的方式相同,因此也可以是None。
- size
必需。字体大小,与传递给Pygame Font构造函数的方式相同。
- enlarge_factor
默认:2。(200%)。最大扩展时字体大小的倍数,作为一个实值。
- enlarge_time
默认:500毫秒。达到最大字体大小所需的时间(以秒为单位)。
>>> updateCaption('enlarge-font-on-focus') >>> option_selected = 0 >>> menu.enableEffect('enlarge-font-on-focus', font=None, size=18) >>> while True: ... time_passed = clock.tick() / 1000. ... events = pygame.event.get() ... menu.update(events, time_passed) ... drawMenu() ... if option_selected: ... break
现在我们可以自定义所有数据
>>> updateCaption('enlarge-font-on-focus (focus)') >>> option_selected = 0 >>> menu.enableEffect('enlarge-font-on-focus', font=None, size=18, enlarge_factor=5., enlarge_time=2.) >>> while True: ... time_passed = clock.tick() / 1000. ... events = pygame.event.get() ... menu.update(events, time_passed) ... drawMenu() ... if option_selected: ... break >>> menu.disableEffect('enlarge-font-on-focus')
组合KezMenu效果
KezMenu效果的主要作用是足够灵活,可以在同一时间激活。随着未来可用的效果的增加,有时可能会出现效果相互冲突的情况,但一般来说,我会尽量将它们整合。
同时激活多个效果非常简单:只需激活即可!
>>> updateCaption('Combined effects example') >>> option_selected = 0 >>> menu.enableEffect('raise-line-padding-on-focus', padding=30, enlarge_time=1.) >>> menu.enableEffect('raise-col-padding-on-focus', padding=20, enlarge_time=1.) >>> menu.enableEffect('enlarge-font-on-focus', font=None, size=16, enlarge_factor=3.) >>> while True: ... time_passed = clock.tick() / 1000. ... events = pygame.event.get() ... menu.update(events, time_passed) ... drawMenu() ... if option_selected: ... break >>> menu.disableEffect('raise-line-padding-on-focus') >>> menu.disableEffect('raise-col-padding-on-focus') >>> menu.disableEffect('enlarge-font-on-focus')
想编写一个新效果吗?
如果有人对开发新效果感兴趣,我将很高兴将其集成到KezMenu中!
更新日志
0.3.6 (2013-06-07)
修复了打包错误
0.3.5
使用Python 2.6和Pygame 1.9进行测试
对doctest进行了修复
删除了过时的代码
0.3.1
没有新功能,但修复了在py2exe环境中使用模块时中断菜单的问题。
0.3.0
添加了README.txt,格式为doctest。
添加了许多针对不遵循PEP 8命名方法的弃用警告。这些方法将在未来被删除。
如果菜单位置从(0,0)移动,则由于未计算此偏移量,鼠标控制将出现错误。
支持菜单效果
0.2.1
作为egg发布。
添加了一些txt文件。
0.2.0 - 未发布
修复了许多与字体处理相关的问题。
添加了对鼠标使用的支持。
0.1.0
对于0.1.0版本,我的意思是原始EzMeNu 1.0版本。
致谢
Pygame社区的PyMike对他的原始工作表示感谢。
待办事项
子菜单?
更多效果(欢迎提出建议)
需要更好地处理透明度
获取代码
源代码库托管在GitHub
项目详情
未验证详情
这些详情尚未由PyPI验证项目链接
元信息
- 许可证: GNU通用公共许可证 (GPL) (GPL)
- 作者: keul
- 标签 python, pygame, menu, kezmenu, library
分类
- 开发状态
- 目标受众
- 许可证
- 操作系统
- 编程语言
- 主题
KezMenu-0.3.6.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 21f6e87454063c00961eb5d55f33c8dddfbe5cc47c893f3612a09aab9ee85ae5 |
|
MD5 | 29a40cd4198dbbc3ee40c621a56de261 |
|
BLAKE2b-256 | f3dbf757790efe0e22e9bbfd96968b701bbe917ba46e021b2ad4512cf94a187e |