How to hide a button by using a class function in python - python

from tkinter import*
root = Tk()
shape = Canvas(root)
class GUI():
def __init__(self):
pass
def create_button(self, info, boom, posit):
self.Button(root)
self.config(text=info)
self.bind("<Button-1>",boom)
self.grid(column=posit[0],row=posit[1])
def create_label(self, info, posit):
self.Label(root)
self.config(text=info)
self.grid(column=posit[0],row=posit[1])
def go_away(self):
print("GO AWAY before")
self.button.grid_forget()
print("GO AWAY")
def make_GUI():
root.title("Hexahexaflexagon")
hexahexa = GUI()
quit_butt = GUI()
quit_butt.create_button("Exit","root.destroy()",[0,1])
quit_butt.go_away()
make_GUI()
root.mainloop()
Okay so I am trying to write a class function to just hide (and if not that then delete) a button created by tkinter, I'm new to classes and the error message I keep getting is that the GUI class does not have that function or that object does not have that attribute, I've tried code such as frm.forget(), .lower(), .grid_forget() but there not working for me.
The traceback is:
Traceback (most recent call last):
File "N:\HW\Hexahexaflexagon generator.py", line 94, in <module>
make_GUI()
File "N:\HW\Hexahexaflexagon generator.py", line 63, in make_GUI
quit_butt.go_away()
File "N:\HW\Hexahexaflexagon generator.py", line 51, in go_away
self.button.grid_forget()
AttributeError: 'function' object has no attribute 'grid_forget'

The problem is this line:
self = Button(root)
You are redefining self from referring to the current object, to now refer to a different object. You have the same problem further down with a label. This is simply not how python works.
You must store the widgets as attributes on self, not as self itself.
self.button = Button(root)
...
self.label = Label(root)
Once you do that, you can hide the button or label with grid_forget since you're using grid to make it visible:
self.button.grid_forget()
You have another problem in that you're passing in a command as a string. This will not work the way you think it does. If you want to be able to pass in a function, it needs to be a reference to an actual function:
quit_butt.button("Exit",root.destroy,[0,1])

Related

Python Tkinter: What syntax in main() will get the return value of a method bound to button in a class instance?

New to tkinter, I want a short program to:
create a window to take user input, by means of an entry widget and a submit button
capture the input and return it to main, so that I can do something else with it.
The following code creates the window and captures input, but breaks at the next-to-last line.
from tkinter import *
from tkinter import ttk
class TxtEntryWindow:
def __init__(self):
self.root = Tk()
self.frame = ttk.Frame(self.root).pack()
self.box = ttk.Entry(self.frame)
self.box.pack()
self.but = ttk.Button(self.frame, text='Submit', command=self.capture_txt)
self.but.pack()
self.root.mainloop()
def capture_txt(self):
txt = self.box.get()
return txt
win = TxtEntryWindow()
user_input = win.capture_txt()
print(user_input)
Here's a copy of the error message:
Traceback (most recent call last):
File "C:...\wclass.py", line 22, in
user_input = win.capture_txt()
File "C:...\wclass.py", line 17, in capture_txt
txt = self.box.get()
File "C:...\Python\Python310\lib\tkinter_init_.py", line 3072, in get
return self.tk.call(self._w, 'get')
_tkinter.TclError: invalid command name ".!entry"
I have no idea what this means. I suspect that dependence of "txt" on the button event in the class prevents "win.capture_txt()" in main() at the bottom from fetching the user input.
Can anyone shed light?
Consulted Python's official documentation (unintelligible), Tkinter's official tutorial and command reference. Searched numerous analogies on StackOverflow and on youtube. Googled the error message itself. I've tried to strike out on my own and rewrite the critical command about twenty times. Blind intuition leads nowhere. Stabbing in the dark.
The error means that the entry widget (self.box) has been destroyed when the line user_input = win.capture_txt() is executed.
You can use an instance variable to store the input text instead and access this instance variable after the window is destroyed:
from tkinter import *
from tkinter import ttk
class TxtEntryWindow:
def __init__(self):
self.text = "" # initialize the instance variable
self.root = Tk()
self.frame = ttk.Frame(self.root).pack()
self.box = ttk.Entry(self.frame)
self.box.pack()
self.but = ttk.Button(self.frame, text='Submit', command=self.capture_txt)
self.but.pack()
self.root.mainloop()
def capture_txt(self):
# save the user input into the instance variable
self.text = self.box.get()
self.root.destroy()
win = TxtEntryWindow()
print(win.text) # show the content of the instance variable

Getting value of tkinter Entry on button click from a different function [duplicate]

This question already has answers here:
Tkinter: AttributeError: NoneType object has no attribute <attribute name>
(4 answers)
Closed 3 years ago.
I'm trying to get a value from an Entry box which is my input, and I want whatever is written in it to be available for processing on button press. Here is the code I have:
from tkinter import *
import tkinter as tk
class GUI(Tk):
def __init__(self):
super(GUI, self).__init__()
tk.Label(self, text="Input").grid(row=0)
self.input = tk.Entry(self).grid(row=0, column=1)
tk.Button(self, text="Start", command=self.start_button).grid(row=5, column=1)
def start_button(self):
print(self.input.get())
gui = GUI()
gui.mainloop()
Whenever I try to press the button, it says None type has no attribute "get". Here is the traceback:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Program Files (x86)\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "D:/Projects/excel_reader/test.py", line 15, in start_button
print(self.input.get())
AttributeError: 'NoneType' object has no attribute 'get'
I have tried removing the TK as subclass for my GUI class, removing the super() call and tried declaring all the variables globally but that did not work either. I am very new to Python GUI.
The problem turns out to be the way I was defining the grids for it. I don't know why but this works now by changing this-> input = tk.Entry(root).grid(row=0, column=1)
to this:
global input
input = tk.Entry(self)
input.grid(row=0, column=1)

How to call this tkinter gui function?

How do i access windows function in Mygui class?
I want to create colored content in my tkinter box#
but i can't pass value to it.
from tkinter import *
class Mygui:
def window(self, colour):
self.main_window=Tk()
self.main_window.geometry('300x100')
self.main_window.title('Login')
self.top_frame=Frame(self.main_window)
self.top_frame.pack()
self.label=Label(self.top_frame, fg=colour, text="Sample Text", width=45)
self.label.pack(side="top")
self.label1=Label(self.top_frame,text=" ", width=45)
self.label1.pack(side="top")
self.my_button = Button(self.main_window, text="Retry", command=self.do_something, height=2, width=18)
self.my_button.pack()
mainloop()
def do_something(self):
print('ok')
class login:
def example(self):
print("Start")
Mygui.window('blue')
a = login.example(' ')
The error i get is:
Start
Traceback (most recent call last):
File "B:/data/loginMech/test.py", line 25, in <module>
a = login.example(' ')
File "B:/data/loginMech/test.py", line 23, in example
Mygui.window('blue')
TypeError: window() missing 1 required positional argument: 'colour'
Mygui is a class, not a function. So, you have to construct an instance of it, like this:
gui = Mygui()
And then you can call methods on that instance:
gui.window('blue')
When you write Mygui.window, that's an unbound method, which you can call by explicitly passing it a self argument along with its other arguments. But you'd still need to have something to pass as that self:
gui = Mygui()
Mygui.window(gui, 'blue')
In general, you don't want to do this. There are cases where unbound methods are useful, but if you have one, you probably know you have one.
And you need to do the same thing with login:
log = login()
log.example()
By calling login.example, you're using an unbound method again. And then you're passing ' ' as the self argument. This doesn't make any sense, because ' ' is not a login instance, but CPython 3.x happens to not check for that error, so you get away with it.
Abarnet pointed out one fix however in Tkinter it might be better to inherit from the Tkinter class Tk to start you GUI.
Take this example. A much smaller amount of code and produces the same results desired.
import tkinter as tk
class MyGUI(tk.Tk):
def __init__(self, colour):
tk.Tk.__init__(self)
self.geometry('300x100')
self.title('Login')
tk.Label(self, fg=colour, text="Sample Text", width=45, pady=10).grid(row=0, column=0)
tk.Button(self, text="Retry", command=self.do_something, height=2, width=18).grid(row=1, column=0)
def do_something(self):
print('ok')
MyGUI("Blue").mainloop()
Results:

Why am I getting this class tkinter.Entry.get() AttributeError error?

I'm sorry for my bad English.
I get an error when I try to get() the Entry named entry from outside the class.
Error:
AttributeError: 'function' object has no attribute 'entry' ""
Example Code:
class asd:
def gui(self, guiwindow, labelplacex, labelplacey, textx, texty, entryx, entryy):
self.root = tk
self.image = tk.PhotoImage(file=aimage_path)
self.label = tk.Label(image=self.image)
self.label.pack()
self.label.place(x=labelplacex , y=labelplacey)
self.text = Label(guiawindow, text="Code:")
self.text.pack()
self.text.place(x = textx,y = texty)
self.entry = Entry(guiwindow)
self.entry.pack()
self.entry.place(x = entryx,y = entryy)
self.button = Button(Tk(), text="Back Menu", command=self.asdfg)
self.button.pack()
self.root.mainloop()
asd.gui.entry.get()
How to do this??
You have two problems. First, you need to create an instance of asd, and second, you need to call the gui method.
For example, something like this:
asd_instance = asd()
asd_instance.gui(...)
asd_instance.entry.get()
Not: ... represents all the parameters that you need to pass to gui, which are irrelevant to the problem. The point being, you must first create an instance of the class before you can get an attribute of the instance. In this case the attribute you want won't exist until you call the gui method. Thus, you must first create an instance, then call the gui method, and only then can you access the attribute.
Try asd.entry.get() instead.
Assuming self.entry has already been defined, you should be able to access it by calling the class itself and then the variable, since the word 'self' means the class itself.
gui in this case is just a function and self.entry belongs to the class asd, not the function gui.

Tkinter name "X" is not defined error.

I am trying to take a more object oriented approach by using classes, but I seem to be getting the following error.
Traceback (most recent call last): File "./Main.py", line 17, in
Main = Menu(root) File "./Main.py", line 11, in init
self.F1.pack(fill=X) NameError: global name 'X' is not defined
Here is the code I am trying to compile, I have broken it down to a simple snippet to show the error I am getting:
#!/usr/bin/python
import Tkinter as tk # Python 2 import
class Menu:
def __init__(self, parent):
self.root = parent
self.root.geometry("800x400")
self.root.title("Image Compression")
self.F1 = tk.Frame(self.root, bg="black")
self.F1.pack(fill=X)
if __name__ == "__main__":
root = tk.Tk()
Main = Menu(root)
root.mainloop()
Your
self.F1.pack(fill=X)
should be
self.F1.pack(fill=tk.X)
and you should also add expand=True to make the fill actually work.
Tkinter.X and Tkinter.Y and Tkinter.BOTH are constants (strings) that are defined in the Tkinter module. Without the Tkinter., you are trying to access X as a variable.
Your line should read
self.F1.pack(fill=tk.X, expand=True)
to do what you want it to do.
Oh, one more afterthought... You may be thinking, "Hey! I've seen .pack(fill=X) working before!" This is true when there is a
from Tkinter import *
statement above the reference. Then, in that instance, X would be found as coming from Tkinter but without needing the leading Tkinter.. That's the topic of namespace, which is beyond the scope of this answer.

Categories

Resources