1

I've tried applying the various examples given in several other SO Question Answers but it's eluding me.

My goal is to be able to send a line of text to a telnet server when "enter" is pressed. My steps toward that are to simply send the last line (since the previous "enter" was pressed) to the output panel.

I've gotten a clumsy set of windows and seem to have attached Text boxes to them, but when I apply any binding type code I end up being unable to write in the input text box. When I remove the binding code I can at least type text into either text box.

This issue relates back to my other query, which is why I am now trying to absorb GUI coding.

The code, of which the skeleton came from the tut' info at Thinking in Tkinter

EDIT: Code lines changed re: Tiger's comments

from Tkinter import *

class MyApp:
    def __init__(self, parent):

        #------ constants for controlling layout of buttons ------
        button_width = 15
        button_padx = "2m"
        button_pady = "1m"
        buttons_frame_padx =  "3m"
        buttons_frame_pady =  "0m"
        buttons_frame_ipadx = "3m"
        buttons_frame_ipady = "0m"
        # -------------- end button constants ----------------

        # First declare ORIGINAL Window area
        self.myParent = parent
        self.myParent.geometry("640x400")

        # Layer ONE
        ### Our First layer/frame is called frameLayerOne
        self.frameLayerOne = Frame(parent, bg="green")
        self.frameLayerOne.pack(expand=YES, fill=BOTH)

        ### We will stack vertically inside frameLayerOne.
        ### Inside frameLayerOne, we will create 
        ### a menu_frame, then a sub frame into which we will
        ### put an output_frame and an input_frame.

        # Layer TWO
        # MENU FRAME - Layer Two
        self.menu_frame = Frame(self.frameLayerOne, borderwidth=5,  relief=RIDGE, bg="cyan")
        self.menu_frame.pack(side=TOP, expand=NO,  padx=0, pady=0, ipadx=0, ipady=0, fill=X)

        MessageMenuFrame="Menu frame.\n"
        # Label(self.menu_frame, text=MessageMenuFrame, justify=LEFT).pack(side=TOP, anchor=W)

        # buttons frame
        self.buttons_frame = Frame(self.menu_frame) # , bg="red"
        self.buttons_frame.pack(side=TOP,
            ipadx=buttons_frame_ipadx,
            ipady=buttons_frame_ipady,
            padx=buttons_frame_padx,
            pady=buttons_frame_pady,)

        # now we add the buttons to the buttons_frame
        self.button1 = Button(self.buttons_frame, command=self.button1Click)
        self.button1.configure(text="CONNECT", background= "green")
        self.button1.focus_force()
        self.button1.configure(width=button_width,
            padx=button_padx,
            pady=button_pady)

        self.button1.pack(side=LEFT)
        self.button1.bind("<Return>", self.button1Click_a)

        self.button2 = Button(self.buttons_frame, command=self.button2Click)
        self.button2.configure(text="QUIT", background="red")
        self.button2.configure(width=button_width,
            padx=button_padx,
            pady=button_pady)

        self.button2.pack(side=RIGHT)
        self.button2.bind("<Return>", self.button2Click_a)

        # SUB FRAME - Layer Two
        self.sub_frame = Frame(self.frameLayerOne) # , bg="red"
        self.sub_frame.pack(side=BOTTOM, expand=YES,  padx=0, pady=0, ipadx=0, ipady=0, fill=BOTH)

        # Layer THREE
        # INPUT FRAME - Layer Three
        self.input_frame = Frame(self.sub_frame, borderwidth=5,  relief=RIDGE, bg="black")
        self.input_frame.pack(side=BOTTOM, expand=NO,  padx=0, pady=0, ipadx=0, ipady=0, fill=X)

        # Text widget for user input to send to server
        self.InputText = Text(self.input_frame, height=4, bg="black", fg="green")
        self.InputText.pack()
        self.InputText.insert(END, "User input here")

        # Moded these two lines on Tiger's advice
        self.input_frame.bindtags(('.input_frame','input_frame','post-class-bindings', '.', 'all'))
        self.input_frame.bind_class('<Return>', self.return_key)

        # OUTPUT FRAME - Layer Three
        self.output_frame = Frame(self.sub_frame, borderwidth=5,  relief=RIDGE, bg="blue")
        self.output_frame.pack(side=BOTTOM, expand=YES,  padx=0, pady=0, ipadx=5, ipady=25, fill=BOTH)

        # Text widget for output from code and server
        self.OutputText = Text(self.output_frame, bg="black", fg="green")
        self.OutputText.pack()
        self.OutputText.insert(END, "server and code output here")


    def return_key(self, event):
        text = "you pressed Return"
        self.InputText.insert(END, text)

    def button1Click(self):
        if self.button1["background"] == "green":
            self.button1["background"] = "yellow"
        else:
            self.button1["background"] = "green"

    def button1Click_a(self, event):
        self.button1Click()


    def button2Click(self):
        self.myParent.destroy()


    def button2Click_a(self, event):
        self.button2Click()


root = Tk()
myapp = MyApp(root)
root.mainloop()
Community
  • 1
  • 1
Dee
  • 191
  • 1
  • 11

1 Answers1

2

I've made some changes to your code, labeling the comments T3 for visibility. This allows you to use Return on the Buttons and Text field, with the "connect" button "rescuing" focus, in effect.

from Tkinter import *

class MyApp:
    def __init__(self, parent):

        #------ constants for controlling layout of buttons ------
        button_width = 15
        button_padx = "2m"
        button_pady = "1m"
        buttons_frame_padx =  "3m"
        buttons_frame_pady =  "0m"
        buttons_frame_ipadx = "3m"
        buttons_frame_ipady = "0m"
        # -------------- end button constants ----------------

        # First declare ORIGINAL Window area
        self.myParent = parent
        self.myParent.geometry("640x400")

        # Layer ONE
        ### Our First layer/frame is called frameLayerOne
        self.frameLayerOne = Frame(parent, bg="green")
        self.frameLayerOne.pack(expand=YES, fill=BOTH)

        ### We will stack vertically inside frameLayerOne.
        ### Inside frameLayerOne, we will create 
        ### a menu_frame, then a sub frame into which we will
        ### put an output_frame and an input_frame.

        # Layer TWO
        # MENU FRAME - Layer Two
        self.menu_frame = Frame(self.frameLayerOne, borderwidth=5,  relief=RIDGE, bg="cyan")
        self.menu_frame.pack(side=TOP, expand=NO,  padx=0, pady=0, ipadx=0, ipady=0, fill=X)

        MessageMenuFrame="Menu frame.\n"
        # Label(self.menu_frame, text=MessageMenuFrame, justify=LEFT).pack(side=TOP, anchor=W)

        # buttons frame
        self.buttons_frame = Frame(self.menu_frame) # , bg="red"
        self.buttons_frame.pack(side=TOP,
            ipadx=buttons_frame_ipadx,
            ipady=buttons_frame_ipady,
            padx=buttons_frame_padx,
            pady=buttons_frame_pady,)

        # now we add the buttons to the buttons_frame
        self.button1 = Button(self.buttons_frame, command=self.button1Click)
        self.button1.configure(text="CONNECT", background= "green")
        self.button1.focus_force()
        self.button1.configure(width=button_width,
            padx=button_padx,
            pady=button_pady)

        self.button1.pack(side=LEFT)
        # T3 - bound to regular button1Click
        self.button1.bind("<Return>", self.button1Click)

        self.button2 = Button(self.buttons_frame, command=self.button2Click)
        self.button2.configure(text="QUIT", background="red")
        self.button2.configure(width=button_width,
            padx=button_padx,
            pady=button_pady)

        self.button2.pack(side=RIGHT)
        # T3 - bound to regular button2Click
        self.button2.bind("<Return>", self.button2Click)

        # SUB FRAME - Layer Two
        self.sub_frame = Frame(self.frameLayerOne) # , bg="red"
        self.sub_frame.pack(side=BOTTOM, expand=YES,  padx=0, pady=0, ipadx=0, ipady=0, fill=BOTH)

        # Layer THREE
        # INPUT FRAME - Layer Three
        self.input_frame = Frame(self.sub_frame, borderwidth=5,  relief=RIDGE, bg="black")
        self.input_frame.pack(side=BOTTOM, expand=NO,  padx=0, pady=0, ipadx=0, ipady=0, fill=X)

        # Text widget for user input to send to server
        self.InputText = Text(self.input_frame, height=4, bg="black", fg="green")
        self.InputText.pack()
        self.InputText.insert(END, "User input here")

        self.InputText.bind('<Return>', self.return_key)

        # OUTPUT FRAME - Layer Three
        self.output_frame = Frame(self.sub_frame, borderwidth=5,  relief=RIDGE, bg="blue")
        self.output_frame.pack(side=BOTTOM, expand=YES,  padx=0, pady=0, ipadx=5, ipady=25, fill=BOTH)

        # Text widget for output from code and server
        self.OutputText = Text(self.output_frame, bg="black", fg="green")
        self.OutputText.pack()
        self.OutputText.insert(END, "server and code output here")


    def return_key(self, event):
        text = "you pressed Return"
        self.InputText.insert(END, text)

    def button1Click(self, event=None): # T3 - give it a default event of None
        if self.button1["background"] == "green":
            self.button1["background"] = "yellow"
        else:
            self.button1["background"] = "green"
        self.button1.focus_set() # T3 - set focus to this button so Return works

    def button2Click(self, event=None): # T3 - give it a default event of None
        self.myParent.destroy()

root = Tk()
myapp = MyApp(root)
root.mainloop()
TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • Thanks for the input. I tried it, and now I can at least enter text in the InputText box now, but now event is being triggered, that I can see.. – Dee Apr 21 '15 at 08:48
  • sorry, **no** event, that I can see. I placed a myParentdestroy() in the function called (returnkey()) but bupkis, =/ – Dee Apr 21 '15 at 09:09
  • You still have some issues where you're binding keypresses to `Button` widgets, and you have the same keypress bound to multiple functions (bound to both the "switch connect button color" function and the "quit" function). Bind it to one command, such as `button1Click`, to one widget, such as `self.myParent`. Then, whenever the user presses the Return key, the "connect" button will switch colors. If you want to bind a keypress to the exit function, try binding `` to `self.myParent`. – TigerhawkT3 Apr 21 '15 at 09:14
  • ok ... the original tut' I got that from was showing how focus can be on a button such that _return_ will 'click' the button... and I'm guessing, as always but, if such functionality were to be kept I can't bind it to the parent frame or it becomes ambiguous which button is being 'clicked' ... no ? – Dee Apr 21 '15 at 09:28
  • Looks like the `Button` bindings work - they just have to have focus (faint outline). However, if you bind `self.InputText.bind('', self.return_key)`, you can type and see the text added to the box when you press Return, but you can't change the focus once it's in the Text widget. I will edit my answer with some modifications. – TigerhawkT3 Apr 21 '15 at 10:23
  • Many thanks, it's catching the bind now and output appearing in the text box (I changed to output frame) I can now pursue sending the text elsewhere - I'll have to study this stuff _deeply_ try to figure/remember it. **Thank you** – Dee Apr 21 '15 at 10:48