Home > database >  Circular keyboard python (tkinter?)
Circular keyboard python (tkinter?)

Time:12-18

So I'm trying to make some different virtual keyboard designs with the goal of using them in combination with head tracking. I wanted to explore if maybe a circular keyboard would be easier to use with head tracking compared to a standard layout. enter image description here

The keyboard would look like the one in the picture, but I'm not sure how to make this kind of a layout using tkinter (this is what I used for the other keyboard but I'm not limited to this lib in any way). Any tips on how to make non square/rectangular UI? Thanks in advance.

CodePudding user response:

You can use the Canvas widget to draw the menu as a collection of arc items. One of the features of the canvas is that you can give items on the canvas a tag, and you can bind that tag to an event.

This isn't a complete solution, but it illustrates how it's possible to draw a circular menu that responds to clicks, as well as enter and leave events. In the following code we draw a circle as a sequence of eight arcs. Each arc is given a generic tag of "item" and a specific tag of "item-". These tags can then be used to bind events, and to get information about the item that was clicked on.

class PieMenu(tk.Canvas):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.tag_bind("item", "<ButtonRelease-1>", self._click)
        self.tag_bind("item", "<Enter>", self._enter)
        self.tag_bind("item", "<Leave>", self._leave)

        for index, start in enumerate(range(0, 360, 45)):
            self.create_arc(
                (2, 2, 200, 200),
                outline="black", fill="white",
                start=start, extent=45, tags=(f"item-{index}", "item")
            )

    def _click(self, event):
        item = event.widget.find_withtag("current")[0]
        tags = event.widget.itemcget("current", "tags")
        print(f"item: {item} tags: {tags}")

    def _enter(self,event):
        event.widget.itemconfigure("current", fill="lightgray")

    def _leave(self,event):
        event.widget.itemconfigure("current", fill="white")

You would need to add code to include the text of each item, and code to know what function to call when a particular part of the menu is clicked. The point of the example is to show the technique for drawing one simple menu that can respond to mouse events.

  • Related