需要在pygame中输入文本/按钮

时间:2018-02-16 03:29:39

标签: python user-interface tkinter textbox pygame

我现在需要的只是基本文本字段和用于在pygames中输入的按钮。一个文本字段作为一些简单的结构,我可以读入变量,一个按钮来调用一个函数。

首先,我浏览了一下,发现在pygames中创建文本字段并不是一个简单的过程。最终,通过拼凑this wall of code,我成为了一个有点破碎的文本领域的骄傲的父亲。然后我查看按钮,发现实施它们是even more complicated的一些恐怖。

Surely PyGame has some sort of buttons module built in right? No.

对不起?我不是只想为一个按钮编写一个完整的程序,我只需要接口进行更深入的模拟。就这样。

然后我研究了Tkinter,它具有非常易于理解的GUI输入命令。但不,那也是not meant to be

I don't believe you can embed tkinter in to pygame.

然后我尝试了PGU,但发现了一个令人惊讶的缺乏任何直接的例子,如何实际使用它我需要的东西(简单的文本字段和按钮)。当我尝试寻找一个时,我找到了this piece of wisdom

Are there any good, modern widget toolkits for Pygame? No. Every year someone makes a new Pygame UI library and then abandons it after a few versions

所以,如果这是真的,那么有谁应该用这种语言完成任何事情呢?在pygame环境中,简单的文本字段和简单按钮的最佳实践究竟是什么?

1 个答案:

答案 0 :(得分:0)

是的 - pygame是准系统"我们控制像素" - 并且已经存在了很长时间,并且它本身看起来像被放弃了很多时间(例如,在2016年末它将在Python 3上安装干净)。所以,与此同时,pygame看起来被遗弃的人搬走了。

目前,你必须尝试从这里挖掘一个可用的工具包:

https://www.pygame.org/wiki/gui

正如您所指出的,那里列出的PGU工具包似乎非常完整 - 如何构建简单的小部件以与现有的Pygame代码库进行交互的示例。所有的例子都假设一个人想要一个表格填充的立场申请,我同意这是非常不合适的:如果想要这种应用,只需使用Tkiner,Qt或创建一个网络应用程序。

然而,事实证明,在现有的pygame窗口中使用独立窗口小部件非常简单。尽管所有的库示例都调用了.run方法,这是扰流器的一部分,但是因为你调用run,所以PGU应用程序会接管并且无法运行代码,除了回调。但是,run方法本身包含一个非常简单的无限循环,调用应用程序的loop方法。你只需要在你自己的pygame循环的所有帧中调用app.loop并让小部件工作。

它会吞下pygame事件,但是 - 如果你想在显示小部件时处理事件,你应该将所有事件发送到app.event并调用app.update而不是调用app.loop。一旦您在https://github.com/parogers/pgu/blob/master/pgu/gui/app.py

查看应用类的源代码,这是微不足道的

因此,使用文本输入的完整示例可以是:

import pygame
from pgu import gui

SIZE = W, H = 800, 600


def bouncing_rect(screen):
    surf = pygame.Surface((50, 50))
    rect = surf.get_rect()
    surf.fill((255, 0, 0))
    vx, vy = 10, 10
    while True:
        screen.blit(surf, rect)
        new_surface = yield rect
        if new_surface:
            surf = new_surface
            rect.width = surf.get_width()
            rect.height = surf.get_height()
        rect.x += vx
        rect.y += vy

        if rect.right > W or rect.left < 0:
            vx = -vx
            rect.x += vx * 2
        if rect.bottom > H or rect.top < 0:
            vy = -vy
            rect.y += vy * 2

def main():
    screen = pygame.display.set_mode((SIZE))
    app = gui.Desktop()
    txt = gui.Input()
    app.init(widget=txt, screen=screen, area=pygame.Rect(50, 50, 200,25))
    bouncing = bouncing_rect(screen)
    previous_value = ""
    font = pygame.font.SysFont(name="Sans", size=30)

    while True:
        screen.fill((0,0,0))
        rect = next(bouncing)
        app.loop()
        if txt.value != previous_value:
            previous_value = txt.value
            rect = bouncing.send(font.render(txt.value, True, (255, 255, 0)))
        pygame.display.update([rect])
        app.repaint()
        pygame.display.flip()
        pygame.time.delay(30)

try:
    main()
finally:
    pygame.quit()

(我刚刚使用&#34; send&#34;方法将弹跳对象作为生成器函数,因为这个模式的例子非常少,但它可能是一个相同的类 - 如果它是常见的pygame.Sprite子类,我只是调用&#34;更新&#34;而不是使用next / send。)