Met knoppen een rechthoek besturen

In dit voorbeeld worden callbacks geregistreerd voor knoppen A en B voor hun "press" en "release" gebeurtenissen. Voor het voorbeeld zenden de callbacks button_press en button_released tk-events uit met behulp van de event_generate-methode: dit betekent dat we de TK API oproepen in een callback, dus we verpakken de callback in do_in_tkinter (zie ook do_in_tkinter)

Dit gebeurt wanneer de A-knop wordt ingedrukt:

  • de callback button_press wordt aangeroepen (do_in_tkinter zorgt ervoor dat dit wordt gedaan door TK)
  • tk.event_generate voegt een <<MICROBIT_BUTTON_PRESS_A>> event toe aan het einde van de TK-eventwachtrij
  • de tk.main_loop verwerkt het event <<MICROBIT_BUTTON_PRESS_A>> en ziet dat er een eventhandler paddle.go_left aan is gebonden
  • de eventhandler paddle.go_left wordt uitgevoerd: dit stelt de richting van paddle in op Paddle.LEFT
  • tk.main_loop() roept redraw aan waardoor de paddle in het canvas naar links beweegt

Zie ook de API-documentatie:

class Paddle:
    LEFT = -4
    RIGHT = 4

    def __init__(self, canvas, color):
        self.canvas = canvas
        self.id = canvas.create_rectangle(0, 0, 100, 10, fill=color)
        self.canvas.move(self.id, 200, 300)
        self.direction = 0
        self.canvas_width = self.canvas.winfo_width()

    def draw(self):
        pos = self.canvas.coords(self.id)
        self.canvas.move(self.id, self.compute_movement_x(pos[0], pos[2]), 0)

    def compute_movement_x(self, left_edge, right_edge):
        if ((self.direction == Paddle.RIGHT) and (right_edge > self.canvas_width)) \
                or ((self.direction == Paddle.LEFT) and (left_edge < 0)):
            return 0
        return self.direction

    def go_left(self, event):
        self.direction = Paddle.LEFT

    def go_right(self, event):
        self.direction = Paddle.RIGHT

    def stop_going_left(self, event):
        if self.direction == Paddle.LEFT:
            self.direction = 0

    def stop_going_right(self, event):
        if self.direction == Paddle.RIGHT:
            self.direction = 0


tk = Tk()
tk.title("Use buttons to move rectangle")
tk.resizable(False, False)
tk.wm_attributes("-topmost", 1)
canvas = Canvas(tk, width=500, height=400, bd=0, highlightthickness=0)
canvas.pack()
tk.update()
paddle = Paddle(canvas, 'blue')
canvas.bind_all('<KeyPress-Left>', paddle.go_left)
canvas.bind_all('<KeyRelease-Left>', paddle.stop_going_left)
canvas.bind_all('<KeyPress-Right>', paddle.go_right)
canvas.bind_all('<KeyRelease-Right>', paddle.stop_going_right)
canvas.bind_all('<<MICROBIT_BUTTON_PRESS_A>>', paddle.go_left)
canvas.bind_all('<<MICROBIT_BUTTON_RELEASE_A>>', paddle.stop_going_left)
canvas.bind_all('<<MICROBIT_BUTTON_PRESS_B>>', paddle.go_right)
canvas.bind_all('<<MICROBIT_BUTTON_RELEASE_B>>', paddle.stop_going_right)


def redraw():
    paddle.draw()
    tk.after(10, redraw)


tk.after(10, redraw)


def button_pressed(button: str):
    tk.event_generate(f'<<MICROBIT_BUTTON_PRESS_{button.upper()}>>', when='tail')


def button_released(button: str):
    tk.event_generate(f'<<MICROBIT_BUTTON_RELEASE_{button.upper()}>>', when='tail')


with KaspersMicrobit.find_one_microbit() as microbit:
    microbit.buttons.on_button_a(press=do_in_tkinter(tk, button_pressed), release=do_in_tkinter(tk, button_released))
    microbit.buttons.on_button_b(press=do_in_tkinter(tk, button_pressed), release=do_in_tkinter(tk, button_released))
    tk.mainloop()