Home > front end >  Creating a button in classes. Can someone help why this doesnt work
Creating a button in classes. Can someone help why this doesnt work

Time:02-18

from tkinter import *                                        
root = Tk()                                                  
                                                             
def main():                                                  
    Window1 = Window(root, "hello", "500x500",)              
                                                             
class Window:                                                
    def __init__(self, root, title, geometry,):              
        self.root = root                                     
        root.title(title)                                    
        root.geometry(geometry)                              
        root.mainloop()                                      
                                                             
class Button(Window):                                        
    def __init__(self, message):                             
        self.message = message                               
        super().__init__(root,)                              
        Button(root, text=message,).pack()                   
        root.mainloop()                                      
                                                             
Button("HI")                                                 
                                                             
                                                             
main()   

CodePudding user response:

One of the two major issues I see is that your Button class is hiding the one that tkinter defines with the same name that would have been available via the from tkinter import *. The second one is that your Button shouldn't be derived from your Window class because subclassing implies there's is an "is a" relationship between the two classes — which is clearly not the case with them.

Below is an object-oriented way to do things that does work:

import tkinter as tk  # PEP 8 recommends avoiding `import *`


def main():
    root = tk.Tk()
    window1 = Window(root, "hello", "500x500")
    Button(root, "HI")
    root.mainloop()


class Window:
    def __init__(self, root, title, geometry):
        self.root = root
        root.title(title)
        root.geometry(geometry)


class Button:
    def __init__(self, parent, message):
        self.message = message
        tk.Button(parent, text=message).pack()


if __name__ == '__main__':
    main()

CodePudding user response:

There are a couple of issues.

Firstly, you're creating a subclass of Window called "Button". When you subclass something, it means that it will be of a similar type as it's parent (Window != Button). But more than that, when you define Button, you're actually hiding tkinter's button!

Second, you need to think about the event loop. When working with GUIs, you want to set everything up (where is the button, where are form elements, etc.) before running the mainloop (where possible). You're calling the root.mainloop function in each element, when you should only really call it once (and probably in your main() method).

So how to actually do it? You're code may look something like this

from tkinter import *


class Window:
    def __init__(self, root, title, geometry, ):
        self.root = root
        root.title(title)
        root.geometry(geometry)

    def add_button(self, label):
        btn = Button(self.root, text=label)
        btn.pack(side='top')


def main():
    root = Tk()
    Window1 = Window(root, "hello", "500x500", )
    Window1.add_button("Hi!")
    root.mainloop()


if __name__ == "__main__":
    main()

Here, the window has a method called "add_button", where you can add whatever button you want. Note that it is just creating a new Button object (the parent is "root") and then is "packing" it (feel free to read more about tk's layouts), which puts it in its place

I've also cleaned up the main function and called it under the classic 'if name == "main":' line.

CodePudding user response:

import tkinter as tk

def main():
root = tk.Tk()
window1 = Window(root, "hello", "500x500")
Button(root, "Click me", 2, 2, 10, 5)
root.mainloop()

class Window:
def init(self, root, title, geometry):
self.root = root
root.title(title)
root.geometry(geometry)

class Button:
def init(self, parent, message, row, column, width, height,):
self.message = message
self.row = row
self.column = column
self.width = width
self.height = height
tk.Button(parent, text=message, height=height, width=width).grid(column=column, row=row)

if name == 'main':
main()

the grid function isnt working now lol

  • Related