Hi all,

I am building a GUI application using Python and Tkinter to mimic a Pay-At-Pump system. Currently, I am at stage where I have coded and defined the relevant frames and widgets that help to traverse through those frames, these are organised into classes.

However, I am trying to use a "Restart" button to effectively reinitiate the program and start again (e.g. if someone makes a mistake with their input in the program). Within my code at the moment, the buttons I've put into each frame simply tell the program to show/navigate to the first frame (SelectLanguagePage).

Due to some of the functionality I am trying to achieve in the program, e.g. disabling buttons once pressed, or destroying buttons based on another widget being used, simply showing the first page does not reset the program. Consequently, when you try to cycle through the process again, it will show based on what was previously pressed.

Essentially, I have been trying to define functions for the 'Restart' button on each frame to essentially undo all of the previous actions/functions that have been carried out in the previous frames. Not only have I struggled to get this to work, as I'm not 100% sure how to call out/makes changes to widgets to one class in a different class, but this also seems a strange way of doing it.

Line 64 shows the first Restart button - this just redirects to first SelectPaymentPage page, which is fine because no other functions have been implemented

Line 75 shows function for 'Insert Card' button, where essentially it destroys the 'Restart' button to prevent you from trying to restart mid-function, while also disabling the 'Insert Card' button to avoid it being clicked multiple times

Line 95 is my current attempt to try and employ a function to undo all of previous actions, which doesn't work (which is run in line 116 - the restart button for that frame)

I was wondering if anyone knew a simple way to essentially reset the program or relaunch it?

Any help you can provide would be greatly appreciated.

Thanks

</>

import tkinter as tk
import gettext
LARGE_FONT = ("Arial", 12)
MEDIUM_FONT = ("Arial", 9)

class Oleum(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 (SelectLanguagePage, SelectPaymentPage, InsertCardPage, SelectCurrencyPage, BeginFuellingPage, TotalGoodbyePage): 
            frame = F(container, self) 
            self.frames[F] = frame 
            frame.grid(row=0, column = 0, sticky = "nsew") 
        self.show_frame(SelectLanguagePage)
    def show_frame(self, cont):
        frame = self.frames[cont] 
        frame.tkraise() 

class SelectLanguagePage(tk.Frame): 
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        EN_lang_lbl = tk.Label(self, text = "PLEASE SELECT LANGUAGE", font = LARGE_FONT) 
        EN_lang_lbl.pack(pady = 10, padx = 10) 
        DE_lang_lbl = tk.Label(self, text = "WÄHLE DEINE SPRACHE", font = LARGE_FONT) 
        DE_lang_lbl.pack(pady = 10, padx = 10)
        ES_lang_lbl = tk.Label(self, text = "ELIGE TU IDIOMA", font = LARGE_FONT) 
        ES_lang_lbl.pack(pady = 10, padx = 10)
        FR_lang_lbl = tk.Label(self, text = "CHOISISSEZ VOTRE LANGUE", font = LARGE_FONT) 
        FR_lang_lbl.pack(pady = 10, padx = 10)

        EN_lang_btn = tk.Button(self, text = "ENGLISH", 
                            command = lambda: controller.show_frame(SelectPaymentPage)) 
        EN_lang_btn.pack()
        DE_lang_btn = tk.Button(self, text = "GERMAN", 
                            command = lambda: controller.show_frame(SelectPaymentPage)) 
        DE_lang_btn.pack()
        ES_lang_btn = tk.Button(self, text = "SPANISH", 
                            command = lambda: controller.show_frame(SelectPaymentPage)) 
        ES_lang_btn.pack()
        FR_lang_btn = tk.Button(self, text = "FRENCH", 
                            command = lambda: controller.show_frame(SelectPaymentPage)) 
        FR_lang_btn.pack()

   class SelectPaymentPage(tk.Frame):
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)

            select_payment_lbl = tk.Label(self, text = "SELECT PAYMENT OPTION", font = LARGE_FONT)
            select_payment_lbl.pack(pady = 10, padx = 10)

            pap_btn = tk.Button(self, text = "PAY-AT-PUMP", 
                                command = lambda: controller.show_frame(InsertCardPage))
            pap_btn.pack()
            pap_btn = tk.Button(self, text = "PAY-AT-KIOSK", 
                                command = lambda: controller.show_frame(SelectCurrencyPage))
            pap_btn.pack()
            restart_btn = tk.Button(self, text = "RESTART", 
                                command = lambda: controller.show_frame(SelectLanguagePage))
            restart_btn.pack()

    class InsertCardPage(tk.Frame):
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)

            def delay():
                app.after(2500, controller.show_frame(SelectCurrencyPage))

            def card_read():
                insert_card_lbl['text'] = "CARD READ"
                app.after(2500, delay)
                insert_card_btn.config(state='disabled')                   # THIS DISABLES THE INSERT CARD BUTTON
                restart_btn.destroy()                                      # THIS DESTROYS RESTART BUTTON 

            insert_card_lbl = tk.Label(self, text = "PLEASE INSERT CARD", font = LARGE_FONT)
            insert_card_lbl.pack()

            insert_card_btn = tk.Button(self, text = "INSERT CARD", 
                                command = card_read) 
            insert_card_btn.pack() 
            restart_btn = tk.Button(self, text = "RESTART", 
                                command = lambda: controller.show_frame(SelectLanguagePage))
            restart_btn.pack()

    class SelectCurrencyPage(tk.Frame):
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)

            def currency_restart():     #THIS DOESN'T WORK - NOT SURE HOW TO MAKE CHANGES TO ANOTHER CLASS WITHIN A CLASS
                InsertCardPage.insert_card_lbl = tk.Label(self, text = "PLEASE INSERT CARD", font = LARGE_FONT)
                InsertCardPage.insert_card_btn.config(state='active')
                InsertCardPage.restart_btn = tk.Button(self, text = "RESTART", 
                                command = InsertCardPage.card_restart)
                restart_btn.pack()
                controller.show_frame(SelectLanguagePage)

            currency_lbl = tk.Label(self, text = "PLEASE SELECT CURRENCY", font = LARGE_FONT)
            currency_lbl.pack(pady = 10, padx = 10)

            GBP_btn = tk.Button(self, text = "£ GBP", 
                                command = lambda: controller.show_frame(BeginFuellingPage))
            GBP_btn.pack()
            USD_btn = tk.Button(self, text = "$ USD", 
                                command = lambda: controller.show_frame(BeginFuellingPage))
            USD_btn.pack()
            EUR_btn = tk.Button(self, text = "€ EUR", 
                                command = lambda: controller.show_frame(BeginFuellingPage))
            EUR_btn.pack()

            restart_btn = tk.Button(self, text = "RESTART", 
                                command = currency_restart)
            restart_btn.pack()

    </>

@rproffitt Thanks for the below - I had found that and tried it out, but I struggled to get it to work. However, I have tried it again and managed to get further than last time, but still find it doesn't work. It closes the program but then doesn't restart?

See definition of restart_program() included at the top, as well as the reference to it in the RESTART button at the bottom

import tkinter as tk
import gettext
import sys
import os

def restart_program():
        python = sys.executable
        os.execl(python, python, *sys.argv)

LARGE_FONT = ("Arial", 12)
MEDIUM_FONT = ("Arial", 9)

class Oleum(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 (SelectLanguagePage, SelectPaymentPage, InsertCardPage, SelectCurrencyPage, BeginFuellingPage, TotalGoodbyePage): 
            frame = F(container, self) 
            self.frames[F] = frame 
            frame.grid(row=0, column = 0, sticky = "nsew") 
        self.show_frame(SelectLanguagePage)
    def show_frame(self, cont):
        frame = self.frames[cont]  
        frame.tkraise() 

class SelectLanguagePage(tk.Frame): 
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent) 

        EN_lang_lbl = tk.Label(self, text = "PLEASE SELECT LANGUAGE", font = LARGE_FONT) 
        EN_lang_lbl.pack(pady = 10, padx = 10) 

        DE_lang_lbl = tk.Label(self, text = "WÄHLE DEINE SPRACHE", font = LARGE_FONT) 
        DE_lang_lbl.pack(pady = 10, padx = 10)

        ES_lang_lbl = tk.Label(self, text = "ELIGE TU IDIOMA", font = LARGE_FONT) 
        ES_lang_lbl.pack(pady = 10, padx = 10)

        FR_lang_lbl = tk.Label(self, text = "CHOISISSEZ VOTRE LANGUE", font = LARGE_FONT) 
        FR_lang_lbl.pack(pady = 10, padx = 10)

        EN_lang_btn = tk.Button(self, text = "ENGLISH", 
                            command = lambda: controller.show_frame(SelectPaymentPage)) 
        EN_lang_btn.pack()

        DE_lang_btn = tk.Button(self, text = "GERMAN", 
                            command = lambda: controller.show_frame(SelectPaymentPage)) 
        DE_lang_btn.pack()

        ES_lang_btn = tk.Button(self, text = "SPANISH", 
                            command = lambda: controller.show_frame(SelectPaymentPage)) 
        ES_lang_btn.pack()

        FR_lang_btn = tk.Button(self, text = "FRENCH", 
                            command = lambda: controller.show_frame(SelectPaymentPage)) 
        FR_lang_btn.pack()

class SelectPaymentPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        select_payment_lbl = tk.Label(self, text = "SELECT PAYMENT OPTION", font = LARGE_FONT)
        select_payment_lbl.pack(pady = 10, padx = 10)

        pap_btn = tk.Button(self, text = "PAY-AT-PUMP", 
                            command = lambda: controller.show_frame(InsertCardPage))
        pap_btn.pack()

        pap_btn = tk.Button(self, text = "PAY-AT-KIOSK", 
                            command = lambda: controller.show_frame(SelectCurrencyPage))
        pap_btn.pack()

        restart_btn = tk.Button(self, text = "RESTART", 
                            command = restart_program)
        restart_btn.pack()