Reputation: 55
I am using Python 3.5 to create a simple GUI that takes in information from the user via a textbox
, then saves to a .txt
file.
What I've noticed is the following:
SaveButton
is automatically clicked at startup, but clicking again does nothing;This is my first GUI python application, so simplicity and patience are appreciated.
Here is the code:
#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()
Upvotes: 2
Views: 1393
Reputation: 82899
You execute the SaveFunction
callback and bind the result to the command
parameter; try a lambda
expression instead. Also, the command
parameter has to go to the constructor, not to the layout function.
SaveButton= tk.Button(root,text = "save", command = lambda: SaveFunction(KeyComboEntry,ActionEntry))
SaveButton.grid(row=2,column =2, sticky = tk.E )
You get the additional empty window because you create two Tk
instances, the first being the MainFrame
itself, extending Tk
, and the second the Tk()
you create in __init__
. Instead of creating another Tk
, just use self
as root
:
root = self # or change all "root" to "self" in the code below
Or don't have MainFrame
extend Tk
.
Some more clarification about the command
callback part and lambda
. The problem, as I said, is that you execute the function and then bind the result of that execution to command
. To make this clearer, command=SaveFunction(KeyComboEntry, ActionEntry)
is the same as
cmd = SaveFunction(KeyComboEntry, ActionEntry)
SaveButton= tk.Button(root, text="save", command=cmd)
which is obviously not what you want. If you would call a function with no parameters, you could just use command=SaveFunction
without ()
, thus not calling the function but using the function itself as a parameter, but since SaveFunction
needs parameters, you have to define an in-line lambda
, calling SaveFunction
, which itself takes no parameters.
Upvotes: 1