Object Orientated Tkinter Functions - How would I

2019-07-22 14:54发布

I am coding a program which will need functions to change labels and enter text into text boxes however I do not know how to do this with a new style of programming which I am using (Object Orientated). I have done the program before however I generated the frames using this code:

f = [Frame(root) for i in range(0,5)]
for i in f:
    i.place(relx=0,rely=0,relwidth=1,relheight=1)

and then I put it all in one class which I ran however that was bad form so I am redoing it. My code so far is as follows:

import tkinter as tk
import datetime,time,os,sys
import sqlite3 as lite
from datetime import date

Title_Font= ("Times", 18, "underline italic")

unix = time.time()
time_curr = str(datetime.datetime.fromtimestamp(unix).strftime('%H:%M'))
date1 = str(datetime.datetime.fromtimestamp(unix).strftime('%d-%m-%Y'))


class Creating_Stuff(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 = {}

        for F in (StartPage, PageOne, PageTwo):

            frame = F(container, self)

            self.frames[F] = frame

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

        self.show_frame(StartPage)

    def show_frame(self, cont):

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

class StartPage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(3, weight=1)       

        self.option_add( "*font", "Times 12" )
        self.tk_setPalette(background='#bbfff0', foreground='black',
               activeBackground='#d9d9d9', activeForeground='#ff9933')


        label = tk.Label(self, text="Laptop Booking System", font=Title_Font)
        label.grid(row=0, column=1, pady = 30)

        time = tk.Label(self, text="Time: " + time_curr + "\nDate: " + date1, font="Times 10")
        time.grid(row=0, column=2,columnspan=2)

        Booking_1 = tk.Button(self, text="Booking",
                            command=lambda: controller.show_frame(PageOne),bg='#f2f2f2',width=20)
        Booking_1.grid(row=2, column=1, pady=10)

        Tbl_q1 = tk.Button(self, text="Table Querying",
                            command=lambda: controller.show_frame(PageTwo),bg='#f2f2f2',width=20)
        Tbl_q1.grid(row=3, column=1, pady=10)

        Exit = tk.Button(self, text ="Exit",command=lambda:destroy(),bg='#f2f2f2')
        Exit.grid(row=5, column=1)


class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(3, weight=1)
        label = tk.Label(self, text="Page One!!!", font=Title_Font)
        label.grid(row=1, column=1)


        bk2_menu = tk.Button(self, text="Back to Home",
                            command=lambda: controller.show_frame(StartPage))
        bk2_menu.grid(row=3, column=1)



class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(3, weight=1)
        label = tk.Label(self, text="Page Two!!!", font=Title_Font)
        label.grid(row=1, column=1)


        bk2_Menu2 = tk.Button(self, text="Back to menu",
                            command=lambda: controller.show_frame(StartPage))
        bk2_Menu2.grid(row=3, column=1)



app = Creating_Stuff()
def destroy():
    app.destroy()

app.title("Laptop Booking System")
app.geometry("700x400")
app.mainloop()

If you try it out it works however it just has 3 different frames. How can I get a button in a frame to make a label say "Hello" in the frame after it is pressed?

1条回答
趁早两清
2楼-- · 2019-07-22 15:36

I've modified one of your page classes to illustrate how it could be done. It involved adding a Label to hold the message, a Button to control it, and a function, called simply handler(), to call when the latter is pressed. It saves the widgets by making them attributes of the containing Frame subclass instance, self, so they can be easily referenced in the handler() function (without resorting to global variables).

class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(3, weight=1)
        label = tk.Label(self, text="Page One!!!", font=Title_Font)
        label.grid(row=1, column=1)

        self.msg_label = tk.Label(self, text="")
        self.msg_label.grid(row=2, column=1)
        self.msg_button = tk.Button(self, text='Show Message',
                                    command=self.handler)
        self.msg_button.grid(row=3, column=1)
        self.msg_toggle = False

        bk2_menu = tk.Button(self, text="Back to Home", 
                             command=lambda: controller.show_frame(StartPage))
        bk2_menu.grid(row=5, column=1)

    def handler(self):
        self.msg_toggle = not self.msg_toggle
        if self.msg_toggle:
            self.msg_label.config(text='Hello')
            self.msg_button.config(text='Clear Message')
        else:
            self.msg_label.config(text='')
            self.msg_button.config(text='Show Message')

Screenshots

Before button is pressed:

screenshot showing before button is pressed

After button is pressed:

screenshot showing before button is pressed

查看更多
登录 后发表回答