I am new to Python and am writing a code to automate certain measurement equipment. I am going to mention only a small part of my code to keep it concise.
The first class VSWR is used to select different frames. Since I need to change frames and go back and forth in them, I made a class VSWR. This class calls Start Page , which has a button "Path Loss". After clicking this button, the user needs to enter certain parameters, and in this case "Start and Stop Frequencies". Clicking the OK button will show what the user has entered and then asks the user to confirm it. After confirming a text window opens in a new frame(which is the RunModuleTests class). I will write all my remaining automation code in this class. But for now I want the power supply to turn on(for now I am using insert command message to show that my power supply is turned on) after 4 secs after I hit the confirm button. But what is happening is the RunModuleTests class executes as soon as I run the whole code and by the time I reach to my text window after entering the parameters, power supply will already be turned on.
What I think is happening is that as soon as I hit run on my whole code, the mainloop starts the execution of all the frames. (Please correct me if I am wrong here), whereas I want my frames(or classes and their functions) to execute only when those classes are called by clicking the button and not when I hit Run for the whole code. Is there any work around to this ?? Please let me know if someone needs me to elaborate my question or need more details of the issue I am facing here. Thanks
import Tkinter as tk
from Tkinter import DoubleVar, IntVar, StringVar
import ttk
from numpy import arange
LARGE_FONT= ("Verdana", 12)
class VSWR(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "VSWR")
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, PathLoss, RunModuleTests):
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)
label = tk.Label(self, text="This is the start page", font=LARGE_FONT)
label.pack(pady=10,padx=10)
button3 = ttk.Button(self, text="Path Loss",
command=lambda: controller.show_frame(PathLoss))
button3.pack()
class PathLoss(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
labelPathLoss = ttk.Label(self, text = 'Path Loss Measurement:', font=LARGE_FONT)
labelPathLoss.pack(pady=10,padx=10)
global X, Y
X = 20
Y = 100
#Define Variables with Type
self.startFreq = DoubleVar()
self.stopFreq = DoubleVar()
self.freqInc = IntVar()
labelenterStartFreq = ttk.Label(self, text = 'Enter the Start Frequency (in MHz):')
labelenterStartFreq.place(x = X, y = Y+20)
labelenterStopFreq = ttk.Label(self, text = 'Enter the Stop Frequency (in MHz):')
labelenterStopFreq.place(x = X, y = Y+40)
entryStartFreq = ttk.Entry(self, textvariable = self.startFreq)
entryStartFreq.place(x = X+240, y = Y+20)
entryStopFreq = ttk.Entry(self, textvariable = self.stopFreq)
entryStopFreq.place(x = X+240, y = Y+40)
buttonOK = ttk.Button(self, text = 'OK', command = lambda: self.getValues(X,Y, controller))
buttonOK.place(x = X+240, y = Y+270)
def getValues(self,X,Y, controller):
getStartFreq = self.startFreq.get()
getStopFreq = self.stopFreq.get()
ttk.Label(self, text = 'You entered the following values:').place(x = X+580, y = Y)
ttk.Label(self, text = 'Start Frequency : %5.2f' %getStartFreq).place(x = X+580, y = Y+20)
ttk.Label(self, text = 'Stop Frequency : %5.2f' %getStopFreq).place(x = X+580, y = Y+40)
buttonConfirmPL = ttk.Button(self, text = 'Confirm', command = lambda: controller.show_frame(RunModuleTests))
buttonConfirmPL.place(x = X+580, y = Y+300)
class RunModuleTests(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.rootText = tk.Text(self)
self.rootText.place(x = 200, y = 100)
self.rootText.tkraise()
opening = '\nProceeding to measure TRX path loss for FWD/REV....\n'
self.rootText.insert("insert", opening )
self.rootText.after(4000, self.temp)
def temp(self):
self.rootText.insert("insert", '\nTurning Power supply ON...\n')
app = VSWR()
app.geometry('1000x600+150+100')
app.mainloop()
The reason the power supply turn-on message appears immediately is this: At the very start of your program you create an instance of
StartPage
,PathLoss
andRunModuleTests
. In the__init__
method ofRunModuleTests
you're callingself.rootText.after(4000, self.temp)
, andself.temp
writes that message. Thus, four seconds after your program starts, that message appears.There are many solutions, but to do it properly involves a lot of rewriting. The structure of your code makes a simple solution difficult. The most common things you can try is to either a) not create an instance of
RunModuleTests
until you actually need it, or b) move the call toafter
into some other function, and then call that function only after you make that frame visible.Personally I would do the latter -- you need to decouple the creation of the frame from the functions that can be done when the frame is visible. That means you'll need to add some extra logic to
show_frame
, or replace the call toshow_frame
with something else.