Tkinter code not showing button (v:3.6) - python

This is my practice from youtube, It's not showing button in window
import tkinter as tk
class Window(Frame):
def _init_ (self, master =None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title('GUI')
self.pack(fill = BOTH, expand = 1)
quitButton = Button(self, text = "Quit")
quitButton.place(x=0, y =.1)
root = tk.Tk()
root.title('GUI')
root.geometry()
app = Window(master=root)
root.mainloop()

Just change your _init_ to __init__.
Python constructor syntax has double underscore.
UNDERSTANDING SELF AND __INIT__ METHOD IN PYTHON CLASS.
__init__ is a reseved method in python classes. It is known as a constructor in object oriented concepts. This method called when an object is created from the class and it allow the class to initialize the attributes of a class.

Related

How do I to call a custom object with custom style methods and use it as a style for a label(and widgets in general) in tkinter?

So I am trying to import my own custom style methods into my main app to then use as a custom style in ttk.Label(), by calling the class method, but I'm having trouble finding a way to call it. Below is the example code of the main app.
import tkinter as tk
from tkinter import ttk
from custom_styles import customStyle
class MainApp:
def __init__(self, master):
self.master = master
**initialization code****
#----style methods-----#
self.styled = customStyle(self.master)
#title label
self.title_label = ttk.Label(self.master, text="test", style=self.styled.test())
self.title_label.pack()
And below is the class I am calling the methods above from, which is different file.
from tkinter import ttk
import tkinter as tk
class customStyle:
def __init__(self, master) -> None:
self.master = master
def test(self):
style = ttk.Style()
style.configure("test.TLabel",
foreground="white",
background="black",
padding=[10, 10, 10, 10])
I've tried to call just the name of the style method like this
self.title_label = ttk.Label(self.master, text="test", style='test.TLabel')
I've also tried to call the method by calling the class then method like this
self.title_label = ttk.Label(self.master, text="test", style=self.styled.test())
I knew this wouldn't work, but I still tried it
self.title_label = ttk.Label(self.master, text="test", style=self.styled.test('test.TLabel'))
I also tried not making an object out of the methods, so I took away the class and just made a list of functions, but that didn't work either. Of course, I looked on the internet and searched stack for questions, but to no avail. Maybe this structure I am trying to maintain is not efficient?
I'm honestly just looking to understand a way to call the methods w/o putting them in the same file, but I just don't know how to.
The style option requires the name of a style as a string. Since your function test returns None, it's the same as if you did ttk.Label(..., style=None)
One solution is to have your test function return the style name:
def test(self):
...
return "test.TLabel"
Of course, that means you can only use it for that one specific style. Another solution is that you leave it as-is and return nothing. In that case you can just hard-code the style. You must ensure that you call the test function, however, so that the style is initialized.
self.styled.test()
self.title_label = ttk.Label(self.master, text="test", style="test.TLabel")
Arguably, a better option would be to add attributes to the class, and initialize the styles when you instantiate the class. It might look something like this:
class customStyle:
def __init__(self, master) -> None:
self.master = master
style = ttk.Style()
style.configure("test.TLabel",...)
...
self.label = "test.TLabel"
self.button = "test.TButton"
self.scrollbar = "test.TScrollbar"
...
class MainApp:
def __init__(self, master):
self.master = master
self.styled = customStyle(self.master)
self.title_label = ttk.Label(..., style=self.styled.label)
...
There are probably even better ways to do this. The point is, you need to pass a valid style name as a string to the style parameter of a ttk widget.

Having trouble with Tkinter using OOP

I have created a small application in tkinter before using just top down programming but I am starting another project, this time using OOP and classes. But I'm having a hard time getting started, I just need someone to point me in the right direction. I've already dabbled in OOP with PyGame but I'm having difficulty with tkinter. Heres my code, where i'm just trying to display a button to the screen:
import tkinter as tk
from tkinter import ttk as ttk
import sqlite3
class Button(tk.Frame):
def __init__(self):
tk.Frame.__init__(self)
tk.Button(root, text = "Hello", width = 25)
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
self.button = Button()
self.button.pack(side="bottom",fill="x")
if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack(side="top", fill="both", expand=True)
root.mainloop()
Try this:
import tkinter as tk
from tkinter import ttk # The `as tkk` isn't needed
# Here you might want to consider inheriting from `tk.Button` but it isn't going to change anything
class Button(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
# It's always a good idea to keep a reference to all of your widgets
self.button = tk.Button(self, text="Hello", width=25)
# You should call `.pack`/`.grid`/`.place` here:
# Note it doesn't really matter which one you choose
self.button.pack(fill="both")
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent # Technically this isn't needed because the line above sets `self.master` to parent
self.button = Button(self) # Pass in self into the Button class
self.button.pack(side="bottom", fill="x")
if __name__ == "__main__":
root = tk.Tk()
main_app = MainApplication(root)
main_app.pack(side="top", fill="both", expand=True)
root.mainloop()
I passed in self when creating the Button object in self.button = Button() and I called self.button.pack(...) inside the Button class.
The whole point of OOP programming it to limit global variables and group similar objects in a single class definition. That is why both your Button and MainApplication classes shouldn't rely on root. Apart from that, your code is very nice :D

tkinter python function takes 1 argument, given 2

I'm getting this error when I try to run my code:
File "./countdown.py", line 36, in <module>
app = Application(root)
File "./countdown.py", line 16, in __init__
self.create_buttons(self)
TypeError: create_buttons() takes exactly 1 argument (2 given)
Here's my code:
import Tkinter as tk
class Application(tk.Frame):
"""Countdown app - simple timer"""
def __init__(self, master):
"""initialize frame"""
tk.Frame.__init__(self, master)
#super(Application, self).__init__(master)
self.grid()
self.create_buttons(self)
def create_buttons(self):
self.startBttn = Button(app, text = "Start")
self.startBttn.grid()
self.stopBttn = Button(app, text = "Stop")
self.stopBttn.grid()
self.resetBttn = Button(app, text = "Reset")
self.resetBttn.grid()
### Main Code ###
# create the root window using Tk - an object of tkinter class
root = tk.Tk()
# modify the prog. window (set size, title, etc.)
root.title("Countdown")
root.geometry("200x100")
#instantiate Application
app = Application(root)
I've been looking for an answer to this for a while but haven't been able to apply other people's solutions to my code- any ideas? If I remove the tk. before Frame in the class Application declaration I get an error that says Frame not found. If I use super(Application, self).__init__(master) instead of the line above it, I get a type error must be class not class object.
Don't explicitly pass self when calling a bound method. Call it like this:
self.create_buttons()
By calling the method with self.create_buttons(self) the function receives two arguments: the implicit self that is passed when calling a bound method (Python does this automatically), and the explicit self that you pass in the method call.
There are also some other problems with create_buttons() which you can fix with this code:
def create_buttons(self):
self.startBttn = tk.Button(self, text = "Start")
self.startBttn.grid()
self.stopBttn = tk.Button(self, text = "Stop")
self.stopBttn.grid()
self.resetBttn = tk.Button(self, text = "Reset")
self.resetBttn.grid()
The changes are that you need to use tk.Button to reference the Button class, and to pass self to tk.Button which is a reference to the parent frame. Here self is the Application instance which is a subclass of tk.Frame - hence self is a frame.
Finally you need to add a call to mainloop():
#instantiate Application
app = Application(root)
root.mainloop()
Regarding the problem with super, the tkinter classes are of the "old-style" type and do not support super(). Therefore you must call the base class with tk.Frame.__init__(self, master).
There is a workaround by using multiple inheritance and including object as a base class. If you declare Application as :
class Application(tk.Frame, object):
def __init__(self, master):
"""initialize frame"""
super(Application, self).__init__(master)
then you can use super(), but it's hardly worth the effort.

Python Tkinter class structure practice

#game class
import Tkinter as tk
class Game(tk.Canvas):
def __init__(self, master):
canvas = tk.Canvas(master)
canvas.pack()
button = tk.Button(canvas, text='Quit', command=self.quit_game)
button.pack()
def quit_game(self):
root.destroy()#Should i put something else here?
root = tk.Tk()
game = Game(root)
root.mainloop()
Is it good practice, or, in other words, is there a problem with inheriting from canvas directly instead of frame, if for example I am not going to add any widgets except the canvas?
Another question I have is regarding the root.destroy(). I don't understand why I can't say master.destroy() or something to that effect.
There is nothing wrong with inheriting from Canvas or any other Tkinter widget.
re master.destroy() vs root.destroy(): you can call it however you want. You simply need a reference to the root window. If you call it root, to destroy it you would call root.destroy().
In general you should avoid the use of global variables. Given that you're passing in the root widget to your class, you can save a reference and use that instead:
class Game(tk.Canvas):
def __init__(self, master):
self.master = master
...
def quit_game(self):
self.master.destroy()

How does class Application(frame): works?

I have a question. I thought that a class can be based on an object or previously define class. When I change it into class Application(object): it doesn't work. Can you tell me why it didn't work and why did the code below works or why did class Application(Frame) works? Frame is not a previously define object and not object. Sorry for my English. Here is my code:
# Lazy Buttons
# Demonstrates using a class with tkinter
from tkinter import *
class Application(Frame): #
""" A GUI application with three buttons. """
def __init__(self, master):
super(Application, self).__init__(master)
self.grid()
self.create_widgets()
def create_widgets(self):
""" Create three buttons that do nothing. """
# create the first Button
self.bttn1 = Button(self, text= "I do nothing.")
self.bttn1.grid()
# create second button
self.bttn2 = Button(self)
self.bttn2.grid()
self.bttn2.configure(text="Me too!")
# create third button
self.bttn3 = Button(self)
self.bttn3.grid()
self.bttn3["text"] = "Same here!"
# main
root= Tk()
root.title("Lazy Buttons")
root.geometry("200x85")
app = Application(root)
root.mainloop()
Frame is a previously defined class. It's part of tkinter, which you imported on your first line.
Your Application class extends Frame, which means that it gets methods from Frame and can do everything that a Tk Frame can do, like show widgets. If you don't extend Frame, and only extend object instead, this will not work.
It might be clearer to replace...
from tkinter import *
with...
import tkinter as tk
and fix your references to Tk's classes (they would become tk.Button, tk.Frame and tk.Tk).

Categories

Resources