I'm trying to create a GUI that allows to the user to manipulate data from mysql database. So the user must add a trip(trip-id, trip-short-name ...) then add stop times for each trip using Entry from tkinter.
paths=''
new_trip_id=''
def add_trip():
top = Toplevel()
top.title("Trips")
top.geometry("600x300")
lbl1 = Label(top, text = 'service_id:', font = {'Helvetica',10})
lbl1.place(relx=0.2, rely=0.1)
entry1 = Entry(top)
entry1.place(relx=0.45, rely=0.1)
global new_trip_id
lbl2 = Label(top, text = 'trip_id:', font = {'Helvetica',10})
lbl2.place(relx=0.2, rely=0.25)
entry2 = Entry(top)
entry2.place(relx=0.45, rely=0.25)
new_trip_id=entry2.get()
lbl3 = Label(top, text = 'trip_headsign')
entry3 = Entry(top)
entry3.place(relx=0.45, rely=0.4)
lbl4 = Label(top, text = 'trip_short_name:', font{'Helvetica',10})
lbl4.place(relx=0.2, rely=0.55)
entry4 = Entry(top)
entry4.place(relx=0.45, rely=0.55)
entry4.bind('<Return>', add_times)
button1 = Button(top, text="Cancel")
button1.place(relx=0.5 ,rely=0.7)
def add_times(event):
mysql.connector("INSERT INTO trips VALUES service_id, trip_id,
trip_headsign, trip_short_name",
[enty1.get(), entry2.get(), enty3.get(),
enty4.get()])
top = Toplevel()
top.title("Trips")
top.geometry("600x300")
Ididn't found a solution that allows to the user to add data.
Related
I have 2 Entrys and one button. I want to make that button's state disabled until the two Entrys are filled in. How can I achieve that?
howManyStocksLabel = Label(root, text = "How many stocks do you want to evaluate?")
howManyStocksLabel.grid(row = 1, column = 0)
howManyStocksEntry = Entry(root, borderwidth = 3)
howManyStocksEntry.grid(row = 1, column = 1)
riskLabel = Label(root, text = "Enter risk %")
riskLabel.grid(row = 2, column = 0, sticky = 'w')
riskEntry = Entry(root, borderwidth = 3)
riskEntry.grid(row = 2, column = 1)
nextButton = Button(root, text = "Next!", width = 20, height = 2,state = DISABLED,
fg = 'green', bg = 'white',
command= lambda: myClick(riskEntry, howManyStocksEntry, var))
nextButton.grid(row = 4, column = 1)
I tried to check whether the entries are filled in or not by:
if(riskEntry.get() != ""):
....................
but it just doesn't work.
You need to check if the value is there after the user inputs it. Also, you can use tk.StringVar() as a text variable and trace it.
Here is an example:
import tkinter as tk
def check_entry(*args):
if r1.get() and r2.get():
b1.config(state='normal')
else:
b1.config(state='disabled')
root = tk.Tk()
r1 = tk.StringVar(master=root)
r2 = tk.StringVar(master=root)
e1 = tk.Entry(root, textvariable=r1)
e1.pack()
e2 = tk.Entry(root, textvariable=r2)
e2.pack()
b1 = tk.Button(root, text='Click Me!', state='disabled')
b1.pack()
r1.trace('w', check_entry)
r2.trace('w', check_entry)
root.mainloop()
You will need to use a binding on your entry widgets to check whether the user has entered anything into the entry or not.
This code will fire the check_entry function every time the user types in one of the entry boxes:
riskEntry.bind('<KeyRelease>', check_entry)
howManyStocksEntry.bind('<KeyRelease>', check_entry)
Then your check_entry function might look like this:
def check_entry(event): #event is required for all functions that use a binding
if riskEntry.get() and howManyStocksEntry.get():
nextButton.config(state=NORMAL)
else:
nextButton.config(state=DISABLED)
One way to do it would be to utilize the ability to "validate" their contents that Entry widgets support — see adding validation to an Entry widget — but make it check the contents of multiple Entry widgets and change the state of a Button accordingly.
Below shows how to do this via a helper class that encapsulates most of the messy details needed to make doing it relatively painless. Any number of Entry widgets can be "watched", so it scales well to handle forms consisting of many more than merely two entries.
from functools import partial
import tkinter as tk
from tkinter.constants import *
class ButtonEnabler:
""" Enable/disable a Button depending on whether all specified Entry widgets
are non-empty (i.e. contain at least one character).
"""
def __init__(self, button, *entries):
self.button = button
self.entries = entries
for entry in self.entries:
func = root.register(partial(self.check_entries, entry))
entry.config(validate="key", validatecommand=(func, '%P'))
def check_entries(self, this_entry, new_value):
other_entries = (entry for entry in self.entries if entry is not this_entry)
all_others_filled = all(entry.get() for entry in other_entries)
combined = bool(new_value) and all_others_filled
self.button.config(state=NORMAL if combined else DISABLED)
return True
root = tk.Tk()
howManyStocksLabel = tk.Label(root, text="How many stocks do you want to evaluate?")
howManyStocksLabel.grid(row=1, column=0)
howManyStocksEntry = tk.Entry(root, borderwidth=3)
howManyStocksEntry.grid(row=1, column=1)
riskLabel = tk.Label(root, text="Enter risk %")
riskLabel.grid(row=2, column=0, sticky='w')
riskEntry = tk.Entry(root, borderwidth=3)
riskEntry.grid(row=2, column=1)
nextButton = tk.Button(root, text="Next!", width=20, height=2, state=DISABLED,
fg='green', bg='white', disabledforeground='light grey',
command=lambda: myClick(riskEntry, howManyStocksEntry, var))
nextButton.grid(row=4, column=1)
enabler = ButtonEnabler(nextButton, howManyStocksEntry, riskEntry)
root.mainloop()
I have a Submit button that prints the output on the tkinter widget label. Everytime I change the input and click the Submit the output is displayed but not at the same place i.e. The previous content of the label is not overwritten.
from tkinter import *
from tkinter import filedialog
root = Tk()
root.title("ImageValidation ")
root.geometry("600x600+100+100")
pathlist = [None, None] # holds the two files selected
labels = []
def browse_button(index):
global filename
filename = filedialog.askopenfilename(title = "Choose your file",filetypes = (("jpeg files","*.jpeg"),("all files","*.*")))
pathlist[index] = filename
heading = Label(root, text = "Select 2 images you want to Validate",
font=("arial",15,"bold","underline"), fg="blue").pack()
label1 = Label(root, text = "Enter Image 1", font=("arial",10,"bold"),
fg="black").place(x=10, y = 100)
label2 = Label(root, text = "Enter Image 2", font=("arial",10,"bold"),
fg="black").place(x=10, y = 200)
button = Button(root,text="Choose an Sign1",width = 30,command= lambda:
browse_button(0)).place(x=250, y= 100)
button = Button(root,text="Choose an Sign2",width = 30,command=
lambda: browse_button(1)).place(x=250, y= 200)
def display():
ImageVerification(pathlist[0], pathlist[1])
l1 = Label(root,text=Scriptoutput, width = 200 )
l1.pack(side='bottom', padx=50, pady=50)
#Scriptoutput is the output variable from the main code.
submit_button = Button(text="Submit", width=15,command = display)
submit_button.pack(side='bottom', padx=15, pady=15)
root.mainloop()
A 'refresh' button that would clear the Label of its content and lets you overwrite it.
I am taking your function ImageVerification() as a blackbox and assuming it is working.
The reason this is happening is because you create a new Label, whenever the Submit button is pressed. What you have to do is to create the display Label outside the function and configure its text, whenever the button is pressed. Something like this.
l1 = Label(root, text="", width=200)
l1.pack(side='bottom', padx=50, pady=50)
def display():
ImageVerification(pathlist[0], pathlist[1])
l1.configure(text=Scriptoutput)
#Scriptoutput is the output variable from the main code.
submit_button = Button(text="Submit", width=15,command = display)
submit_button.pack(side='bottom', padx=15, pady=15)
I am building a chat GUI. On enter-key press, I want the text fields to be shown on the text box as well as be saved in a file. I do not want to use separate button. It is being shown in the text box correctly but not getting saved in the file. Please tell me how can it be done. This is my first time using tkinter.
from Tkinter import *
root = Tk()
frame = Frame(root, width=300, height=1000)
frame.pack(side=BOTTOM)
#username entry
L1 = Label(frame, text="User Name")
L1.pack(side = LEFT)
input_username = StringVar()
input_field1 = Entry(frame, text=input_username, width=10)
input_field1.pack(side=LEFT, fill=X)
#addresee entry
L2 = Label(frame, text="#")
L2.pack(side = LEFT)
input_addresee = StringVar()
input_field2 = Entry(frame, text=input_addresee, width=10)
input_field2.pack(side=LEFT, fill=X)
#user comment entry
L3 = Label(frame, text="Comment")
L3.pack(side = LEFT)
input_usertext = StringVar()
input_field3 = Entry(frame, text=input_usertext, width=100)
input_field3.pack(side=LEFT, fill=X)
#write to a file
def save():
text = input_field1.get() + input_field2.get() + input_field3.get()
with open("test.txt", "w") as f:
f.write(text)
#chat box
chats = Text(root)
chats.pack()
def Enter_pressed(event):
input_get_name = input_field1.get()
print(input_get_name)
chats.insert(INSERT, '%s : ' % input_get_name)
input_username.set('')
input_get_add = input_field2.get()
print(input_get_add)
chats.insert(INSERT, '#%s : ' % input_get_add)
input_addresee.set('')
input_get_comment = input_field3.get()
print(input_get_comment)
chats.insert(INSERT, '%s\n' % input_get_comment)
input_usertext.set('')
save()
frame2 = Frame(root)
L2_1 = Label(frame2, text="All chats")
L2_1.pack(side = TOP)
input_field1.bind(Enter_pressed)
input_field2.bind(Enter_pressed)
input_field3.bind("<Return>", Enter_pressed)
frame2.pack()
root.mainloop()
As you said you are setting the input fields to blank
Here's the solution:
def save(text):
with open("test.txt", "w") as f:
f.write(text)
And when calling save:
save(input_get_name+": "+input_get_add+": "+input_get_comment)
I have a frame with a checkbox and a X button in it. When I hit the X button, I want to delete that frame. Is there a way to denote parent frames? I can't refer to it by its variable name because I made it using a function so all the relevant frames share the same name.
My code:
import tkinter
master = tkinter.Tk()
master.title("test1")
master.geometry("300x300")
checkboxArea = tkinter.Frame(master)
checkboxArea.pack(fill=tkinter.X)
inputStuff = tkinter.Frame(master)
def removeInputStuff():
inputStuff.pack_forget()
buttonAdd.pack()
buttonDone.remove()
buttonDone = tkinter.Button(inputStuff, text = "Close Input", command=removeInputStuff)
def createInputStuff():
paddingFrame = tkinter.Frame(inputStuff, height=5)
paddingFrame.pack(fill=tkinter.X)
buttonDone.pack()
inputStuff.pack()
buttonAdd.pack_forget()
buttonAdd = tkinter.Button(master, text="Add Item", command=createInputStuff)
buttonAdd.pack()
topInput = tkinter.Frame(inputStuff)
bottomInput = tkinter.Frame(inputStuff)
topInput.pack()
bottomInput.pack()
def drawCheckboxAndDeleteInputBoxAndPrompt():
nextToCheckbox = entry.get()
entry.delete(0,tkinter.END)
checkboxRow = tkinter.Frame(checkboxArea)
checkboxRow.pack(fill=tkinter.X)
checkbox1 = tkinter.Checkbutton(checkboxRow, text = nextToCheckbox)
checkbox1.pack(side=tkinter.LEFT)
deleteItem = tkinter.Button(checkboxRow, text = "x", bg="red", fg="white", activebackground="white", activeforeground="red")
deleteItem.pack(side=tkinter.RIGHT)
prompt = tkinter.Label(topInput, text="What do you want your checkbox to be for?")
prompt.pack()
entry = tkinter.Entry(bottomInput, bd=3)
entry.pack(side=tkinter.LEFT)
buttonConfirm = tkinter.Button(bottomInput, text="Confirm", command=drawCheckboxAndDeleteInputBoxAndPrompt)
buttonConfirm.pack(side=tkinter.LEFT)
master.mainloop()
I would assign a function to delete checkboxRow, but I think that would delete all of my rows.
I just added command=checkboxRow.destroy when the deleteItem button is created and it works (it only delete the intended item, not all of them).
So drawCheckboxAndDeleteInputBoxAndPrompt becomes
def drawCheckboxAndDeleteInputBoxAndPrompt():
nextToCheckbox = entry.get()
entry.delete(0,tkinter.END)
checkboxRow = tkinter.Frame(checkboxArea)
checkboxRow.pack(fill=tkinter.X)
checkbox1 = tkinter.Checkbutton(checkboxRow, text = nextToCheckbox)
checkbox1.pack(side=tkinter.LEFT)
deleteItem = tkinter.Button(checkboxRow, text = "x", bg="red", fg="white",
activebackground="white", activeforeground="red",
command=checkboxRow.destroy)
deleteItem.pack(side=tkinter.RIGHT)
When I type in entrybox1 it automatically appears in entrybox2. So is like anything that happens entrybox1 happens to entrybox2.
Below is my code
from Tkinter import*
import random
class Love:
def __init__(self):
window = Tk()
window.title("Love Calculator")
window.geometry("300x180")
frame1 = Frame(window)
frame1.pack()
self.lbl = Label(frame1, text = "Love is Pure",fg="white",bg = "blue")
self.lbl2=Label(frame1, text ="are you meant for one another",fg="White",bg = "red")
self.lbl3=Label(frame1,text="Let FIND OUT!!",fg="white",bg = "green")
self.lbl.pack()
self.lbl2.pack()
self.lbl3.pack()
frame2=Frame(window)
frame2.pack()
label = Label(frame2,text = "Your Name")
label2 = Label(frame2, text= "Your Lovers name")
self.msg = StringVar
entry1 = Entry(frame2, textvariable =self.msg)
self.out = StringVar
entry2 = Entry(frame2, textvariable =self.out)
btCalculate=Button(frame2, text="Calculate", command=self.processButton)
label.grid(row=1,column=1)
label2.grid(row=2,column=1)
entry1.grid(row=1,column=2)
entry2.grid(row=2,column=2)
btCalculate.grid(row=4,column=3,sticky=E)
Both of your Entry widgets are effectively using the same textvariable. This is because you are using StringVar wrong. You aren't creating newStringVars, you're merely referencing the class.
In short, you need to do this:
self.msg = StringVar()
... Rather than this:
self.msg = StringVar
Notice the use of ().