ricky6991
ricky6991

Reputation: 53

using function from module with button -Tkinter

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()

Upvotes: 1

Views: 1107

Answers (1)

Khristos
Khristos

Reputation: 983

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.

Upvotes: 1

Related Questions