Python Forum
[Tkinter] Tkinter Class Import Module Issue
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] Tkinter Class Import Module Issue
#1
Lightbulb 
I'm trying to keep my code clean by separating the GUI from the logic.

Inside of the 'main.py' file, I'd like to call functions from other files that are imported to build the GUI.

The problem is that I cannot figure out how to build a GUI from the 'main.py' file when I try to call another file as an imported module.

Here's what I have in the 'main.py' file:

from tkinter import *
import create_btn

class Main(Tk):
    def __init__(self):
        super().__init__()
        self.title('Main Window')
        self.geometry('600x400')
        self.eval('tk::PlaceWindow . center')


if __name__ == '__main__':
    app = Main()
    app.mainloop()
And here is what I have in the 'create_btn.py' file:

from tkinter import *

def createBTN(self):
    self.b1 = Button(root, text='B1')
    self.b1.pack()
So, how exactly can I build a simple button from another file that I want to import into the 'main.py', or in other words, how do I get the 'create_btn.py' file to build the button inside of the 'main.py' file? A simple example would be greatly appreciated.
Reply
#2
In main.py, you just call
create_btn.createBTN(self)
Also note that in createBTN(), there is an undefined reference to 'root'. I suppose you mean 'self'.
AaronCatolico1 likes this post
Reply
#3
Thanks you so much! This worked!

Also, could you briefly explain why I have to put '(self)' into the 'create_btn.createBTN(self)' function?
I'm still trying to learn classes in both Python & Tkinter. I'm not quite sure how it relates to the class.
Thanks again!
Reply
#4
(Sep-04-2022, 08:20 PM)AaronCatolico1 Wrote: Also, could you briefly explain why I have to put '(self)' into the 'create_btn.createBTN(self)' function?
The function needs at least an argument that is the parent widget of the Button it creates. You could perhaps call this argument 'parent' instead of 'self'.

When developing the function, you may find that it needs to access methods of your instance of the Main class, for example it may want to call a method of that class, in that case, it would become necessary to pass this instance. The variable name 'self' is typically used only to denote the implicit instance of methods in classes, not external functions.

Another technique that you will learn when you have more experience with classes is that of Mixin classes, which are ways of extending existing classes with new methods that may come from another file. As you are only beginning to use classes, keep it simple.
AaronCatolico1 likes this post
Reply
#5
Please see the thread Namespace flooding with * imports

If your intention is to make a special version of a tk.Button that you set some attributes and then use that button in various places.
Subclass tk.Button and then you can use it in place of a normal tk.Button,
I would leave the parent to decide how the buttons are located.

specialized_btn.py
import tkinter as tk


class SpecializedButton(tk.Button):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # your sepecialized code here
        self.config(bg="Red")
main.py
import tkinter as tk
from specialized_btn import SpecializedButton


class MainFrame(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, *kwargs)
        specialized_button = SpecializedButton(self, text="B1")
        specialized_button.pack()


def main():
    app = tk.Tk()
    app.title("Main Window")
    app.geometry("600x400")
    app.eval("tk::PlaceWindow . center")
    main_frame = MainFrame(app)
    main_frame.pack()
    app.mainloop()


if __name__ == "__main__":
    main()
AaronCatolico1 likes this post
Reply
#6
I am not seeing where you are "separating the GUI from the logic". Where is there any logic?

Or are you trying to create a layer that insulates writing a GUI program from the details of a particular GUI package? In that context "createButton()" makes a little more sense, but I would still try to implement that framework as a family of classes instead of a bunch of functions. Programmers will want to create special versions of your button (subclasses) and this is easier if you provide classes instead of functions.
AaronCatolico1 likes this post
Reply
#7
Lightbulb 
Thank you for your example code!

(Sep-04-2022, 09:07 PM)Yoriz Wrote: Please see the thread Namespace flooding with * imports

If your intention is to make a special version of a tk.Button that you set some attributes and then use that button in various places.
Subclass tk.Button and then you can use it in place of a normal tk.Button,
I would leave the parent to decide how the buttons are located.

specialized_btn.py
import tkinter as tk


class SpecializedButton(tk.Button):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # your sepecialized code here
        self.config(bg="Red")
main.py
import tkinter as tk
from specialized_btn import SpecializedButton


class MainFrame(tk.Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, *kwargs)
        specialized_button = SpecializedButton(self, text="B1")
        specialized_button.pack()


def main():
    app = tk.Tk()
    app.title("Main Window")
    app.geometry("600x400")
    app.eval("tk::PlaceWindow . center")
    main_frame = MainFrame(app)
    main_frame.pack()
    app.mainloop()


if __name__ == "__main__":
    main()
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
Lightbulb Using Tkinter With Concurrent.Futures / ThreadPoolExecutor Class AaronCatolico1 1 1,479 Dec-14-2022, 08:01 PM
Last Post: deanhystad
  unexplained issue with tkcalender module. cybertooth 8 7,640 Aug-12-2021, 11:00 PM
Last Post: deanhystad
  [Tkinter] Redirecting all print statements from all functions inside a class to Tkinter Anan 1 2,653 Apr-24-2021, 08:57 AM
Last Post: ndc85430
  tkinter moving an class object with keybinds gr3yali3n 5 3,291 Feb-10-2021, 09:13 PM
Last Post: deanhystad
  Super basic tkinter arduino issue Kurta 3 2,416 Jan-07-2021, 05:22 PM
Last Post: deanhystad
Photo tkinter issue mate 4 2,544 Dec-06-2020, 09:03 PM
Last Post: mate
  How to import entire module ? tonycstech 5 3,346 Oct-21-2020, 06:16 AM
Last Post: tonycstech
  Issue in Tkinter with winfo_class() and LabelFrame ReDefendeur 1 2,747 Oct-05-2020, 05:52 AM
Last Post: Jeff900
  [Tkinter] tkinter: after issue edwin6938 1 3,407 Aug-25-2020, 04:37 PM
Last Post: Larz60+
  [Tkinter] Troubles with accessing attr from other class zarize 3 2,643 Aug-20-2020, 06:05 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020