Tkinter创建意外的额外空白窗口

时间:2017-05-21 08:47:32

标签: python user-interface tkinter

我使用Python 3.5创建一个简单的GUI,通过textbox从用户接收信息,然后保存到.txt文件。

我注意到的是:

  1. 启动时会自动点击SaveButton,但再次点击则不会执行任何操作;
  2. 另一个名为tk的空白窗口出现在前景中。
  3. 这是我的第一个GUI python应用程序,因此非常感谢简单和耐心。

    以下是代码:

    #Program by Fares Al Ghazy started 20/5/2017
    #Python script to assign key combinations to bash commands, should run in the background at startup
    #Since this program is meant to release bash code, it is obviously non-system agnostic and only works linux systems that use BASH
    #Further versions which support more OSs may come to life
    #This is one file which only creates the GUI, another file is needed to use the info taken by this program
    
    import tkinter as tk
    #function to write to file
    def SaveFunction(e1,e2):
        print("opening file")
        file = open("BinderData.txt","a")
        combo = e1.get()
        print("combo =" + combo)
        performed = e2.get()
        print("action = " + performed)
        print("Writing to file")
        file.write(combo)
        file.write(performed)
        print("closing file")
        file.close()
        print("file closed")
    
    class MainFrame(tk.Tk):
        def __init__(self,*args,**kwargs):
            tk.Tk.__init__(self,*args,**kwargs)
            #create GUI to take in key combinations and bash codes, then save them in file
            root = tk.Tk() # create new window
            root.wm_title("Key binder") #set title
            #create labels and text boxes
            KeyComboLabel = tk.Label(root,text = "Key combination = ")
            KeyComboEntry = tk.Entry(root)
    
            ActionLabel = tk.Label(root, text = "Command to be executed = ")
            ActionEntry = tk.Entry(root)
            #place widgets in positions
            KeyComboLabel.grid(row=0,column =0,sticky = tk.E)
            ActionLabel.grid(row=1,column =0, sticky = tk.E)
    
            KeyComboEntry.grid(row=0,column =1)
            ActionEntry.grid(row=1,column =1)
            #create save button
            SaveButton= tk.Button(root,text = "save")
            SaveButton.grid(row=2,column =2, sticky = tk.E , command = SaveFunction(KeyComboEntry,ActionEntry))
    
    app = MainFrame()
    app.mainloop()
    

1 个答案:

答案 0 :(得分:1)

  1. 执行SaveFunction回调并将结果绑定到command参数;尝试使用lambda表达式。此外,command参数必须转到构造函数,而不是布局函数。

    SaveButton= tk.Button(root,text = "save", command = lambda: SaveFunction(KeyComboEntry,ActionEntry))
    SaveButton.grid(row=2,column =2, sticky = tk.E )
    
  2. 您获得了额外的空窗口,因为您创建了两个Tk个实例,第一个是MainFrame本身,扩展了Tk,第二个是Tk()你在__init__创建。不要创建另一个Tk,只需使用self作为root

    root = self # or change all "root" to "self" in the code below
    

    或者没有MainFrame延长Tk

  3. 有关command回调部分和lambda的更多说明。正如我所说,问题在于您执行该函数,然后将该执行的结果绑定到command。为了更清楚,command=SaveFunction(KeyComboEntry, ActionEntry)

    相同
    cmd = SaveFunction(KeyComboEntry, ActionEntry)
    SaveButton= tk.Button(root, text="save", command=cmd)
    

    这显然不是你想要的。如果你要调用一个没有参数的函数,你可以只使用command=SaveFunction而没有(),因此不会调用函数,而是使用函数本身作为参数,但是因为{ {1}}需要参数,您必须定义内联SaveFunction,调用lambda,它本身不带参数。