-
-
Notifications
You must be signed in to change notification settings - Fork 31.8k
Tkinter ttk widgets cget() returning _tkinter.Tcl_Obj instead of str #126008
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hello, @maj113 The result of my test is no problem, my environment is as follows:
The code I tested is as follows: import tkinter
root = tkinter.Tk()
radio_button = tkinter.Radiobutton(root)
state = radio_button.cget("state")
is_normal = state == tkinter.NORMAL
print(f"{is_normal=}, {type(state)=}") The output is as follows: is_normal=True, type(state)=<class 'str'> Obviously, it's not a |
I'm testing this on Windows 11 24H2 with the same behavior on (C)python 3.12.5 and 3.13.0 |
Ok, I'll try to create a PR later to fix this. I don't think this should be solved just by modifying the docstring, |
I've encountered the same issue yesterday by accessing the state using the key directly. Took me way to long to figure out that the state isn't string type. self.entry_box = ttk.Entry(self.root, width=40)
# This doesn't work!
if (self.entry_box['state'] == 'normal'):
print('State is normal') The weird thing is, if you access the state before hand by printing it as a string, then it becomes a string type. import tkinter as tk
from tkinter import ttk, messagebox
class App:
def __init__(self, root):
self.root = root
self.entry_box = ttk.Entry(self.root, width=40)
self.entry_box.pack(padx=10, pady=10)
messagebox.showinfo(message=f"Type: {type(self.entry_box['state'])}\nState: {self.entry_box['state']}\nType after access: {type(self.entry_box['state'])}")
if __name__ == "__main__":
root = tk.Tk()
app = App(root)
root.mainloop() Result: Type: <class '_tkinter.Tcl_Obj'>
State: normal
Type after access: <class 'str'> |
Hello, @brianzhouzc I tested your code and it turned out to be different from yours: Result: Type: <class '_tkinter.Tcl_Obj'>
State: normal
Type after access: <class '_tkinter.Tcl_Obj'> Perhaps you should point out your environment. |
@serhiy-storchaka We need a decision on what to do before too much effort is put into PRs. |
The docstring is outdated. Perhaps it was written when all low-level Tkinter API returned only strings. "as string" should be removed. |
Apologies, my environment is Windows 10 Business 22H2 19045.5011, Python 3.11.9. Tried on Python 3.12.6 as well and the behaviours is indeed different, like what you have in your reply. |
I don't think just removing that would be enough to clarify the return value, it still might confuse people that the same key behaves differently comparing tk vs ttk, I haven't checked how tkinter.Tcl_Obj is implemented but maybe it can be extended with a eq so that at least string comparisons work as expected without the need to wrap it in a str |
This is a Tk implementation detail. Depending on the key, the Tk version, the way of creating and modifying the widget, you can get a number, a boolean, a string, a tuple, a Tcl_Obj. If you get a Tcl_Obj and need a string, just call str(). Making Tcl_Obj comparable with str is an interesting idea, but this is a new feature which can only be added in a new Python version. It may require significant internal changes in Tkinter. |
Is it possible that the "as string" in the comment refers to the KEY, not the return value? This can really be misleading. But beyond that, it's also a problem that widgets of tk don't behave consistently with widgets of ttk. |
What I understood wrongly: the key is a string, the return value is a string as well because everything is stored as a string. But this was wrong! (I think?) The key is a string, the return value is anything. Am I correct now? |
I think so. |
I added tests to the PR, can anyone help review that?
Also, as mentioned above, this should be more than just a docs issue. |
…thods * Explain the behavior of Widget.configure() depending on arguments. * Unify descriptions. * Replace "resource" with "option".
To me, it looks like saying that KEY is a string. This is redundant and may be confusing, so it is is better to remove it. There are also other issues with docstrings of |
The docstring:
"""Return the resource value for a KEY given as string."""
claims it returns as a string however it returns a_tkinter.Tcl_Obj
which seems to lack
__eq__
/the ability to compare it to a string so something like this:Will always return false no matter what unless its wrapped in a str()
I propose either clarifying the docstr or returning as a str() wrapped obj but i presume that's a breaking change
Linked PRs
ttk.Widget.cget
#126102The text was updated successfully, but these errors were encountered: