I create a check button / box, with the following call
x=ttk.Checkbutton(tab1,state='disabled',command = lambda j=i,x=k: fCheckButton(j,x))
x.state(['selected'])
The box appears fine and is selected, but it appears on load up, with a black box in it, which seems to have nothing to do with the state of it.
I have looked for reasons why, but can't actually find anyone with the same problem.
thanks
I hit this problem when creating a Checkbutton object from within a class. I was declaring a local variable instead of a member variable in the class. The local variable was getting out of scope causing the checkbox value to not be either a 0 or a 1.
Wrong:
import tkinter as Tk
from tkinter import IntVar
from tkinter.ttk import Frame, Checkbutton
class TestGui(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
var1 = IntVar()
var1.set(1)
button = Checkbutton(parent,
text="Pick me, pick me!",
variable=var1)
button.grid()
root = Tk.Tk()
app = TestGui(root)
root.mainloop()
Fixed:
import tkinter as Tk
from tkinter import IntVar
from tkinter.ttk import Frame, Checkbutton
class TestGui(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.var1 = IntVar()
self.var1.set(1)
button = Checkbutton(parent,
text="Pick me, pick me!",
variable=self.var1) # note difference here
button.grid()
root = Tk.Tk()
app = TestGui(root)
root.mainloop()
I've had a similar issue on Windows 7.
After loading the app, one of my checkbuttons contained a filled square. But after clicking on it, it became a normal checkbutton:
In my case, it was because I had multiple checkbuttons sharing the same variable... After creating a separate Tk.IntVar() variable for each checkbutton, the problem disappeared.
import Tkinter as Tk
import ttk
root = Tk.Tk()
checkVar = Tk.IntVar()
x = ttk.Checkbutton(root, variable=checkVar, text="check 1")
x.pack()
checkVar2 = Tk.IntVar()
y = ttk.Checkbutton(root, variable=checkVar2, text="check 2")
y.pack()
root.mainloop()
Related
I want to create Buttons with a text and define a function that prints me the text on the monitor when i press the button.
Everything works well without classes:
from tkinter import *
from tkinter import ttk
def PressButton():
print(FirstButton.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=ttk.Button(ButtonsFrame, text=1, command= PressButton)
FirstButton.grid()
root.mainloop()
"1" is printed on the monitor when I press FirstButton.
Because I want to have a lot of Buttons, I created a class MyButton with the parent ttk.Button:
from tkinter import *
from tkinter import ttk
class MyButton(ttk.Button):
def __init__(self, text):
self.text=text
super().__init__()
self.Button=ttk.Button(ButtonsFrame, text=self.text, command=self.PressButton)
def PressButton(self):
print(self.Button.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=MyButton(1)
FirstButton.grid()
root.mainloop()
Here a button is created but without text at all.
I found out that if I change the super().__init__() to super()._init__(text=self.text) then I get a Button with the right text but the PressButton command doesnt work. I tried diffent things with *args aswell but had no success.
What am I doing wrong? I would appreciate any help.
The main problem is that you're not specifying the parent widget for the parent in the constructor.
Here's corrected version of code:
from tkinter import *
from tkinter import ttk
class MyButton(ttk.Button):
def __init__(self, parent, text):
self.text=text
super().__init__(parent, text=self.text, command=self.PressButton)
def PressButton(self):
print(self.cget('text'))
root = Tk()
root.title("Simple Calculator")
ButtonsFrame = ttk.Frame(root,relief= "groove").grid()
FirstButton=MyButton(ButtonsFrame, 1)
FirstButton.grid()
root.mainloop()
You could've also swapped super(). with this:
super(MyButton,self).__init__(parent, text=self.text,command=self.PressButton)
Which is equal to super().__init__(parent, text=self.text, command=self.PressButton)
You can read more about it here:
https://docs.python.org/3/library/functions.html#super
I have a searchbox that is an Entry in tkinter and I want to have an X-button in the right corner that the user can click on and it will delete everything that was typed in the box. But I cannot fin a solution on how to put a Label or Button inside Entry. Any suggestions?
Thanks in advance
this is an oop solution, init function creates widgets and the clear function deletes the text inside the entry. You can arrange the position of the widgets with pack(), grid() would also work.
here is a similar question: How to clear the Entry widget after a button is pressed in Tkinter?
import tkinter as tk
from tkinter import ttk
class App(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.entryText = ttk.Entry(self)
self.entryText.pack()
self.XButton = ttk.Button(self, text="X-Button", command=self.clear_text).pack()
def clear_text(self):
self.entryText.delete(0, 'end')
if __name__ == "__main__":
root = tk.Tk()
root.geometry('200x100')
App(root).pack()
root.mainloop()
I wonder if someone could tell me if its possible to update toplevel windows using external functions. I've replicated my issue below what I need to do is update the Toplevel(master) using the function updatelabel(). I have used similar external function to update items in root which works like a dream. However, with the top level window I always get the
NameError: name 'newWindow' is not defined
The only work around I found was to kill the newWindow using newWindow.destroy() on each load but this method makes the screen pop up and then close again which doesn't look pretty. Any help most welcome thanks.
from tkinter import *
from tkinter.ttk import *
master = Tk()
master.geometry("200x200")
def updatelabel():
Label(newWindow,
text="I changed").pack()
def openNewWindow():
# Toplevel object which will
# be treated as a new window
newWindow = Toplevel(master)
# sets the title of the
# Toplevel widget
newWindow.title("New Window")
# sets the geometry of toplevel
newWindow.geometry("200x200")
# A Label widget to show in toplevel
Label(newWindow,
text="I want to change").pack()
button1 = Button(newWindow,
text="Click me to change label", command=updatelabel).pack()
btn = Button(master,
text="open a new window",
command=openNewWindow)
btn.pack(pady=10)
mainloop()
Your “newWindow” is defined in your “openNewWindow” function and so it basically only exists in there, you could probably fix this by either defining “newWindow” outside of the function, or by using it as an argument(just add it to the brackets and give it a name in the function itself’s brackets) calling “updateLabel”
I think this should work, though I haven’t worked with tkinter in a bit so don’t blame me if it doesn’t
from tkinter import *
from tkinter.ttk import *
master = Tk()
master.geometry("200x200")
def updatelabel(newWindow):
Label(newWindow,
text="I changed").pack()
def openNewWindow():
# Toplevel object which will
# be treated as a new window
newWindow = Toplevel(master)
# sets the title of the
# Toplevel widget
newWindow.title("New Window")
# sets the geometry of toplevel
newWindow.geometry("200x200")
# A Label widget to show in toplevel
Label(newWindow,
text="I want to change").pack()
button1 = Button(newWindow,
text="Click me to change label", command= lambda: updatelabel(newWindow)).pack()
btn = Button(master,
text="open a new window",
command=openNewWindow)
btn.pack(pady=10)
mainloop()
I'm trying to make a simple outline for a gui, and I'm getting the warning
"variable" May be undefined or defined from star imports: tkinter for all of my variables.
Here is my code:
from tkinter import *
class myApp :
def __init__(self, gui,) :
self.root = gui
self.bframe = Frame(self.root) # Create a container Frame at bottom
self.bframe.pack(side=BOTTOM)
self.xlabel = Label(self.root, text="Item ID") # Create the Label
self.xlabel.pack(side=LEFT)
self.xentry = Entry(self.root, bd=5) # Create the Entry box
self.xentry.pack(side=LEFT)
self.xentry.bind('<Return>', self.showStockItem)
self.xentry.focus_set() # Set focus in the Entry box
self.xopen = Button(self.root, text="Show", command=self.showStockItem) # Create the open Button
self.xopen.pack(side=LEFT)
self.xquit = Button(self.bframe, text="Quit", command=self.quitit) # Create the quit Button
self.xquit.pack(side=BOTTOM)
return
gui = Tk()
gui.title("Travel")
app = myApp(gui)
gui.mainloop()
from tkinter import *
In this line, you import everything from tkinter. This is not recommended, so linter will warn you. But if you really want to do this, it's OK, just ignore it.
To be better, you should explicitly import what you need. For example:
from tkinter import Tk, Label, Frame, Entry, Button
Consider using:
import tkinter as tk
and then, prefix all your calls like:
root = tk.Tk()
or,
variableName.pack(side = tk.LEFT)
and so on...
Ok, I made it work by changing all the references to the stringvar "commentEntryVar" to "self.commentEntryVar" inside the def initUI function.
I'm not exactly sure why this is necessary (or if making all the references self.commentEntryVar was necessary). Would be pleased if someone can explain why this solved the issue.
self.commentEntryVar = tk.StringVar()
self.commentEntryVar.set("default text")
print "commentEntryVar"
print self.commentEntryVar.get()
commentEntryWidget = ttk.Entry(workoutParametersFrame, textvariable=self.commentEntryVar)
commentEntryWidget.grid(row=6, column=1)
=========================================
(THE ORIGINAL QUESTION)
Trying to use the "textvariable" method to set default text for a ttk entry widget. It seems like I'm correctly setting the value of the tk.StringVar, but it is not affecting the window display -- the 'set comment' field remains blank.
commentEntryVar = tk.StringVar()
commentEntryVar.set("default text")
print "commentEntryVar"
print commentEntryVar.get()
commentEntryWidget = ttk.Entry(workoutParametersFrame, textvariable=commentEntryVar)
commentEntryWidget.grid(row=6, column=1)
If I understand your code, you are doing everything correctly syntactically. If the value is appearing blank on the screen, the only explanation is that commentEntryVar is a local variable that is being garbage-collected after the widget is created but before the window appears.
If it is a local variable, when the function exits the variable will be destroyed and thus the default value will be thrown away. For example, this minimal program illustrates the effect you're seeing since it is using a local variable:
import Tkinter as tk
import ttk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
workoutParametersFrame = tk.Frame(self)
workoutParametersFrame.pack(fill="both", expand=True);
# start code from the question
commentEntryVar = tk.StringVar()
commentEntryVar.set("default text")
print "commentEntryVar"
print commentEntryVar.get()
commentEntryWidget = ttk.Entry(workoutParametersFrame,
textvariable=commentEntryVar)
commentEntryWidget.grid(row=6, column=1)
# end code from the question
if __name__ == "__main__":
root = tk.Tk()
app = Example(root)
app.pack(fill="both", expand=True)
app.mainloop()
The fix is to keep a reference to the StringVar so that it is not garbage collected. In this code we're using a class so we can store a reference in a class variable. If you are not using classes and objects you'll need to store it in a global variable.
For example, if you change commentEntryVar to self.commentEntryVar, the problem goes away because the object holds a persistent reference:
...
self.commentEntryVar = tk.StringVar()
...
commentEntryWidget = ttk.Entry(..., textvariable=self.commentEntryVar)
...
Make sure you keep the reference of the StringVar object.
For example, try following example with / without del commentEntryWidget statement.
try:
import Tkinter as tk
import ttk
except ImportError:
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
commentEntryVar = tk.StringVar()
commentEntryVar.set("default text")
commentEntryWidget = ttk.Entry(root, textvariable=commentEntryVar)
commentEntryWidget.grid(row=6, column=1)
# del commentEntryWidget
root.mainloop()