Search code examples
pythonarcade

Reading text from user in Python Arcade library


Is there a way in Python Arcade library to read text from the user (with textbox rectangle, or popup, etc.)? Without the need to read each key, and interpereting it (and translate to some other char if the system language isn't English).

If not, is there built-in way to check what is the correct character for the pressed key (depends to the system language and Caps Lock state, etc)?

I found just ways to write texts, but not to read them.


Solution

  • From most tutorials, the Python Arcade Library has only basic key-event handling implemented, like on_key_press and on_key_release.

    UI components for text I/O

    However, the Python Arcade Library has GUI components as one of the major feature differences when compared to PyGame.

    When searching the docs for input we can find a class

    arcade.gui.UIInputText

    An input field the user can type text into.

    This seems to be since version 2.6.0 (see release notes).

    Note: There is currently an open issue #1059: UIInputText() not working. (Could reproduce with arcade-2.6.7; but got it working by passing text to the constructor like UIInputText(text='hello')).

    Example demonstrating text-input

    I adapted it from the sample-code attached to the issue #1059. Added some event-handling as shown in Arcade Library's docs: FlatButton example.

    import arcade
    import arcade.gui as gui
    
    # --- Method 1 for handling click events,
    # Create a child class.
    class QuitButton(arcade.gui.UIFlatButton):
        def on_click(self, event: arcade.gui.UIOnClickEvent):
            arcade.exit()
    
    class MyWindow(arcade.Window):
        def __init__(self):
            super().__init__(400, 300, "UI Example", resizable=True)
            self.manager = gui.UIManager()
            self.manager.enable()
    
            arcade.set_background_color(arcade.color.BEIGE)
            
            # Create a text label
            self.label = arcade.gui.UILabel(
                text="look here for change",
                text_color=arcade.color.DARK_RED,
                width=350,
                height=40,
                font_size=24,
                font_name="Kenney Future")
    
            # Create an text input field
            self.input_field = gui.UIInputText(
              color=arcade.color.DARK_BLUE_GRAY,
              font_size=24,
              width=200,
              text='Hello ..')
    
            # Create a button
            submit_button = gui.UIFlatButton(
              color=arcade.color.DARK_BLUE_GRAY,
              text='Submit')
            # --- Method 2 for handling click events,
            # assign self.on_click_start as callback
            submit_button.on_click = self.on_click 
            
            self.v_box = gui.UIBoxLayout()
            self.v_box.add(self.label.with_space_around(bottom=0))
            self.v_box.add(self.input_field)
            self.v_box.add(submit_button)
            self.v_box.add(QuitButton(text="Quit"))
            
            self.manager.add(
                arcade.gui.UIAnchorWidget(
                    anchor_x="center_x",
                    anchor_y="center_y",
                    child=self.v_box)
            )
    
    
        def update_text(self):
            print(f"updating the label with input text '{self.input_field.text}'")
            self.label.text = self.input_field.text    
    
        def on_click(self, event):
            print(f"click-event caught: {event}")
            self.update_text()
    
            
        def on_draw(self):
            arcade.start_render()
            self.manager.draw()
    
    
    window = MyWindow()
    arcade.run()
    

    See also

    • Real Python: Arcade: A Primer on the Python Game Framework, section Keyboard Input
    • A list with GUI projects targeted for PyGame from Maic's GitHub repo: eruvanos/arcade_gui