Related
I am trying to code a CPS test for fun but I ran into a problem:
I defined a function at the beginning of the code and than I defined a tkinter button which has this function as command and the button should disappear in this function. When I do it like this it says that the variable of the button isn't defined yet but when I defined it vice versa so first the button and then the function it says that the function is not defined yet.
Can anyone help me?
(Sorry for my bad English)
import tkinter as tk
root = tk.Tk()
root.title("CPS test")
root.geometry("1000x1000")
root.configure(bg='white')
def getstring():
duration = entry.get()
entry.delete(0)
entry.place_forget()
okbutton.place_forget
lab1 = tk.Label(text = "How long should the CPS test last? 2,5 or 10 seconds?(Answer with 2,5,10)", font = "Ariel 20", bg = "#FFFFFF")
button = tk.Button(root, text = "Click me!", font = "Ariel 50", bg = "#FFFFFF", fg = "#000000")
entry = tk.Entry(root, font=('Arieal 20'), bd = 2)
okbutton = tk.Button(root, text = "OK", font = "Ariel 20", bg = "#FFFFFF", fg = "#000000", bd = 2, command = getstring())
lab1.place(x = 45,y = 250)
entry.place(x = 344, y = 350)
entry.insert(0, "Enter your answer here!")
okbutton.place(x = 465, y = 400)
root.mainloop()
I think the error is on the button name.
def getstring():
duration = entry.get()
entry.delete(0)
entry.place_forget()
button.place_forget
Just replace "okbutton" by "button" and it should work.
Else just declared the "okbutton" before the function
This question already has answers here:
Why is my Button's command executed immediately when I create the Button, and not when I click it? [duplicate]
(5 answers)
Closed 1 year ago.
The goal of this project is to have a user be able to enter a m and b value into a tkinter window and have a graph show up when a button is pressed. There is multiple windows. There is a click to start button, and a menu to select the type of graph. Currently I am just focusing on getting the linear graph working. When the linear window is reached it prompts the user to enter a m and b value (through entries).
When the graph button is pressed I have coded for it to print the m and b value out. As of right now I cannot get it to print out in the console. If anyone could help up let me know thanks!
Code:
from tkinter import *
root = Tk()
root.geometry("500x500")
class testInputs():
def __init__(self,m,b):
#self.displaygframe = Frame(root)
#self.displayglabe = Label(self.displaygframe,
#text="Test for now",
#font= "ComicSansMS 14")
print(m)
print(b)
class selectGraph(): #2
def __init__(self):
self.gselectframe = Frame(root)
self.gselectlabel = Label(self.gselectframe,
text = "Select Graph Type",
font= "ComicSansMS 14")
self.Var = IntVar()
#define buttons
self.linearButton = Radiobutton(self.gselectframe,
text="Linear",
variable = self.Var,
value=1)
self.quadraticButton = Radiobutton(self.gselectframe,text="Quadratic",
variable = self.Var,
value = 2)
self.confirmButton = Button(self.gselectframe, text = "Continue", command = self.transferAnswer,
fg = "red", font = "ComicSansMS 14",
bd = 2, bg = "light green")
self.sgBack = Button(self.gselectframe, text = "Back", command = self.backButton,
fg = "red", font = "ComicSansMS 5",
bd = 2, bg = "light green")
#pack
self.gselectlabel.pack()
self.linearButton.pack(anchor=W)
self.quadraticButton.pack(anchor=W)
self.confirmButton.pack()
self.gselectframe.pack()
mainloop()
def transferAnswer(self):
answer= self.Var.get()
print(str(answer))
self.gselectframe.destroy()
getEquation(answer)
def backButton(self):
self.gselectframe.destroy()
introWindow()
class getEquation(): #3
def __init__(self, answer):
if answer == 1:
self.linearInput()
if answer == 2:
self.quadraticInput()
else:
selectGraph()
def linearInput(self):
self.linearFrame = Frame(root)
#define widgets
self.linearLabel = Label(self.linearFrame,
text = "Enter Linear Equation",
font= "ComicSansMS 14")
self.linearBack = Button(self.linearFrame, text = "Back", command = self.backButtonLinear,
fg = "red", font = "ComicSansMS 5",
bd = 2, bg = "light green")
formatLabel = Label(self.linearFrame,
text="Format:",
font="ComicSansMS 14")
equationLabel = Label(self.linearFrame,
text="y=mx+b",
font="ComicSansMS 14",
fg="midnight blue")
#name = StringVar()
#name2 = StringVar()
self.mLabel = Label(self.linearFrame,
text= "m=",
font= "ComicSansMS 14")
self.mInput = Entry(self.linearFrame,
width =2, font="ComicSansMS 14")
self.bLabel = Label(self.linearFrame,
text = "b=",
font = "ComicSansMs 14")
self.bInput = Entry(self.linearFrame,
width=2,
font="ComicSansMS 14")
#get info from widget
m = self.mInput.get()
b = self.mInput.get()
self.graphButton = Button(self.linearFrame, text = "Graph", command = self.nextFromLinear(m,b), #error from here
fg = "red", font = "ComicSansMS 14",
bd = 2, bg = "light green")
#place widgets on screen
#self.linearFrame.pack()
self.linearLabel.grid(row=0,column=0)
formatLabel.grid(row=1,column=0)
equationLabel.grid(row=2, column=0)
self.bInput.grid(row=4, column=1)
self.bLabel.grid(row=4, column=0)
self.mInput.grid(row=3, column=1)
self.mLabel.grid(row=3,column= 0)
self.graphButton.grid(row=5, column=1) #error from here
self.linearBack.grid(row=5,column=0)
self.linearFrame.pack()
mainloop()
def quadraticInput(self):
self.quadraticFrame = Frame(root)
self.quadraticLabel = Label(self.quadraticFrame,
text = "Enter Quadratic Equation",
font= "ComicSansMS 14")
self.quadraticLabel.pack()
self.quadraticBack = Button(self.quadraticFrame, text = "Back", command = self.backButtonQuadratic,
fg = "red", font = "ComicSansMS 5",
bd = 2, bg = "light green")
self.quadraticBack.pack(anchor=SW)
self.quadraticFrame.pack()
mainloop()
def backButtonLinear(self):
self.linearFrame.destroy()
selectGraph()
def backButtonQuadratic(self):
self.quadraticFrame.destroy()
selectGraph()
def nextFromLinear(self,m,b):
#self.linearFrame.destroy()
#testInputs(m,b)
print(m)
print(b)
#Figuring out how to write singular back button function for all equation Frames:
#def backButton(self, frame1):
#frame1.destroy()
#selectGraph
class introWindow(): #1
def __init__(self):
self.introframe = Frame(root)
self.introlabel = Label(self.introframe,
text = "Graphing Program",font="ComicSansMS 14")
self.introbutton = Button(self.introframe, text = "Click to start", command = self.windowRemoval,
fg = "red", font = "ComicSansMS 14",
bd = 2, bg = "light green")
self.introlabel.pack()
self.introbutton.pack()
self.introframe.pack()
mainloop()
def windowRemoval(self):
self.introframe.destroy()
selectGraph()
introWindow()
The command argument to Button() must be a function reference, not a call to the function. You're calling the function when you create the button, not when it's clicked.
Use a lambda to create an anonymous function. And it has to call get() when it's called, you can't call it when creating the button, or you'll get the initial values of the inputs, not what the user has entered into them.
self.graphButton = Button(self.linearFrame, text = "Graph",
command = lambda: self.nextFromLinear(self.mInput.get(),self.bInput.get()), #error from here
fg = "red", font = "ComicSansMS 14",
bd = 2, bg = "light green")
I made this program in Tkinter in python where a small window pops up when the code is run and a start button would pop up and make the window full screen and show the content after. I want to make the button destroy itself after I press it so it makes a fullscreen and removes the button. I am still a beginner and would like the answer to be simple. The solution I am looking for is to maybe destroy the button completely(preferred) or move it way out of sight in the fullscreen window. Here is the code:
import Tkinter as w
from Tkinter import *
w = Tk()
w.geometry("150x50+680+350")
def w1():
w.attributes("-fullscreen", True)
l1 = Label(w, text = "Loaded!", height = 6, width = 8).pack()
global b1
b1.place(x = -10000, y = -10000)
b1 = Button(w, text = "Start", height = 3, width = 20, command = w1).place(x = 0, y = 10)
b2 = Button(w, text = "Exit", command = w.destroy).place(x = 1506, y = 0)
w.mainloop()
As you can see I want to make button one destroy itself.
Try this:
import tkinter as tk # Use `import Tkinter as tk` for Python 2
root = tk.Tk()
root.geometry("150x50+680+350")
def function():
global button_start
root.attributes("-fullscreen", True)
label = tk.Label(root, text="Loaded!", height=6, width=8)
label.pack()
button_start.place_forget() # You can also use `button_start.destroy()`
button_start = tk.Button(root, text="Start", height=3, width=20, command=function)
button_start.place(x = 0, y = 10)
button_exit = tk.Button(root, text="Exit", command=root.destroy)
button_exit.place(x=1506, y=0)
root.mainloop()
PS: Please read this.
Try:
b1.place_forget()
This will essentially "forget" about the button and hide it from view.
Edit:
If you are getting the error that b1 is None try:
b1 = Button(w, text = "Start", height = 3, width = 20, command = w1)
b1.place(x = 0, y = 10)
You need to add the b1.place() option at the bottom for this to work
I have created a widget in python using tkinter library. It has one combobox
from tkinter import *
from tkinter.ttk import *
import os
import time
import win32api
def f_step():
window=Tk()
style = Style()
style.configure('W.TButton', font =
('calibri', 12, 'bold'),
foreground = 'blue')
s = Style() # Creating style element
s.configure('Wild.TRadiobutton', # First argument is the name of style. Needs to end with: .TRadiobutton
background='bisque2', # Setting background to our specified color above
font = "calibri 10 bold") # You can define colors like this also
window.title('Tool tool')
window.geometry("700x300+10+10")
#window.geometry(side="top", fill="both", expand = True)
txt_1=StringVar()
lbl_1 = Label(window,text="Are result files same", background ="bisque2",font = "calibri 10 bold").place(x=10,y=40)
lbl_2 = ttk.Combobox(window,textvariable = txt_1, values = ["Yes","No"], background ="bisque2",font = "calibri 10 bold").place(x=275,y=40)
a1 = txt_1.get()
if a1 == "Yes":
txt_2=StringVar()
lbl_3 = Label(window,text="Working directory path", background ="bisque2",font = "calibri 10 bold").place(x=10,y=70)
txt_b = Entry(window,textvariable=txt_2,width=60).place(x=275,y=70)
txt_3=StringVar()
lbl_4 = Label(window,text="file name (without extenstion)", background ="bisque2",font = "calibri 10 bold").place(x=10,y=100)
txt_c = Entry(window,textvariable=txt_2,width=60).place(x=275,y=100)
elif a1 == "No":
txt_2=StringVar()
lbl_3 = Label(window,text="Working directory path", background ="bisque2",font = "calibri 10 bold").place(x=10,y=70)
txt_b = Entry(window,textvariable=txt_2,width=60).place(x=275,y=70)
txt_3=StringVar()
lbl_4 = Label(window,text="file1 name (without extenstion)", background ="bisque2",font = "calibri 10 bold").place(x=10,y=100)
txt_c = Entry(window,textvariable=txt_2,width=60).place(x=275,y=100)
txt_4=StringVar()
lbl_5 = Label(window,text="file2 name (without extenstion)", background ="bisque2",font = "calibri 10 bold").place(x=10,y=130)
txt_d = Entry(window,textvariable=txt_2,width=60).place(x=275,y=130)
btn_1 = Button(window, text="run",style = 'W.TButton',command=clicked)
btn_1.place(x=300,y=250)
window.configure(bg='bisque2')
window.resizable(0, 0)
window.mainloop()
def clicked():
a=1212
f_step()
It has combobox but once i select one option (yes or no) it does not update the following options. Please help me to solve this as i am not sure how to update the application based on real time inputs. i do not want it to updated once i click the button. Also this is just the portion of code which i am having the problem please advise.
You should bind the virtual event <<ComboboxSelected>> to a callback and show the required labels and entries based on the combobox selection in the callback:
def f_step():
window = Tk()
window.title('Tool tool')
window.geometry("700x300+10+10")
#window.geometry(side="top", fill="both", expand = True)
window.configure(bg='bisque2')
window.resizable(0, 0)
s = ttk.Style() # Creating style element
s.configure('W.TButton', font=('calibri', 12, 'bold'), foreground='blue')
s.configure('Wild.TRadiobutton', # First argument is the name of style. Needs to end with: .TRadiobutton
background='bisque2', # Setting background to our specified color above
font="calibri 10 bold") # You can define colors like this also
def on_change(event):
# show the labels and entries
lbl_3.place(x=10, y=70)
txt_b.place(x=275, y=70)
lbl_4.place(x=10, y=100)
txt_c.place(x=275, y=100)
a1 = txt_1.get()
if a1 == "Yes":
lbl_5.place_forget()
txt_d.place_forget()
else:
lbl_5.place(x=10, y=130)
txt_d.place(x=275, y=130)
txt_1 = StringVar()
Label(window, text="Are result files same", background ="bisque2", font="calibri 10 bold").place(x=10,y=40)
cb_1 = ttk.Combobox(window, textvariable=txt_1, values=["Yes","No"], background="bisque2", font="calibri 10 bold", state="readonly")
cb_1.place(x=275,y=40)
cb_1.bind("<<ComboboxSelected>>", on_change)
# define the labels and entries and initially they are hidden
txt_2 = StringVar()
lbl_3 = Label(window, text="Working directory path", background="bisque2", font="calibri 10 bold")
txt_b = Entry(window, textvariable=txt_2, width=60)
txt_3 = StringVar()
lbl_4 = Label(window, text="file1 name (without extenstion)", background="bisque2", font="calibri 10 bold")
txt_c = Entry(window, textvariable=txt_3, width=60)
txt_4 = StringVar()
lbl_5 = Label(window, text="file2 name (without extenstion)", background="bisque2", font="calibri 10 bold")
txt_d = Entry(window, textvariable=txt_4, width=60)
btn_1 = ttk.Button(window, text="run", style='W.TButton', command=clicked)
btn_1.place(x=300, y=250)
window.mainloop()
Note that your code uses txt_2 variable in txt_c and txt_d entries and I think it is typo and fix it.
what you are looking for is lbl_2.bind("<<ComboboxSelected>>", f_step) also note that you must add a parameter in the f_step function as it is passed form combo virtual event. This will make sure to update whenever the option is changed
Try this:
from tkinter import *
from tkinter.ttk import *
import os
import time
import win32api
def f_step(event=None):
a1 = txt_1.get()
if a1 == "Yes":
txt_2=StringVar()
lbl_3 = Label(window,text="Working directory path", background ="bisque2",font = "calibri 10 bold").place(x=10,y=70)
txt_b = Entry(window,textvariable=txt_2,width=60).place(x=275,y=70)
txt_3=StringVar()
lbl_4 = Label(window,text="file name (without extenstion)", background ="bisque2",font = "calibri 10 bold").place(x=10,y=100)
txt_c = Entry(window,textvariable=txt_2,width=60).place(x=275,y=100)
elif a1 == "No":
txt_2=StringVar()
lbl_3 = Label(window,text="Working directory path", background ="bisque2",font = "calibri 10 bold").place(x=10,y=70)
txt_b = Entry(window,textvariable=txt_2,width=60).place(x=275,y=70)
txt_3=StringVar()
lbl_4 = Label(window,text="file1 name (without extenstion)", background ="bisque2",font = "calibri 10 bold").place(x=10,y=100)
txt_c = Entry(window,textvariable=txt_2,width=60).place(x=275,y=100)
txt_4=StringVar()
lbl_5 = Label(window,text="file2 name (without extenstion)", background ="bisque2",font = "calibri 10 bold").place(x=10,y=130)
txt_d = Entry(window,textvariable=txt_2,width=60).place(x=275,y=130)
def clicked():
a=1212
#f_step()
window=Tk()
style = Style()
style.configure('W.TButton', font =
('calibri', 12, 'bold'),
foreground = 'blue')
s = Style() # Creating style element
s.configure('Wild.TRadiobutton', # First argument is the name of style. Needs to end with: .TRadiobutton
background='bisque2', # Setting background to our specified color above
font = "calibri 10 bold") # You can define colors like this also
window.title('Tool tool')
window.geometry("700x300+10+10")
#window.geometry(side="top", fill="both", expand = True)
txt_1=StringVar()
lbl_1 = Label(window,text="Are result files same", background ="bisque2",font = "calibri 10 bold").place(x=10,y=40)
lbl_2 = Combobox(window,textvariable = txt_1, values = ["Yes","No"], background ="bisque2",font = "calibri 10 bold")
lbl_2.place(x=275,y=40)
#lbl_2.current(1)
lbl_2.bind("<<ComboboxSelected>>", f_step)
btn_1 = Button(window, text="run",style = 'W.TButton',command=clicked)
btn_1.place(x=300,y=250)
window.configure(bg='bisque2')
window.resizable(0, 0)
window.mainloop()
also if you want to update only when run is clicked you may call the f_step from clicked() and remove the binding from combobox.
ok as per your request here is the Updated code:
from tkinter import *
from tkinter.ttk import *
import os
import time
import win32api
def f_step(event=None):
global lbl_3
global txt_b
global lbl_4
global lbl_c
global lbl_5
global txt_d
hide()
a1 = txt_1.get()
txt_2=StringVar()
txt_3=StringVar()
lbl_3 = Label(window,text="Working directory path", background ="bisque2",font = "calibri 10 bold")
lbl_3.place(x=10,y=70)
txt_b = Entry(window,textvariable=txt_2,width=60)
txt_b.place(x=275,y=70)
txt_b = Entry(window,textvariable=txt_2,width=60)
txt_b.place(x=275,y=70)
lbl_4 = Label(window,text="file name (without extenstion)", background ="bisque2",font = "calibri 10 bold")
lbl_4.place(x=10,y=100)
txt_c = Entry(window,textvariable=txt_2,width=60)
txt_c.place(x=275,y=100)
if a1 == "No":
lbl_5 = Label(window,text="file2 name (without extenstion)", background ="bisque2",font = "calibri 10 bold")
lbl_5.place(x=10,y=130)
txt_d = Entry(window,textvariable=txt_2,width=60)
txt_d.place(x=275,y=130)
def hide():
#lbl_3.place_forget()
lbl_3.destroy()
txt_b.destroy()
lbl_4.destroy()
txt_c.destroy()
lbl_5.destroy()
txt_d.destroy()
def clicked():
a=1212
f_step()
window=Tk()
style = Style()
style.configure('W.TButton', font =
('calibri', 12, 'bold'),
foreground = 'blue')
s = Style() # Creating style element
s.configure('Wild.TRadiobutton', # First argument is the name of style. Needs to end with: .TRadiobutton
background='bisque2', # Setting background to our specified color above
font = "calibri 10 bold") # You can define colors like this also
window.title('Tool tool')
window.geometry("700x300+10+10")
lbl_3 = Label(window)
txt_b = Entry(window)
txt_b = Entry(window)
lbl_4 = Label(window)
txt_c = Entry(window)
lbl_5 = Label(window)
txt_d = Entry(window)
txt_1=StringVar()
lbl_1 = Label(window,text="Are result files same", background ="bisque2",font = "calibri 10 bold").place(x=10,y=40)
lbl_2 = Combobox(window,textvariable = txt_1, values = ["Yes","No"], background ="bisque2",font = "calibri 10 bold")
lbl_2.place(x=275,y=40)
#lbl_2.current(1)
lbl_2.bind("<<ComboboxSelected>>", f_step)
btn_1 = Button(window, text="run",style = 'W.TButton',command=clicked)
btn_1.place(x=300,y=250)
window.configure(bg='bisque2')
window.resizable(0, 0)
window.mainloop()
you can use the widget.destroy() to delete the widget whole together or widget.place_forget to temporarily hide the widget. Note: if you use widget.place_forget you don't need to recreate the widget instead change the existing widget using widget.config
This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed 9 months ago.
What's the difference between packing a frame "in line" versus ='ing it to a variable and .pack'ing it on the next line?
So I saw how to do grid and pack at the same time (see here), but after playing around with it, I ran into something weird. If you change line 16/17 from:
f5 = Frame(mainF, bg = "yellow", height=100, width = 60)
f5.pack(side=BOTTOM,fill=NONE)
to:
f5 = Frame(mainF, bg = "yellow", height=100, width = 60).pack(side=BOTTOM,fill=NONE)
At the end of the code where the buttons get put into the grid within a pack within a frame within a frame within a dream... My once error-free code now gives the error:
TclError: cannot use geometry manager grid inside .164287488 which already has slaves managed by pack
How? Wha-huh? Why?
My full code here:
from tkinter import Tk, Frame, Label, Entry, LEFT, TOP, YES, NONE, BOTH, RIGHT, BOTTOM,SE, Button,W,E,N,S
root = Tk()
mainF = Frame(root, bg = "green", height=100, width = 1060).pack(side=BOTTOM,fill=NONE)
f4 = Frame(mainF, bg = "blue", width = 300).pack(side=BOTTOM,fill=BOTH)
f = Frame(f4, bg = "orange", width = 500, height = 500).pack(side=LEFT, expand = 1)
f3 = Frame(f, bg = "red", width = 500)
f3.pack(side=LEFT, expand = 1, pady = 10, padx = 50)
f2 = Frame(f4, bg = "black", height=100, width = 100).pack(side=LEFT, fill = BOTH)
f5 = Frame(mainF, bg = "yellow", height=100, width = 60)
f5.pack(side=BOTTOM,fill=NONE)
#f7 = Frame(f5, bg = "green", height=100, width = 160).pack(side=BOTTOM,fill=BOTH)
#f6 = Frame(f7, bg = "green", height=100, width = 360).pack(side=BOTTOM,fill=BOTH)
b = Button(f2, text = "test")
b.pack()
Button(f3, text = "1").grid(row=0, column=0)
Button(f3, text = "2").grid(row=1, column=1)
Button(f3, text = "3").grid(row=2, column=2)
Button(f5, text = "1").grid(row=0, column=0)
Button(f5, text = "2").grid(row=1, column=1)
Button(f5, text = "3").grid(row=2, column=2)
root.mainloop()
I'm using Spyder2 within ipython within anaconda 64 within python 3.4.1 64 within Windows 7 64...
That many dreams within dreams is too unstable!
In the second example:
f5 = Frame(mainF, bg = "yellow", height=100, width = 60).pack(side=BOTTOM,fill=NONE)
f5 is None. This is not the case in the first example:
f5 = Frame(mainF, bg = "yellow", height=100, width = 60)
f5.pack(side=BOTTOM,fill=NONE)
In short terms, the "in line" method is not-recommended. It is one of the most common mistakes and causes of headache for new users of tkinter in python.
The reason for None is very simple: pack() and grid() return None.
In your full code example, mainF, f4, f, f2 are all None. So for exmaple, you think you are passing a reference to mainF frame as master to f4 , but in fact you are passing None.