Every source of documentation I've been able to find for this say that by calling itemconfig without any arguments will return a list of possible attributes that can be edited. I tried to do this with the following code:
import tkinter
from tkinter import *
master = Tk()
w = Canvas(master, width=200, height=100)
w.pack()
print(w.itemconfig('bg'))
...And it only returned an empty dictionary (it throws an error when I put in zero arguments, and no other arguments I could think of have given me results, except for actually using the function as intented)
I find it rather silly that nobody has written down all of the attributes that itemconfig can use (or if they have, I can't find it); being able to actually retrieve attributes would be nice, but far more than that, I'd like a complete list to be written down, since I can't find it anywhere.
Related
I had started writing a tkinter program when I stumbled across this problem in my code:
elif (xtimes=="" or xtimes=="Optional") and (t!="" or t!="Optional"):
amount
years=0
while years<t:
principle=principle+((interest/100)*(principle))
years+=1
amount=principle
finallabel=Label(root,text="Your Final Amount will be",amount,"at the end of",years,"years")
finallabel.grid(row=13,column=0)
Under the elif statement, I have calculated amount and I want to show the answer using a label, which gives the error: "positional argument follows keyword argument"
I think that I want to send the variable amount through the text, like in normal python, but the code makes it think like I am passing some parameter called amount which doesn't exist.
Please help.
the only positional argument you need to pass is Label(root).
So if you do Label(text='my text', root) it gives this error.
this works:
import tkinter as tk
root = tk.Tk()
lab = tk.Label(root, text='hi')
lab.pack()
root.mainloop()
this not:
import tkinter as tk
root = tk.Tk()
lab = tk.Label(text='hi',root)
lab.pack()
root.mainloop()
After update.. Let's look on this line of your code here:
finallabel=Label(root,text="Your Final Amount will be",amount,"at the end of",years,"years")
What you did here, was to parse arguments through the interface of the Label class to make an instance of it, with the config of given arguments.
the tkinter Label class knows the arguments that can be found here.
So comparing your Label with the available parameters, you will notice that amount and years arent part of them. The only Posistional argument that the Label class of tkinter is expecting is the master, followed by keyword arguments **options. Read this.
What you trying to do is a string with variables and there are several ways to achieve this. My personal favorite is the f'string.
And with a f'string your code will be look like this:
finallabel=Label(root,text=f'Your Final Amount will be {amount},at the end of {years} years')
Let me know if something isnt clear.
I am building a simple GUI using TkInter, and I'd like to have Python tell me all available options that I can configure Cursors to, e.g.: button.config(Cursor="cross").
I know I could just find a list on a tutorial or documentation somewhere, but my thinking is that I'd be better off knowing how to get Python to tell me itself... Give a man a fish etc.
I've done some research and tried to use dir(), getattr() and vars() as well as keys(). I'm guessing that at least one of those will get me what I want, but I'm confused by the sheer amount of stuff they spit out.
for example:
import tkinter as tk
b = tk.Button()
print('Using dir: ', dir(b))
print('Using getattr: ', getattr(b, 'config'))
print('Using vars: ', vars(b))
print('Using keys: ', b.keys())
Ideally, I'd like it to spit out an iterable that I can use to test/trial each available definition. I don't know whether this is possible, but since python/TkInter knows what I mean when I pass something like b.config(cursor='cross'), it's got to be listed somewhere, right?
As I said, the functions I tried spit out a bunch of methods and attributes I could give values, but not what values are available.
*edit: Here's the code I'd like to feed with the available Options, for this specific example.
import math
import tkinter as tk
w = tk.Tk()
def listify(event):
c = 0
all_options = entry.get()
entry.destroy()
list_options = all_options.split(" ")
print(len(list_options))
for value in list_options:
lbl = tk.Label(text=value, cursor=value, bd=2, relief=tk.RAISED)
rounded = int(math.floor(c / 20))
r = c - 20 * rounded
lbl.grid(column=rounded, row=r, pady=5,
padx=5, rowspan=1, sticky=tk.NSEW)
c += 1
entry = tk.Entry()
entry.grid()
entry.bind('<Return>', listify)
w.mainloop()
Every widget has a configure method which will return all of the configuration options for a widget.
When you call configure you get back a dictionary. The keys are the option names, the value is a tuple. The tuple will either have two values or five values.
Two values
If the dictionary element has two values, it represents an alias to another option. The values are as follows:
the name of the option (eg: "bd" for borderwidth)
the tcl/tk option that it is aliased to (e.g. "-borderwidth")
For example, for widgets with a borderwidth attribute, the result of configure() will have a key "bd" with the value ('bd', '-borderwidth').
Five values
If the dictionary element has five values, it is a normal option. The values are as follows:
The name of the option (e.g. "borderwidth")
The option database1 name (e.g. "borderWidth")
The option database class name (e.g. "BorderWidth")
The default value of the option
The currently configured value of the option
Printing all options and their values
You can iterate over this dictionary to print out the values by examing all values that have five elements. For example:
config = button.configure()
for option in sorted(config.keys()):
if len(config[option]) == 5:
print("{} = {}".format(option, config[option][5]))
1The option database is something that is mostly used on X11-based systems (i.e. not windows, not OSX). For an example of how to use the option database see Changing the Default Font via the Option Database on effbot.
For a comprehensive overview of the option database see Options and Tk - a Beginners Guide. It is written from the perspective of a tcl programmer, but the concepts are applicable to tkinter.
After seeing this, PhotoImage not showing up the image associated with it I wondered why omitting the type of option does not throws an error instead of just not showing up the image?
This code does not show the image without throwing any error
import tkinter as tk
root = tk.Tk()
image1 = tk.PhotoImage("ban.gif")
tk.Label(root,image=image1).pack()
tk.Label(root, text="some string here").pack()
root.mainloop()
But this one works fine
import tkinter as tk
root = tk.Tk()
image1 = tk.PhotoImage(file="ban.gif")
tk.Label(root,image=image1).pack()
tk.Label(root, text="some string here").pack()
root.mainloop()
On effbot it doesn't say anything about it so I checked tcl man page for creating photos but still can not find why it behaves like this.
Also, if those two are duplicate ones, let me know so I will delete/close vote this one.
When you specify a function with named arguments in python, those named arguments appear in a specific order. If you do not supply a name when defining these arguments, they are applied in the order that the arguments appear in the function definition.
In the case of PhotoImage, the first keyword argument is for the name of the image, not a path to a file. So, PhotoImage("ban.gif") is the same as doing PhotoImage(name="ban.gif"). It doesn't throw an error because "ban.gif" is a valid name, and there are use cases where you want to create an image without referencing a file.
I've tryied to build a Tkinter form in some universal method, but I got a problem.
First look at my Method's code..
def BuildWindow(title, args, icon):
Window = Tk()
Window.title(title)
Window.wm_iconbitmap(icon)
for item in args:
item.master = Window
item.pack()
Window.mainloop()
When I'm trying to run this code, I'm getting two differnet Windows: one with the arguments from the list "args", and the other with the title and the icon only..
I want all the parameters to appear in the same Form..
can someone help me to solve it?
Thanks..
Based on the code presented, I must assume that args contains a list of widgets that have already been created. If they've already been created, an instance of Tk must already exist. Since this function is also creating in instance of Tk, that's why you get two windows.
You must create only a single instance of Tk for your entire application.
I'm using Python 2.7, if that matters.
Here is a code I wrote for fun:
def p():
root = Tk()
def cmd(event):
print int(slider.get())
slider = Scale(root, orient = "horizontal", from_ = 0, to = 100, command = cmd, state = "disabled")
def enable():
slider.config(state = "active")
b = Button(root, text = "Enable slider", command = enable)
b.grid()
slider.grid(row = 1)
root.mainloop()
For this code, I'm wondering why the command for Scale requires an event, but that for Button does not. It seems that for some widgets in Tkinter their commands need to have "event" as an argument, and other don't. Why? How to distinguish them?
Thanks.
Scale doesn't take an event. It takes the current value. Try this:
def cmd(value):
print int(value)
If you read the Tk tutorial, it explains this:
There is a "command" configuration option, which lets you specify a script to call whenever the scale is changed. Tk will automatically append the current value of the scale as a parameter each time it invokes this script (we saw a similar thing with extra parameters being added to scrollbar callbacks and those on the widgets they scroll).
Or, if you read the actual manpage:
Specifies the prefix of a Tcl command to invoke whenever the scale's value is changed via a widget command. The actual command consists of this option followed by a space and a real number indicating the new value of the scale.
In other words, the way to distinguish them is to read the docs. Unfortunately, the Tkinter docs aren't all that complete—they assume you already know how Tcl/Tk works, or how to look it up yourself. That's why the docs start off with a list of links to sources of Tk documentation.
If you prefer to figure it out by trial and error, it's not that hard to see what gets passed:
def cmd(*args):
print('Scale command says {}'.format(args))
def enable(*args):
print('Button command says {}'.format(args))
But this won't always tell you everything you need to know; there are other callbacks whose arguments aren't obvious enough to figure out without a lot more work, or which are configurable (e.g., the validate callback).
When you set up a binding (with the bind) command, the callback always is given an event object.
When you are working with the command attribute of a widget, different widgets send different information to the command. In this case they never send an event, but they will send other types of data. This is simply due to the fact different commands do different things.
The scale widget is no different -- you claim the callback takes an event, but that is false. It is passed the current value of the scale widget rather than an event object.