I am working on a Tkinter app that takes input and outputs excel data. I cannot get the entry for size or any other entry field. I want the entry to be obtained and stored in the excel file when the user selects finish order. What change does the code need?
so far everything works except that I do not know how to get the data from the entry because when the button is clicked it runs the code again and thus erases the values.
import datetime
import tkinter as tk
import xlwt as xl
from datetime import datetime
style1 = xl.XFStyle()
style1.num_format_str = "D-MM-YY"
wb = xl.Workbook()
sheet1 = wb.add_sheet("Sheet1", cell_overwrite_ok=True)
sheet1.write(0, 0, datetime.now(), style1)
sheet1.write(0, 1, "Item")
sheet1.write(0, 2, "Size")
sheet1.write(0, 3, "Quantity")
window = tk.Tk()
window.geometry("500x500")
window.title("Furniture order")
item_label = tk.Label(text="Select your item ")
item_label.grid(column= 5, row=0)
def destroy ():
item_label.destroy()
table_button.destroy()
chair_button1.destroy()
def options ():
size_label = tk.Label(text="Enter the size")
size_label.grid(column=0, row=0)
color_label = tk.Label(text="Enter the color")
color_label.grid(column=0, row=1)
quantity_label = tk.Label(text="Enter the quantity")
quantity_label.grid(column=0, row=2)
done_button = tk.Button(text="Finish the order", command=get_data)
done_button.grid(column=1, row=4)
def entry ():
size_entry = tk.Entry(window)
size_entry.grid(column=2, row=0)
color_entry = tk.Entry()
color_entry.grid(column=2, row=1)
quantity_entry = tk.Entry()
quantity_entry.grid(column=2, row=2)
return size_entry.get()
def get_data ():
size = entry()
sheet1.write(1, 1, "table")
sheet1.write(1, 2, size)
wb.save("test2.xls")
def t_d ():
destroy()
options()
entry()
def c_d ():
destroy()
options()
entry()
chair_button1 = tk.Button(text="Chair", command=t_d)
chair_button1.grid(column=0, row=3)
table_button = tk.Button(text="Table", command=c_d)
table_button.grid(column=10, row=3)
wb.save("test2.xls")
window.mainloop()
Related
I want to allow the user to create as many labels as they want using the following code:
def new_line(event):
global Row_n
Row_n = Row_n + 1
Choose= tk.Label(frame, text="Choose option", background = "white",font = ("Helvetica",13),fg = "blue")
Choose.grid(row = Row_n, column = 0, sticky = 'nsew')
return Row_n
root.bind('<Return>',lambda event:new_line(event))
That way, by pressing "Enter", the user can create as many "Choose" labels as they wish. But then I want for a second label to appear every time the user clicks on one of the "Choose" label. So I use the following code:
def second_l(event):
Row_n = Row_n+1
second_label = tk.Label(frame, text="Second label")
Choose.bind('<Button-1>',lambda event:second_l(event))
When I try to run this I get the following error:
can't invoke "bind" command: application has been destroyed
If I add "Choose" label outside the "new_line" function the "second_l" function will only work for that label. It won´t work for the labels generated by the "new_line" function.
Whole code:
import tkinter as tk#to create the gui
from tkinter import filedialog, Text #filedialog to pick apps and Text to display text
import os #Allows us to run apps
root = tk.Tk()
frame = tk.Frame(root,bg="white")
frame.place(relwidth=0.8,relheight=0.7,relx=0.1,rely=0.1)
Row_n=0
def new_line(event):
global Row_n
Row_n = Row_n + 1
Choose= tk.Label(frame, text="Choose option", background = "white",font = ("Helvetica",13),fg = "blue")
Choose.grid(row = Row_n, column = 0, sticky = 'nsew')
return Row_n
root.bind('<Return>',lambda event:new_line(event))
def second_l(event):
global Row_n
Row_n = Row_n+1
second_label = tk.Label(frame, text="Second label")
second_label.grid(row = Row_n, column = 0, sticky = 'nsew')
Choose.bind('<Button-1>',lambda event:second_l(event))
root.mainloop()
I am unable to understand why are you getting this error "can't invoke "bind" command" but I think, I understand your problem
you can try this:-
import tkinter as tk#to create the gui
from tkinter import filedialog, Text #filedialog to pick apps and Text to display text
import os #Allows us to run apps
root = tk.Tk()
frame = tk.Frame(root,bg="white")
frame.place(relwidth=0.8,relheight=0.7,relx=0.1,rely=0.1)
Row_n=0
Choose= tk.Label(frame, text="", background = "white",font = ("Helvetica",13),fg = "blue")
def new_line(event):
global Row_n
Row_n = Row_n + 1
Choose.config(text="Choose option")
Choose.grid(row = Row_n, column = 0, sticky = 'nsew')
return Row_n
root.bind('<Return>',lambda event:new_line(event))
def second_l(event):
global Row_n
Row_n = Row_n+1
second_label = tk.Label(frame, text="Second label")
second_label.grid(row = Row_n, column = 0, sticky = 'nsew')
Choose.bind('<Button-1>',lambda event:second_l(event))
root.mainloop()
I have a program (below) that creates an entry box that shows only '*' when you type in it and it creates a button next to the text box. I want the button to show what has been typed in the entry box while it is being pressed. I have tried to use <Button-1> and <ButtonRelease-1> but to no avail.
import tkinter as tk
def myFunc() :
#Something#
pass
root = tk.Tk()
root.title('Password')
password = tk.Entry(root, show = '*')
password.grid(row = 0, column = 1)
password_label = tk.Label(text = 'Password:')
password_label.grid(row = 0, column = 0)
button = tk.Button(text = '.', command = myFunc)
button.grid(row = 0, column = 2)
Try this:
import tkinter as tk
def show_stars(event):
password.config(show="*")
def show_chars(event):
password.config(show="")
root = tk.Tk()
root.title("Password")
password = tk.Entry(root, show="*")
password.grid(row=0, column=1)
password_label = tk.Label(text="Password:")
password_label.grid(row = 0, column=0)
button = tk.Button(text="Show password")
button.grid(row=0, column=2)
button.bind("<ButtonPress-1>", show_chars)
button.bind("<ButtonRelease-1>", show_stars)
Using the bindings that #BryanOakley suggested
Only if button is pressed it changes the text from * to the text entered.
import tkinter as tk
def myFunc():
#Something#
if password.cget("show")=="*":
password.configure(show="")
elif password.cget("show") =="":
password.configure(show="*")
root = tk.Tk()
root.title('Password')
password = tk.Entry(root, show = '*')
p = password
password.grid(row = 0, column = 1)
password_label = tk.Label(text = 'Password:')
password_label.grid(row = 0, column = 0)
button = tk.Button(text = '.', command = myFunc)
button.grid(row = 0, column = 2)
root.mainloop()
Can you please help me with follwing issue I face:
When I am creating radiobutton with tkinter, I don't have a problem to select from the list.
However, if I put the same script under a menu, then selected option is always the default one, ("Python",1) in this specific case. Do you have any idea how to overcome this? Thanks in advance!
import tkinter as tk
root_m = tk.Tk()
root_m.geometry("400x200")
frame_m = tk.Frame(root_m)
root_m.title("NUMERIC UNIVERSE")
frame_m.pack()
def chars_merging():
languages = [
("Python",1),
("Perl",2),
("Java",3),
("C++",4),
("C",5)
]
root = tk.Tk()
root.geometry("400x200")
frame = tk.Frame(root)
root.title("SELECT SOMETHING")
frame.pack()
v = tk.IntVar()
v.set(0) # initializing the choice, i.e. Python
label = tk.Label(frame,
text="""Choose your favourite
programming language:""",
justify = tk.LEFT,
padx = 20)
label.pack()
def ShowChoice():
global data_sel
data_sel = v.get()
print(data_sel)
for val, language in enumerate(languages):
tk.Radiobutton(frame,
text=language,
indicatoron = 0,
width = 20,
padx = 20,
variable=data_sel,
command=ShowChoice,
value=val).pack(anchor=tk.W)
root.mainloop()
#return(languages[v.get()])
print("You selected", languages[v.get()])
button3 = tk.Button(frame_m,
text="3.Prepare and merge chars",
command=chars_merging,
width=25)
button3.pack()
# CLOSING THE WINDOW ---------------------------------------------------------
def finish():
root_m.destroy()
button_n = tk.Button(frame_m,
text="Finish",
command=finish,
width=25)
button_n.pack()
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
root_m.mainloop()
from tkinter import *
import sys,math,random,datetime,os,time
import tkinter.messagebox
from tkinter import filedialog
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import showerror
from time import gmtime, strftime
import xlsxwriter
export = "Excel"
current_time = strftime("%m-%d-%Y %H:%M", gmtime())
root = Tk()
e1 = Entry()
e1.insert(10, "First Name")
e2 = Entry()
e2.insert(10, "Last Name")
Here is where I am trying to format variable to become string.
fullname = "%s %s" % (e1, e2)
title = ["Titan Tech", "Caleb Fahlgren made this!", "Python is life!", "FIRST Robotics!","Doesn't this make your life easier?"]
title = (random.choice(title))
root.title(title)
root.geometry("640x600")
#Submit Button
def Submit():
submit = tkinter.messagebox.askquestion("Submit Entry", "Are you sure you want to submit?")
if submit == "yes":
Xlsx program.
workbook = xlsxwriter.Workbook('TitanTechSummary.xlsx')
worksheet = workbook.add_worksheet()
bold = workbook.add_format({'bold': 1})
worksheet.write('A1', 'Name:',bold)
This is where I am trying to write the players input for name. Or the tkinter Entry(). But I keep getting like a weird decimal number when I look at the excel document. I keep getting this in the B1 field '.140041879004720 .140041884602944'
worksheet.write_string('B1',fullname, bold)
worksheet.write('C1', 'Date:',bold)
I also want to do the same thing with the date.
worksheet.write('D1', 'Date')
workbook.close()
userconfirm = tkinter.messagebox.showinfo("Save","Your entry has been saved to an " + export + " document!")
def keypress(event):
if event.keysym == 'Escape':
root.destroy()
def Quit():
quitask = tkinter.messagebox.askquestion("Quit", "Are you sure you want to quit?")
if quitask == "yes":
root.destroy()
def Insert():
filen = askopenfilename()
filen1 = tkinter.messagebox.showinfo("Saved", "If you opened a picture we saved it!")
firstname = Label(root, text="First Name",font=("Helvetica", 12),fg="green")
lastname = Label(root, text="Last Name",font=("Helvetica", 12),fg="green")
time = Label(root, text=current_time, font=("Helvetica", 12),fg="black")
TextArea = Text()
ScrollBar = Scrollbar(root)
ScrollBar.config(command=TextArea.yview)
TextArea.config(yscrollcommand=ScrollBar.set)
ScrollBar.pack(side=RIGHT, fill=Y)
Submit = Button(root, fg="white", bg="green", text="Submit", width=50, command=Submit, activebackground="yellow")
Quit = Button(root, fg="white", bg="green", text="Quit", width=50, command=Quit,activebackground="yellow")
Insert = Button(root,fg="white", bg="green", text="Insert Images", width=50, command=Insert,activebackground="yellow")
root.bind_all('<Key>', keypress)
firstname.pack()
e1.pack()
lastname.pack()
e2.pack()
time.pack()
TextArea.pack(expand=YES, fill=BOTH)
Insert.pack()
Submit.pack()
Quit.pack()
mainloop()
The problem is this line of code:
fullname = "%s %s" % (e1, e2)
e1 and e2 are entry widgets. Their string representation (ie: if you do str(e1)) is going to be "a weird decimal number".
You need to be calling the get() method of the widget to get the contents:
fullname = "%s %s" % (e1.get(), e2.get())
I'm trying to put old school sequential Tkinter code into class structure code.
So let's consider this example :
import Tkinter as Tk
def StartProcess():
print Text_1_Var.get(), Text_2_Var.get(), Text_3_Var.get()
if __name__ == '__main__':
MainFrame = Tk.Tk()
Tk.Button(MainFrame , text = "Start",command=StartProcess).grid(column=2, row=0)
Tk.Label(MainFrame , text = "1").grid(column=1, row=1)
Text_1_Var = Tk.StringVar()
Text_1 = Tk.Entry(MainFrame , width=40, textvariable = Text_1_Var).grid(column=2, row=1)
Tk.Label(MainFrame , text = "2").grid(column=1, row=2)
Text_2_Var = Tk.StringVar()
Text_2 = Tk.Entry(MainFrame , width=40, textvariable = Text_2_Var).grid(column=2, row=2)
Tk.Label(MainFrame , text = "3").grid(column=1, row=3)
Text_3_Var = Tk.StringVar()
Text_3 = Tk.Entry(MainFrame , width=40, textvariable = Text_3_Var).grid(column=2, row=3)
# etc
MainFrame.mainloop()
On press "Start" it displays values of Entry from 1 to 3.
Now i recode it as follow :
import Tkinter as Tk
def StartProcess():
print "???"
class NewEntry(Tk.Frame):
def __init__(self,master=None,idnumber=None):
Tk.Frame.__init__(self,master)
self.pack(side=Tk.TOP)
self.CreateWidgets(idnumber)
def CreateWidgets(self,idnumber):
Tk.Label(master=self, text = idnumber).grid(column=1, row=0)
self.Text_Var = Tk.StringVar()
self.Text = Tk.Entry(master=self, width=40, textvariable = self.Text_Var).grid(column=2, row=0)
if __name__ == '__main__':
MainFrame = Tk.Tk()
Tk.Button(master=MainFrame,text="Start", command=StartProcess).pack()
for i in range (1, 4): # or more
NewEntry(master=MainFrame,idnumber=str(i))
MainFrame.mainloop()
GUI are both identical. I want to get the same result but i don't know where my function StartProcess should take place and how extract value of each self.Text_Var instance.
It's not enough to create a NewEntry object; you need to save references to them so you can access them later (e.g., from StartProcess).
entries = []
for i in range (1, 4): # or more
e = NewEntry(master=MainFrame,idnumber=str(i))
entries.append(e)
# Or more simply,
# entries = [NewEntry(master=MainFrame, idnumber=str(i)) for i in range(1,4)]
Then, StartProcess becomes something like
def StartProcess():
strings = [x.Text_Var.get() for x in entries]
print " ".join(strings)