I'm trying to make a python tkinter application and I'm having a lot of trouble finding a list of what arguments are available for creating a Tk object.
example:
from tkinter import *
root = Tk(<args>)
root.mainloop()
Where can I find a full list of the arguments available?
For example I know I can give the window a title after it is already created by saying root.title("title"), but can I give the window a title in the constructor directly?
I used the documentation, which can be accessed via IDLE, Is this what you looking for?
Related
Consider this very simple code snippet:
import tkinter as tk
class GUI:
def __init__(self):
self.top_level_window = tk.Tk()
GUI()
GUI().top_level_window.mainloop()
It creates two top-level windows on my screen. Why?
I thought the first instance would be immediately garbage collected, so that I would only get one window.
I have also tried slightly modified version, which I was sure for would create two separate objects, and thus only one window:
a=GUI()
b=GUI()
b.top_level_window.mainloop()
but I was wrong. And I can't think of a reason.
Any help?
You are saying
GUI()
GUI().top_level_window.mainloop()
Which is two windows because you called the class twice like Frost Dream said so all you need to do is delete GUI()
import tkinter as tk
class GUI:
def __init__(self):
self.top_level_window = tk.Tk()
GUI().top_level_window.mainloop()
I think that with tkinter, the framework itself keeps hold of instances of GUI objects that you create. This defeats any garbage collection that you might assume is going to happen.
You would need to call .destroy() on any elements you want tkinter to forget.
I thought the first instance would be immediately garbage collected
The python object that is the instance of GUI is garbage-collected. However, tkinter creates objects inside of an embedded tcl interpreter, and the tcl interpreter doesn't know anything about python objects. So, while the object is removed from python, the widgets still exist inside the tcl interpreter.
Put another way, garbage collect of a python object doesn't guarantee that the underlying tcl object is deleted. If you want the first window to be destroyed, you must call destroy() on the instance.
Because you called the class two times.
GUI()
GUI().top_level_window.mainloop()
>>>
GUI().top_level_window.mainloop()
I have a main program which does some cool stuff and I am currently setting up a 'settings editor' to let the user change some GUI related stuff and default values. It reads values from a text file, which is read in correctly and saves them to a dictionary self.propertiesDict. Some of the options are on/off switches, so I use checkbuttons for them. What is puzzling me is following behavior: the code works perfectly fine, when I execute the settingsEditor.py (the script creating the settings window) directly. All the checkbuttons are set to active / True. However, when I include my settingsEditor in my main program and call it, it creates fine but all the checkbuttons show the wrong value: False. I read a lot of topics here to find an answer, but I think I avoided the most common errors:
I use the tk variables
tk variables are created and set prior to the buttons
variables are not only in local scope (prefixed self.)
As you can see, I tried with an IntVar and a BooleanVar, but neither is working correctly. Something else is strange, when I use ttk.checkbuttons, I get the issue described here. I use Visual Studio for debugging and I can't see any difference in the process when going trough line by line, except for the wrong display result. I am happy for any suggestion. Sorry for not providing a full MWE, I will do, if nobody can help me from this here.
settingsEditor.py
import tkinter as tk
from tkinter import ttk
...
class mySettingsEditor:
def __init__(self):
...
def createGUI(self):
# Show main options on startup on/off
self.showOptionsVar = tk.IntVar()
self.showOptionsVar.set(str2int(self.propertiesDict['showMainOptionsExpanded']))
print(self.showOptionsVar.get())
self.checkBtn1 = tk.Checkbutton(Frame, text='Main Options Section', variable=self.showOptionsVar)
self.checkBtn1.grid(column=0,row=2)
# Show main STL section on startup on/off
self.showMainSTLVar = tk.BooleanVar()
self.showMainSTLVar.set(str2bool(self.propertiesDict['showMainSTLSectionExpanded']))
print(self.showMainSTLVar.get())
self.checkBtn2 = tk.Checkbutton(Frame, text='Main STL Section', variable=self.showMainSTLVar)
self.checkBtn2.grid(column=0,row=3)
main.py
from settingsEditor import mySettingsEditor
...
settEditor = mySettingsEditor()
This is how it looks in the GUI when executed separately (terminal with print output to the left):
Thats the result when I add it in main.py. The boxes are unchecked, but .get() tells me the values are correctly assigned to the tk variables.
As suggested by jasonharper, switching to Toplevel() for the child windows fixed the issue. Thanks alot!
With other toolkits there's usually a way to set _NET_WM_WINDOW_TYPE_DIALOG so that my tiling window manager (i3) renders it properly without needing an explicit rule for the window. It seems like I should be able to do this with either Tk.attributes() or Tk.wm_attributes(), but every keyword argument I've tried (type and toolwindow) are unrecognized.
Took a much closer look at the doc.
import Tkinter as tk
root = tk.Tk()
root.attributes('-type', 'dialog')
a = tk.Frame(master=root)
root.title(__file__)
a.mainloop()
I'm new to programming and I'm attempting to create an application using tkinter from python 3.3. In this application I'm using buttons containing images and I want to perform actions that depend on the kind of image that the buttons are containing. This is a simplified version of my program:
from tkinter import *
master=Tk()
c_black = PhotoImage(file="c_black.gif")
b=Button(master, image=c_black)
print(b.cget('image'))
master.mainloop()
Instead of
c_black
the console returns
pyimage1
And I have no idea why. I've been trying to figure it out for hours now. Perhaps there's a way to do it differently?
With cget() you can only retrieve the property as a string, so you need to store the reference to the PhotoImage object:
b = Button(...)
b.image = c_black
print(b.image.cget('file'))
I've been following a tutorial for the tkinter interface in python and it uses the following piece of code to declare a root widget for the program which then has children widgets:
root = Tk()
I'm getting the following error when trying to interpret this piece of code:
Global name Tk() is not defined
I'm fairly sure this is because tkinter has changed since the tutorial; I cannot find any other tutorials that do not use snippets of code like this so they wouldn't work either.
The question I have is in context simple, but searching, I cannot find the answer;
How can I bypass this: what has changed to the syntax of tkinter and what is the new method of sorts to declare a root widget? additionally it would be brilliant if anybody has the knowledge of tkinter to warn me whether the way in which you can add children widgets to the root has changed as well.
Thank you for any and all replies ~ Michael
You probably forgot from Tkinter import * at the top.
Alternatively, there's
import Tkinter
or
import Tkinter as tk
Edit: Generally, you want to use the idiom from <library> import <module>, so for your specific example from Tkinter import Tk would work.
which just allows you type tk.Button, for example, rather than Tkinter.Button throughout your code. And if you're using Python 3.x, the library is lowercase.
import tkinter
For general importing questions, I've seen the Importing Python Modules link referenced a lot on SO.
You seem to have named the file tkinter.py. You cannot name a file with the module you are importing. Python will try to import from your existing file instead of tkinter module. There will be module name collison. Try to rename your file name.
from Tkinter import *
root = Tk()