Quantcast
Channel: Active questions tagged frames - Stack Overflow
Viewing all articles
Browse latest Browse all 55

Tkinter: Focus issue when raising frame

$
0
0

The following code is a GUI for a touch screen (no mouse, no keyboard).The input is the touch screen and it responds like a mouse click. This isa stripped down from a larger program to show the issue. It has 3 frames that are raised as needed. Ideally I would want the focus to be nowhereuntil the user clicks (points) to a field, then the keyboard enters digitsin the focused field on frames Machine 1 or Machine 2. This works well,but if the user does not first "click" in an entry field, this generatesan exception: AttributeError: 'machine1' object has no attribute 'insert'.

I would be happy if the keyboard inputs would go to a "bit bucket" oran invisible (and unused) dummy entry field, but could accept that bydefault, when a frame is raised, the focus be automatically placed onthe first field.

After many hours and research on the web, I have been unable to find a solution. Thanks for pointing me in the right direction.

import tkinter as tkfrom tkinter import font  as tkfont  class MyApp(tk.Tk):    def __init__(self, *args, **kwargs):        tk.Tk.__init__(self, *args, **kwargs)        self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")        # the container is where we stack the frames        # then the one we want visible is raised above the others        container = tk.Frame(self)        container.grid(row=0, column=0, sticky='news')        container.grid_rowconfigure(0, weight=1)        container.grid_columnconfigure(0, weight=1)        self.frames = {}        self.frames["machine1"] = machine1(parent=container, controller=self)        self.frames["machine2"] = machine2(parent=container, controller=self)        self.frames["running"] = running(parent=container, controller=self)        self.frames["machine1"].grid(row=0, column=0, sticky="nsew")        self.frames["machine2"].grid(row=0, column=0, sticky="nsew")        self.frames["running"].grid(row=0, column=0, sticky="nsew")        self.show_frame("running")    def show_frame(self, page_name):'''Show a frame for the given page name'''        frame = self.frames[page_name]        frame.tkraise()        frame.focus_set() # this removed focus from the hidden windowclass Keypad(tk.Frame):    cells = [        ['1', '2', '3', '4', '5'],        ['6', '7', '8', '9', '0'],        ]    def __init__(self, *args, **kwargs):        super().__init__(*args, **kwargs)        for y, row in enumerate(self.cells):            for x, item in enumerate(row):                b = tk.Button(self, text=item, command=lambda text=item:self.append(text))                b.grid(row=y, column=x, sticky='news')        x = tk.Button(self, text='Backspace', command=self.backspace)        x.grid(row=0, column=10, sticky='news')        x = tk.Button(self, text='Clear', command=self.clear)        x.grid(row=1, column=10, sticky='news')    def get(self):        widget = self.focus_get()        return widget.get()    def append(self, text):    # get the widget with the focus         widget = self.focus_get()    # insert the value         widget.insert("insert", text)    def clear(self):        widget = self.focus_get()        widget.delete(0, 'end')    def backspace(self):        widget = self.focus_get()        text = widget.get()        text = text[:-1]        self.clear()        self.append(text)class machine1(tk.Frame):    def __init__(self, parent, controller):        tk.Frame.__init__(self, parent)        self.controller = controller        label = tk.Label(self, text="Machine 1", font=controller.title_font)        label.grid(row=0, column=0, sticky='news')        e1 = tk.Entry(self, highlightthickness = 2)        e1.grid(row=2, column=0, sticky='news')        e1.focus_set()   # by default start with this one        e2 = tk.Entry(self, highlightthickness = 2)        e2.grid(row=3, column=0, sticky='news')        kbd = Keypad(self)        kbd.grid(row=5, column=0, columnspan=3)        button3 = tk.Button(self, text="Run",                            command=lambda: controller.show_frame("running"))        button3.grid(row=6, column=2, sticky='news')        class machine2(tk.Frame):    def __init__(self, parent, controller):        tk.Frame.__init__(self, parent)        self.controller = controller        label = tk.Label(self, text="Machine 2", font=controller.title_font)        label.grid(row=0, column=0, sticky='news')        e1 = tk.Entry(self, highlightthickness = 2)        e1.grid(row=2, column=0, sticky='news')        e1.focus_set()   # by default start with this one        e2 = tk.Entry(self, highlightthickness = 2)        e2.grid(row=3, column=0, sticky='news')        kbd = Keypad(self)        kbd.grid(row=5, column=0, columnspan=3)        button3 = tk.Button(self, text="Run",                            command=lambda: controller.show_frame("running"))        button3.grid(row=6, column=2, sticky='news')class running(tk.Frame):    def __init__(self, parent, controller):        tk.Frame.__init__(self, parent)        self.controller = controller        label = tk.Label(self, text="Run", font=controller.title_font)        label.grid(row=0, column=0, sticky='news')        button1 = tk.Button(self, text="Machine 1",                           command=lambda: controller.show_frame("machine1"))        button2 = tk.Button(self, text="Machine 2",                           command=lambda: controller.show_frame("machine2"))        button1.grid(row=5, column=0, sticky='news')        button2.grid(row=5, column=1, sticky='news')        e1 = tk.Entry(self, highlightthickness = 2)        e1.grid(row=1, column=1, sticky='news')if __name__ == "__main__":    app = MyApp()    app.geometry("800x480")    app.mainloop()``b

Viewing all articles
Browse latest Browse all 55

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>