I like to mixed my radio button selection with a few user input boxes.
I managed to output them separately but I can't combine them due to the one using canvas1.pack and another using row.pack.
This is my first radio button interface where user will select Auto or Manual and there is a box for user to input stock symbols manually.
This interface by default will show the default parameters such as volume or dividend amount and the user can change this parameter.
When I tried to put them together, they overlaps. The stock symbol input box was also shifted down. How can I move the parameter boxes below the auto and manual radio button without shifting the stock symbol box to the bottom?
Below is a sample of my code that is ready to be executed on jupyter.
from tkinter import *
from tkinter import simpledialog
from tkinter import messagebox
import tkinter as tk
#default filter values
parameter1 = 100000
parameter2 = 3
global answer
global user_list
# Prepare parameters
fields = ['Min. parameter1', 'Min. parameter2', 'Min. 3parameter3',
'Min. parameter4','Min. parameter5', 'Max. parameter6']
default_values = [parameter1,parameter2,parameter3,parameter4,
parameter5,parameter6]
captured_values = []
def on_closing():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
root.destroy()
sys.stdout = orig_stdout
f.close()
sys.exit("Application closed by user")
def makeform(root, fields,default_values):
entries = {}
for i in range(len(fields)):
row = tk.Frame(root)
lab = tk.Label(row, width=24, text=fields[i]+": ", anchor='w')
ent = tk.Entry(row)
ent.insert(0, default_values[i])
row.pack(side=tk.TOP,
fill=tk.X,
padx=5,
pady=5)
lab.pack(side=tk.LEFT)
ent.pack(side=tk.RIGHT,
expand=tk.YES,
fill=tk.X)
entries[fields[i]] = ent
return entries
# Button click event
def btn_click (e):
global answer
answer_choice = rdo_var.get()
answer = rdo_txt[answer_choice]
global user_list
user_list = entry1.get()
captured_values.append(e['Min. parameter1'].get())
captured_values.append(e['Min. parameter2'].get())
captured_values.append(e['Min. parameter3'].get())
captured_values.append(e['Min. parameter4'].get())
captured_values.append(e['Min. parameter5'].get())
captured_values.append(e['Max. parameter6'].get())
root.destroy()
return answer
# Generate Tk class
root = tk.Tk()
# Screen size
root.geometry ('270x250')
# Screen title
root.title ('Enter parameters')
# set default parameters
ents = makeform(root, fields, default_values)
# box for manual input
canvas1 = tk.Canvas(root, width = 350, height = 400)
canvas1.pack()
entry1 = tk.Entry (root)
canvas1.create_window(165, 45, window=entry1)
# List radio button labels
rdo_txt = ['Auto','Manual']
# Radio button status
rdo_var = tk.IntVar ()
# Create and place radio buttons dynamically
for i in range (len (rdo_txt)):
rdo = Radiobutton (root, value = i, variable = rdo_var, text = rdo_txt [i])
rdo.place (x = 20, y = 15 + (i * 20))
# Create button
confirm_button = tk.Button (root, text = 'Confirm', command = (lambda e=ents: btn_click(e)))
confirm_button.place (x = 180, y = 200)
root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop ()
if(answer == 'Manual'):
print('Manual run selected.')
manual_run = 1
temp_user_list = []
user_list = user_list.split(',')
for i in range(len(user_list)):
temp_user_list.append(user_list[i].strip().upper())
print('Symbol(s) entered : ' + str(temp_user_list))
else:
manual_run = 0
print('Auto run selected.')
# new captured values
parameter1 = float(captured_values[0])
parameter2 = float(captured_values[1])
Here is an expanded answer.
Complete code example.
from tkinter import *
from tkinter import simpledialog
from tkinter import messagebox
import tkinter as tk
#default filter values
parameter1 = 100000
parameter2 = 2
parameter3 = 3
parameter4 = 4
parameter5 = 5
parameter6 = 6
global answer
global user_list
# Prepare parameters
fields = ['Min. parameter1', 'Min. parameter2', 'Min. parameter3',
'Min. parameter4','Min. parameter5', 'Max. parameter6']
default_values = [parameter1,parameter2,parameter3,parameter4,
parameter5,parameter6]
captured_values = []
def on_closing():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
root.destroy()
sys.stdout = orig_stdout
f.close()
sys.exit("Application closed by user")
def makeform(root, fields,default_values):
entries = {}
for i in range(len(fields)):
row = tk.Frame(root)
lab = tk.Label(row, width=28, text=fields[i]+": ", anchor='e')
ent = tk.Entry(row)
ent.insert(0, default_values[i])
row.pack(side=tk.TOP,
fill=tk.X,
padx=5,
pady=5)
lab.pack(side=tk.LEFT)
ent.pack(side=tk.RIGHT,
expand=tk.YES,
fill=tk.X)
entries[fields[i]] = ent
return entries
# Button click event
def btn_click (e):
global answer
answer_choice = rdo_var.get()
answer = rdo_txt[answer_choice]
global user_list
user_list = entry1.get()
captured_values.append(e['Min. parameter1'].get())
captured_values.append(e['Min. parameter2'].get())
captured_values.append(e['Min. parameter3'].get())
captured_values.append(e['Min. parameter4'].get())
captured_values.append(e['Min. parameter5'].get())
captured_values.append(e['Max. parameter6'].get())
root.destroy()
return answer
# Generate Tk class
root = tk.Tk()
# Screen size
root.geometry("410x260")
# Screen title
root.title('Enter parameters')
# set default parameters
ents = makeform(root, fields, default_values)
# box for manual input
manual = makeform(root, ['Manual input'], ["Enter value here"])
entry1 = manual["Manual input"]
entry1["background"] = "yellow" # make it standout
del manual
# List radio button labels
rdo_txt = ['Auto','Manual']
# Radio button status
rdo_var = tk.IntVar()
# Create and place radio buttons dynamically
for i in range (len (rdo_txt)):
rdo = Radiobutton (root, value = i, variable = rdo_var, text = rdo_txt [i])
rdo.place (x = 20, y = 15 + (i * 20))
# Create button
confirm_button = tk.Button (root, text = 'Confirm', command = (lambda e=ents: btn_click(e)))
confirm_button.place (x = 205, y = 220)
root.protocol("WM_DELETE_WINDOW", on_closing)
root.mainloop()
if(answer == 'Manual'):
print('Manual run selected.')
manual_run = 1
temp_user_list = []
user_list = user_list.split(',')
for i in range(len(user_list)):
temp_user_list.append(user_list[i].strip().upper())
print('Symbol(s) entered : ' + str(temp_user_list))
else:
manual_run = 0
print('Auto run selected.')
# new captured values
parameter1 = float(captured_values[0])
parameter2 = float(captured_values[1])
Related
im trying to name a button what it is named in ent and so it doesn't repeat when the button is pressed again so if you press once it's button1 and again button2
from tkinter import *
def ext():
win1.destroy()
but1 = Button(root, text=txt.get(), height=10, width=30)
but1.grid(padx=3, row=0, column=1)
def create():
global win1
global txt
win1 = Tk()
win1.geometry("200x200")
ent = Entry(win1)
ent.pack(pady=20)
txt = ent.get()
sub = Button(win1, text="Submit", command=ext)
sub.pack()
root = Tk()
root.geometry("750x750")
root.config(background="#6673ED")
create_but = Button(root, text="Create new card", height=10, width=30, command=create)
create_but.grid(row=0,column=0)
root.mainloop()
The code below uses a dictionary of lists to add an integer to any repeating text input. I think this is what the question is about.
import tkinter as tk # import as tk is safer and more flexible
# Globals to keep it simple
names = {} # Dictionary. Will become a dictionary of lists.
row = 1
col = 0
win1 = None
ent = None
def add_text( txt ):
""" Adds txt to the names dictionary if it doesn't already exist.
Adds and integer to the txt if it does already exit """
name = names.get( txt, None )
if name:
name.append( txt + str(len( name )) ) # Append `txt + int` to a list
else:
names[ txt ] = [ txt ] # Add a list of one item to the dict.
# print( names ) # Uncomment to see what is happening.
return names[ txt ][-1]
def ext():
global row, col
txt = ent.get() # Get the text from the entry
win1.destroy() # before the window is destroyed
txt = add_text( txt )
but1 = tk.Button(root, text=txt, height=10, width=30)
but1.grid(padx=3, row=row, column=col) # row and column need to
# change to show all buttons.
col += 1
if col > 2:
row += 1
col = 0
def create():
global win1
global ent
win1 = tk.Toplevel() # Create a second window with tk.Toplevel.
# Never create two tk.Tk objects.
win1.geometry("200x200")
ent = tk.Entry(win1)
ent.pack(pady=20)
ent.focus() # Position the focus in the Entry
# txt = ent.get() # removed as the Entry was being read before data was entered.
# The entry is now read in `ext`.
sub = tk.Button( win1, text="Submit", command=ext )
sub.pack()
root = tk.Tk()
root.geometry("750x750")
root.config(background="#6673ED")
create_but = tk.Button(root, text="Create new card", height=10, width=30, command=create)
create_but.grid(row=0,column=0)
root.mainloop()
I'm trying to create a feedback form using Tkinter in Python. For now I am writing for it to show a message box if the name entry is '' when clicked on the submit button. But the button cannot be clicked and is disabled. How can I fix this?
# import all functions from the tkinter
from tkinter import *
from tkinter import messagebox
# import messagebox class from tkinter
from tkinter import messagebox
# Create a GUI window
root = Tk()
# create a function to check input
def check_input():
if name_input == '':
messagebox.showerror("please enter your name")
# create the input entry
name_input = Entry(root)
age_input = Entry(root)
phone_input = Entry(root)
email_input = Entry(root)
# label the input entry
name_label = Label(text="Username")
age_label = Label(text="Age")
phone_label = Label(text="Phone")
email_label = Label(text="Email")
# display the input entry
name_label.grid(row = 1,column = 1, padx = 10)
name_input.grid(row = 2,column = 1,padx = 10)
age_label.grid(row = 3,column = 1,padx = 10)
age_input.grid(row = 4,column = 1,padx = 10)
phone_label.grid(row = 5,column = 1,padx = 10)
phone_input.grid(row = 6,column = 1,padx = 10)
email_label.grid(row = 7,column = 1,padx = 10)
email_input.grid(row = 8,column = 1,padx = 10)
# create the submit button
submit_button = Button(root,text="Submit",command = check_input)
# display the submit button
submit_button.grid(row = 9,column = 1,padx = 10)
# Start the GUI
root.mainloop()
You have to use the get() method to get contents from an Entry:
# create a function to check input
def check_input():
if name_input.get() == '':
messagebox.showerror("please enter your name")
[![tested and shows no error][1]][1]
your button is clickable and is visible ... there maybe some other issue with your requirements but button works
[1]: https://i.stack.imgur.com/JQqH3.png
if you want to get value from the textbox your need to set text variable for entry
like
ttk.Entry(win,textvariable=hexanum).grid(column=1,row=0)
then if you need to get values from text box you'll be doing something like
inhexa=(hexanum.get()) #hexanum is the textvariable associated to entry/textbox
#inhexa is a variable in which the value from get function is stored (if need to store)
do your homework :) feel free to ask
I'm wondering if I got my if else statement wrong or if its a tkinter issue. I want it so that if a 0 is left in any or all boxes, it gives an error message. But after the error message is closed, it opens a random blank window. This is my code. The specific area is the if else statement within the function valueget()
import tkinter as tk
def mainwindow():
mainwindow = tk.Tk()
mainwindow.title('Enter values')
mainwindow.geometry('160x110')
mainwindow.config(bg='#aaf0d1')
tk.Label(mainwindow, text = 'Enter a', font = ('verdana'), bg='#aaf0d1').grid(row=0)
tk.Label(mainwindow, text = 'Enter b', font = ('verdana'), bg='#aaf0d1').grid(row=1)
tk.Label(mainwindow, text = 'Enter c', font = ('verdana'), bg='#aaf0d1').grid(row=2)
getA = tk.IntVar()
aBox = tk.Entry(mainwindow, textvariable = getA, width=3, bg='#aaf0d1')
aBox.grid(row=0, column=1)
aBox.config(highlightbackground='#aaf0d1')
getB = tk.IntVar()
bBox = tk.Entry(mainwindow, textvariable = getB, width=3, bg='#aaf0d1')
bBox.grid(row=1, column=1)
bBox.config(highlightbackground='#aaf0d1')
getC = tk.IntVar()
cBox = tk.Entry(mainwindow, textvariable = getC, width=3, bg='#aaf0d1')
cBox.grid(row=2, column=1)
cBox.config(highlightbackground='#aaf0d1')
button = tk.Button(mainwindow, text='Obtain roots', command = lambda: valueget(), font = ('verdana'), highlightbackground='#aaf0d1')
button.grid(row=4)
button.config(bg='#aaf0d1')
def valueget():
readA = getA.get()
readB = getB.get()
readC = getC.get()
intA = int(readA)
intB = int(readB)
intC = int(readC)
negroot = (readB**2)-(4*readA*readC)
quadformulaplus = (-readB + (pow(negroot,0.5)))/(2*readA) #quad forumla
quadformulaminus = (-readB - (pow(negroot,0.5)))/(2*readA) #quad forumla
messagewindow = tk.Tk()
messagewindow.geometry('290x50')
messagewindow.title('Roots of the equation')
messagewindow.config(bg='#aaf0d1')
if readA == 0 or readB==0 or readC==0 or (readA==0 and readB==0 and readC==0):
errorwindow = tk.messagebox.showerror(message='none').pack()
else:
label = tk.Label(messagewindow, text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}', bg='#aaf0d1', font = ('verdana'))
label.grid(row=1)
closebutton = tk.Button(messagewindow, text='Close', command = lambda: messagewindow.destroy(), font = ('verdana'), highlightbackground='#aaf0d1')
closebutton.grid(row=2)
closebutton.config(bg='#aaf0d1')
messagewindow.mainloop()
# print(f'the roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}')
mainwindow.mainloop()
def startup():
startpage = tk.Tk()
startpage.title('Solver')
photo = tk.PhotoImage(file = r"/Users/isa/Desktop/DiffEqns/cover.png") #image load
coverbutton = tk.Button(startpage, image = photo, command = lambda: [startpage.destroy(), mainwindow()])
coverbutton.pack()
coverbutton.configure(highlightbackground='#aaf0d1')
startpage.mainloop()
startup()
Here's a basic idea of what I would do:
import tkinter as tk
from tkinter import messagebox
def mainwindow(root):
# Creates a toplevel window
mainwindow = tk.Toplevel()
mainwindow.protocol("WM_DELETE_WINDOW", root.destroy) # This overrides the "X" being clicked to also destroy the root window.
root.withdraw() # "Hides" the root window, leaving it (and mainloop) running in the background.
mainwindow.title('Enter values')
mainwindow.geometry('160x110')
mainwindow.config(bg='#aaf0d1')
# Since all three of the labels/entries are the same
# we can save space by generating them in a loop
entry_items = ('Enter a', 'Enter b', 'Enter c')
values = []
for x, item in enumerate(entry_items): # Using enumerate and x to assign rows
tk.Label(mainwindow, text = item,
font = ('verdana'), bg='#aaf0d1').grid(row=x) # Row assigned to x.
values.append(tk.StringVar()) # Appended StringVar to list.
tk.Entry(mainwindow,
textvariable = values[-1], # Uses the last value appended to the values list.
highlightbackground='#aaf0d1',
width=3,
bg='#aaf0d1').grid(row=x, column=1) # Row assigned to x.
tk.Button(mainwindow,
text='Obtain roots',
command = lambda vals = values: valueget(vals), # Here the button command is assigned with the values list
font = ('verdana'), bg='#aaf0d1',
highlightbackground='#aaf0d1').grid(row=3) # we know there are 3 items before this.
mainwindow.lift() # This is a method of bringing a window to the front
def valueget(vals):
# This line gets the values from the StringVars, converts them to ints,
# and returns them to their respective variables.
try:
readA, readB, readC = [int(val.get()) for val in vals]
except ValueError:
messagebox.showerror(title="Number Error", message='Values must be numbers')
return
# Here the variables are checked to see if they are 0
# Since each one is being checked if it is 0, there is no need to check if they are all 0.
for val in (readA, readB, readC):
if val == 0:
# If they are 0, shows an error message
messagebox.showerror(title="Zero Error", message='Values must not be zero')
return
# Creates a toplevel to display the results
messagewindow = tk.Toplevel()
messagewindow.title('Roots of the equation')
messagewindow.config(bg='#aaf0d1')
negroot = (readB**2)-(4*readA*readC)
quadformulaplus = (-readB + (pow(negroot,0.5)))/(2*readA) #quad forumla
quadformulaminus = (-readB - (pow(negroot,0.5)))/(2*readA) #quad forumla
tk.Label(messagewindow,
text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}',
bg='#aaf0d1',
font = ('verdana')).pack(padx = 5, pady = 2)
tk.Button(messagewindow,
text='Close',
command = messagewindow.destroy, # There is no need for a lambda for this.
font = ('verdana'),
bg = '#aaf0d1',
highlightbackground='#aaf0d1').pack(padx = 5, pady = 2)
# print(f'the roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}')
messagewindow.lift() # This is a method of bringing a window to the front
def startup():
startpage = tk.Tk()
startpage.title('Solver')
# COMMENTED OUT FOR TESTING
#photo = tk.PhotoImage(file = r"/Users/isa/Desktop/DiffEqns/cover.png") #image load
coverbutton = tk.Button(startpage,
# COMMENTED OUT FOR TESTING
#image = photo,
text = "TESTING", # HERE FOR TESTING
highlightbackground='#aaf0d1',
command = lambda root = startpage: mainwindow(root)).pack() # Passes the startpage to the mainwindow function.
startpage.mainloop() # The only mainloop you need.
startup()
I would recommend to improve the readability of the if-else statement for a start.
coefficients = [readA, readB, readC]
if sum(coefficients): # If they all are all zeros this will be False
if min(coefficients): # If any one is zero, this will be False
label = tk.Label(messagewindow, text = f'The roots are {quadformulaplus:.1f} and {quadformulaminus:.1f}', bg='#aaf0d1', font = ('verdana'))
label.grid(row=1)
closebutton = tk.Button(messagewindow, text='Close', command = lambda: messagewindow.destroy(), font = ('verdana'), highlightbackground='#aaf0d1')
closebutton.grid(row=2)
closebutton.config(bg='#aaf0d1')
else:
errorwindow = tk.messagebox.showerror(message='none').pack()
else:
errorwindow = tk.messagebox.showerror(message='none').pack()
iam trying to make a phonebook using python and tkinter . I need to add new numbers to my phonebook
by adding elements to the dictionary but i can't access the numbers again after the programme is closed .
from tkinter import*
#defining the submit button
def submit():
global my_dict
new = entry2.get()
new2 = entry3.get()
my_dict.update({new:new2})
#definig the add button
def add():
top = Toplevel(root)
top.configure(background="black")
top.geometry("400x400")
top.title("Add new member")
label6 =Label(top,text="Welcome",bg="black",fg="orange")
label6.place(x=135,y=13)
global entry2
entry2 = Entry(top,width=23)
entry2.place(x=102,y=78)
label7 = Label(top,text="Name",bg="black",fg="orange")
label7.place(x=48,y=78)
global entry3
entry3 = Entry(top,width = 23)
entry3.place(x=108,y=127)
label8 = Label(top,text="phone number",bg ="black",fg="orange")
label8.place(x=0,y=129)
button3 = Button(top,text="Submit",command = submit)
button3.place(x=185,y=200)
button5 = Button(top,text = "close",command = top.quit)
button5.place(x=185,y=300)
#defining the chek button
def check():
person = entry.get()
if person in my_dict:
phone = my_dict.get(person)
print("Found: " + person + " : " + phone)
# Erase the old result by placing a blank label
label0 = Label(root, width=200, bg ="black", fg = "black").place(x=10,y=167)
label5 = Label(root, text = person + " : " + phone, bg ="black", fg = "orange").place(x=10,y=167)
#creating the main window
root = Tk()
global my_dict
my_dict = {"john":'7598769587'}
root.title("vole phone book")
root.geometry("400x400")
root.configure(background="black")
label = Label(root,text="phone book",bg="black",fg="orange",width=13).place(x=133,y=23)
label2 = Label(root,text="Enter here.",bg = "black",fg="orange").place(x=2,y=89)
entry = Entry(root,width = 27)
entry.place(x=89,y=90)
button =Button(root,text="Check",bg="yellow",fg="red",command=check).place(x=190,y=129)
button2=Button(root,text="Add",width=23,command = add).place(x=120,y=300)
root.mainloop()
this is my code,what to do?
Variables in Python are not saved to disk, they only exist in memory (RAM) unless you explicitly save it there yourself.
You can either save to a file directly or, use a database instead.
See Here for using Pickle to do what you want.
I haven't figured out how to set the focus on a specific tab of a ttk.Notebook. focus_set does not work. Is there any possibility?
Thanks in advance
I was having the same problem. What I found is the 'select' method for notebooks (ttk.Notebook.select(someTabFrame)) solves this problem:
import ttk, Tkinter
mainWindow = Tkinter.Tk()
mainFrame = Tkinter.Frame(mainWindow, name = 'main-frame')
mainFrame.pack(fill = Tkinter.BOTH) # fill both sides of the parent
nb = ttk.Notebook(mainFrame, name = 'nb')
nb.pack(fill = Tkinter.BOTH, padx=2, pady=3) # fill "master" but pad sides
tab1Frame = Tkinter.Frame(nb, name = 'tab1')
Tkinter.Label(tab1Frame, text = 'this is tab 1').pack(side = Tkinter.LEFT)
nb.add(tab1Frame, text = 'tab 1')
tab2Frame = Tkinter.Frame(nb, name = 'tab2')
Tkinter.Label(tab2Frame, text = 'this is tab 2').pack(side = Tkinter.LEFT)
nb.add(tab2Frame, text = 'tab 2')
nb.select(tab2Frame) # <-- here's what you're looking for
mainWindow.mainloop()
python docs for ttk.Notebook:
https://docs.python.org/2/library/ttk.html#ttk.Notebook
I also used this blog post as a model for my code:
http://poquitopicante.blogspot.com/2013/06/blog-post.html
This code based on wordsforthewise's answer to this question. Here you can find example of using select as get and set function, it shown by button that switch between 2 tabs.
small improvement:
import ttk, Tkinter
from pango import Weight
from Tkinter import Button
tab2Frame = None
tab1Frame = None
def switchTab():
if nb.select()[-1] == "1":
nb.select(tab2Frame)
elif nb.select()[-1] == "2":
nb.select(tab1Frame)
mainWindow = Tkinter.Tk()
mainWindow.geometry("%dx%d+0+0" % (200, 200))
mainFrame = Tkinter.Frame(mainWindow, name = 'main-frame')
mainFrame.pack(fill = Tkinter.BOTH) # fill both sides of the parent
button = Button(mainWindow, text = "Switch", command = switchTab)
button.configure(width = 15, activebackground = "#6f6Fff")
button.pack()
nb = ttk.Notebook(mainFrame, name = 'nb')
nb.pack(fill = Tkinter.BOTH, padx=2, pady=3) # fill "master" but pad sides
tab1Frame = Tkinter.Frame(nb, name = 'tab1')
Tkinter.Label(tab1Frame, text = 'this is tab 1').pack(side = Tkinter.LEFT)
nb.add(tab1Frame, text = 'tab 1')
tab2Frame = Tkinter.Frame(nb, name = 'tab2')
Tkinter.Label(tab2Frame, text = 'this is tab 2').pack(side = Tkinter.LEFT)
nb.add(tab2Frame, text = 'tab 2')
mainWindow.mainloop()