1

so i am doing some learning with modules. i am decent with tkinter after using it for 5 months or so. i can get this to work if i put my functions inside my main file. i am separating them into separate modules so i can learn how to work with modules better. so this question is more for knowledge.

I am going to have 3 files total, my main loop (example_gui.py) , my pythonic functions (example_funcs.py) , my GUI functions (more_example_funcs.py)... you can see that my issue is with using "get_text()" inside more_example_funcs.py its obvious why it doesnt work in this case. the variable is not defined inside this .py file. how would i make this work? I was told it is better way to code by having the functions inside another file(modules).

With a full scale app using Tkinter , i am going to have bunch of functions connected to entries an such that are going to be defined in the example_gui.py it would be much easier if i could put the functions for those inside more_example_funcs.py just like my example below

example_funcs.py

from Tkinter import *
import Tkinter as tk

def center(toplevel):
    toplevel.update_idletasks()
    w = toplevel.winfo_screenwidth()
    h = toplevel.winfo_screenheight()
    size = tuple(int(_) for _ in toplevel.geometry().split('+')[0].split('x'))
    x = w/2 - size[0]/2
    y = h/2 - size[1]/2
    toplevel.geometry("%dx%d+%d+%d" % (size + (x, y)))

def popupmsg(msg):
    popup = tk.Toplevel()
    popup.title("Information Dialog")
    label = Label(popup, text = msg)
    label.pack(side="top", pady=10)
    button = Button(popup, text = "OK", command = popup.destroy)
    button.pack()
    popup.grab_set()
    center(popup)
    popup.mainloop()

more_example_funcs.py

from Tkinter import *
import Tkinter as tk

def get_text():
    print entry_one_var.get()

example_gui.py

from Tkinter import *
import Tkinter as tk
import example_funcs as EF
import more_example_funcs as MEF

class start(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = {}
        tk.Tk.title(self, "app name")
        menubar = tk.Menu(container)
        tk.Tk.config(self, menu=menubar)
        fileMenu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="File", menu=fileMenu)
        fileMenu.add_command(label="Exit", command=quit)

        for F in (Page_one, Page_two, Page_three):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")


        self.show_frame(Page_one)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

class Page_one(tk.Frame):

    def __init__(self, parent, controller, *args, **kwargs):
        self.controller = controller
        Frame.__init__(self, parent, *args, **kwargs)
        self.labels_one()
        self.buttons_one()
        self.entries_one()

    def labels_one(self):
        label1 = Label(self, text="Welcome to page one")
        label1.grid()

    def buttons_one(self):
        button_one = Button(self, text="go to page two", command=lambda:self.controller.show_frame(Page_two))
        window_one_button = Button(self, text="open popup window", command=lambda:EF.popupmsg("New window 1"))
        text_one_button = Button(self, text="print entered text", command=MEF.get_text)
        button_one.grid()
        window_one_button.grid()
        text_one_button.grid()

    def entries_one(self):
        entry_one_var=StringVar()
        entry_one = Entry(self, textvariable= entry_one_var)
        entry_one.grid()

class Page_two(tk.Frame):

    def __init__(self, parent, controller, *args, **kwargs):
        self.controller = controller
        Frame.__init__(self, parent, *args, **kwargs)
        self.labels_two()
        self.buttons_two()

    def labels_two(self):
        label2 = Label(self, text="Welcome to page two")
        label2.grid()

    def buttons_two(self):
        button_two = Button(self, text="go to page three", command=lambda:self.controller.show_frame(Page_three))
        window_two_button = Button(self, text="open popup window", command=lambda:EF.popupmsg("New window 2"))
        button_two.grid()
        window_two_button.grid()

class Page_three(tk.Frame):

    def __init__(self, parent, controller, *args, **kwargs):
        self.controller = controller
        Frame.__init__(self, parent, *args, **kwargs)
        self.labels_three()
        self.buttons_three()

    def labels_three(self):
        label3 = Label(self, text="Welcome to page three")
        label3.grid()

    def buttons_three(self):
        button_three = Button(self, text="go to page one", command=lambda:self.controller.show_frame(Page_one))
        window_three_button = Button(self, text="open popup window", command=lambda:EF.popupmsg("New window 3"))
        button_three.grid()
        window_three_button.grid()

app = start()
EF.center(app)
app.mainloop()
3
  • What is the question? Commented Sep 12, 2017 at 1:35
  • text_one_button in Page_one() is going to call a function(get_text)when clicked... i want the function to be inside another file (more_example_funcs.py). the question is, how do i make that function work with the entry field inside example_gui.py? at some point in my function i will need to call the .get() to retrieve entry data. which will need access to variable inside example_gui.py Commented Sep 12, 2017 at 1:47
  • to sum it up, can you make my function get_text inside the file more_example_funcs.py, to use the data from the entry field inside example_gui.py Commented Sep 12, 2017 at 1:50

1 Answer 1

1

Make your get_text function take arguments so you can call it on any variable later.

more_example_funcs.py

from Tkinter import *
import Tkinter as tk

def get_text(var):
    print var.get()

Also, make entry_one_var in Page_one a class variable using the self keyword (self.entry_one_var) since you'll need it in more than one method, then pass self.entry_one_var as an argument when you call get_text.

This is how the Page_one class will look like:

class Page_one(tk.Frame):

    def __init__(self, parent, controller, *args, **kwargs):
        self.controller = controller
        Frame.__init__(self, parent, *args, **kwargs)
        self.labels_one()
        self.buttons_one()
        self.entries_one()

    def labels_one(self):
        label1 = Label(self, text="Welcome to page one")
        label1.grid()

    def buttons_one(self):
        button_one = Button(self, text="go to page two", command=lambda:self.controller.show_frame(Page_two))
        window_one_button = Button(self, text="open popup window", command=lambda:EF.popupmsg("New window 1"))
        text_one_button = Button(self, text="print entered text", command=lambda: MEF.get_text(self.entry_one_var))##
        button_one.grid()
        window_one_button.grid()
        text_one_button.grid()

    def entries_one(self):
        self.entry_one_var=StringVar() #make entry_one_var class instance variable
        entry_one = Entry(self, textvariable= self.entry_one_var) ##
        entry_one.grid()

I hope it helps.

Sign up to request clarification or add additional context in comments.

1 Comment

wish i could keep hitting up arrow. thanks a bunch. i ended up finding this stackoverflow.com/questions/42607002/… .... however yours is explained much better, especially since you used my code! haha. thank you

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.