【问题标题】:Python TKinter binding to enter keyPython TKinter 绑定输入密钥
【发布时间】:2015-04-21 18:29:22
【问题描述】:

我已尝试应用其他几个 SO Question Answers 中给出的各种示例,但我无法做到。

我的目标是在按下“enter”时能够向 telnet 服务器发送一行文本。我的步骤是简单地将最后一行(因为之前的“输入”被按下)发送到输出面板。

我得到了一组笨拙的窗口,并且似乎已将文本框附加到它们,但是当我应用任何绑定类型代码时,我最终无法在输入文本框中进行书写。当我删除绑定代码时,我至少可以在任一文本框中输入文本。

这个问题与我的另一个 query 有关,这就是我现在尝试吸收 GUI 编码的原因。

代码,其中骨架来自Thinking in Tkinter的tut信息

编辑:代码行已更改:Tiger 的 cmets

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()

【问题讨论】:

    标签: python tkinter user-input


    【解决方案1】:

    我对您的代码进行了一些更改,将 cmets 标记为 T3 以提高可见性。这允许您在 ButtonsText 字段上使用 Return,“连接”按钮“救援”焦点有效。

    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()
    

    【讨论】:

    • 感谢您的意见。我试过了,现在我至少可以在 InputText 框中输入文本,但是现在正在触发事件,我可以看到..
    • 抱歉,no 事件,我可以看到。我在名为 (returnkey()) 的函数中放置了一个 myParentdestroy() 但是 bupkis,=/
    • 在将按键绑定到Button 小部件时仍然存在一些问题,并且您将相同的按键绑定到多个功能(绑定到“切换连接按钮颜色”功能和“退出”功能)。将其绑定到一个命令,例如button1Click,绑定到一个小部件,例如self.myParent。然后,每当用户按下 Return 键时,“连接”按钮就会切换颜色。如果您想将按键绑定到退出功能,请尝试将&lt;Esc&gt; 绑定到self.myParent
    • ok ... 我得到的原始 tut' 显示了如何将焦点放在按钮上,以便 return 将“单击”按钮...我一直在猜测,但是,如果要保留此类功能,我将无法将其绑定到父框架,否则会变得模棱两可,正在“单击”哪个按钮...不?
    • 看起来Button 绑定工作 - 他们只需要有焦点(模糊的轮廓)。但是,如果您绑定self.InputText.bind('&lt;Return&gt;', self.return_key),您可以在按下 Return 时键入并查看添加到框中的文本,但是一旦焦点位于 Text 小部件中,您就无法更改焦点。我将通过一些修改来编辑我的答案。
    猜你喜欢
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    • 2014-05-11
    • 1970-01-01
    相关资源
    最近更新 更多