-5

All I need right now is basic text fields and buttons for input in pygames. A text field as some simple structure that I can read into variables, and a button to call a function.

First, I browsed around and found it was not a straight-forward process to create a text field in pygames. Eventually, by cobbling together this wall of code, I became the proud father of one, somewhat broken text field. Then I looked into buttons, and found to some horror that implementing them is even more complicated.

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

Excuse me? I'm not trying to write a whole program just for one button, I just need the interface for a deeper simulation. That's all.

So then I looked into Tkinter, which has very easy-to-understand commands for GUI input. But no, that was also not meant to be.

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

So then I tried PGU, but found a stunning lack of any straight-forward examples of how to actually use it for what I need (simple text fields and buttons). When I tried looking for one, I found 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

So if that was true, how is anyone supposed to get anything done with this language? What exactly is the best practice for a simple textfield and simple button in a pygame environment?

Nathan
  • 194
  • 1
  • 17
  • 3
    I voted to close this question, because it's too broad. You're basically asking for tutorials on implementing or using a pygame GUI toolkit. Asking us to recommend libraries is also off-topic on SO. Forums like https://www.reddit.com/r/pygame/ are less restrictive. If you want my opinion, check out the [SGC](http://www.pygame.org/project-SGC-2089-4505.html) library. I think it's the easiest to use GUI toolkit for pygame that you can find (doesn't steal the main loop). – skrx Feb 16 '18 at 11:57
  • I don't think I'm being broad at all. All I asked for was a text field and a button. – Nathan Feb 16 '18 at 16:15
  • 1
    That's still pretty broad and there are already questions about buttons and input boxes, so this question would be a duplicate (it also sounds a bit like a rant (I know it can be troublesome to get started)). What you really need is a tutorial, but I'm not sure if there are any. You can study the examples, read the source code and experiment (that's what I did). – skrx Feb 16 '18 at 19:34

1 Answers1

0

yes - pygame is barebones "we control the pixels" - and has been around a lot of time, and itself looked like abandoned for a lot of time (it was just in late 2016 that it would install clean on Python 3, for example). So, in the meantime pygame looked abandoned people moved away.

For the time being, you have to try your luck mining a usable toolkit from here:

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

The PGU toolkit listed there, as you noted, seems quite complete - bar examples on how to build simple widgets to interact with an existing Pygame codebase. All the examples assume one wants to just have an stand alne gui application for form filling, which, I agree, is quite inapropriate: if one wants this kind of application, just use Tkiner, Qt or create a web app.

It turns out, however, that using a standalone widget in an existing pygame window is quite simple. Despite all the library examples calling the .run method, which is the spoiler part, since nce you call run the PGU app takes over and there is no way to run your code back, save for callbacks. However, the run method itself consist of a very simple infinite loop, calling the app's loop method. You just have to put a call to app.loop in all frames of your own pygame loop and have the widgets working.

It will swallow pygame events, however - if you want to treat event while you are displaying widgets, you should dispatch all events to app.event and call app.update instead of calling app.loop. It is trivial once you look at the source code for the app class at https://github.com/parogers/pgu/blob/master/pgu/gui/app.py

So, a complete example for using a text-input can be:

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()

(I just made the bouncing object as generator function using the "send" method, since there are very few examples of this pattern, but it could be a class just the same - if it were a common pygame.Sprite child class, I'd just call "update" instead of using next/send. )

jsbueno
  • 99,910
  • 10
  • 151
  • 209
  • I did see the gui article you linked, the reason I was asking here is because the article is never clear which GUI toolkit has the simple text fields and buttons that I was looking for – Nathan Feb 16 '18 at 16:13