最近有一個需要,用python搭建一個測試軟件。需要三種測試功能,三種功能所需要的參數還不一樣,所以操作界面也不一樣。在網上看了一些教程,感覺自己水平不夠,看不太懂,就自己琢磨了一下,實現了三個界面互相切換的功能,在這里記錄一下。(Python3做的)
我的主界面只有輸入參數的界面需要切換,其他界面不需要改變。因此我把這個界面所有的組件都放在一個Frame中,利用destroy方法摧毀一個,再新放置另一個Frame,從而實現界面的切換。下面是我截取的界面部分代碼,可能多少有點格式的問題,需要小修改。另外我已經把所有按鍵的觸發函數去掉了。后面簡單的分析一下代碼。
import tkinter as tk #---------主窗口初始化--------- def main_window_init(size = '900x556'): my_window = tk.Tk() #新建一個主窗口 my_window.title('探針測試系統') #窗口名 my_window.geometry(size) #窗口大小 my_window.resizable(width = False,height = False) #是否可以拉伸 #my_window.iconbitmap('001.ico') #圖標 return my_window #---------創建IV測試參數輸入界面--------- def IV_input_window_init(): #----------參數輸入窗口--------- Frame_input = tk.Frame(main_window) #放置所有組件的框架 tk.Label(Frame_input,text='開始電壓(V):',bg='#DDDDDD',width=12).grid(row=0,column=0) #起始電壓文本 Entry_v_start = tk.Entry(Frame_input,bg='#DDDDDD',width=12) #起始電壓輸入控件 Entry_v_start.grid(row=0,column=1) tk.Label(Frame_input,text='結束電壓(V):',bg='#DDDDDD',width=12).grid(row=1,column=0) #結束電壓文本 Entry_v_stop = tk.Entry(Frame_input,bg='#DDDDDD',width=12) #結束電壓輸入控件 Entry_v_stop.grid(row=1,column=1) tk.Label(Frame_input,text='步長(V):',bg='#DDDDDD',width=12).grid(row=2,column=0) #步長 Entry_step = tk.Entry(Frame_input,bg='#DDDDDD',width=12) #步長輸入控件 Entry_step.grid(row=2,column=1) tk.Label(Frame_input,text='延時(ms):',bg='#DDDDDD',width=12).grid(row=3,column=0) #延時 Entry_delay = tk.Entry(Frame_input,bg='#DDDDDD',width=12) #延時 Entry_delay.grid(row=3,column=1) tk.Label(Frame_input,text='限流(A):',bg='#DDDDDD',width=12).grid(row=4,column=0) #限流文本 Entry_compliance = tk.Entry(Frame_input,bg='#DDDDDD',width=12) #限流輸入控件 Entry_compliance.grid(row=4,column=1) tk.Label(Frame_input,text='點數(個):',bg='#DDDDDD',width=12).grid(row=5,column=0) #文本 tk.Label(Frame_input,textvariable=num_of_data, bg='#DDDDDD',width=12,relief='ridge').grid(row=5,column=1) #點數 #Rbuttn_sweep_direction = tk.Checkbutton(Frame_input,text='單掃') tk.Button(Frame_input,text='保存',width=12, #保存參數按鍵 bg='#87CEFA').grid(row=6,column=0) tk.Button(Frame_input,text='運行',width=12, #啟動按鍵 bg='#87CEFA').grid(row=6,column=1) tk.Button(Frame_input,text='清除圖像',width=12, #清空 bg='#87CEFA').grid(row=7,column=0) tk.Button(Frame_input,text='退出',width=12, #退出 command=main_window.quit,bg='#87CEFA').grid(row=7,column=1) #Frame_input.place(x=60,y=200) #放置框架 return Frame_input #---------創建IV_t測試參數輸入界面--------- def IVt_input_window_init(): #----------參數輸入窗口--------- Frame_input = tk.Frame(main_window) #放置所有組件的框架 tk.Label(Frame_input,text='偏置電壓(V):').grid(row=0,column=0) #起始電壓文本 Entry_v_bias = tk.Entry(Frame_input,bg='#DDDDDD') #起始電壓輸入控件 Entry_v_bias.grid(row=0,column=1) tk.Label(Frame_input,text='掃描點數:').grid(row=1,column=0) #結束電壓文本 Entry_v_stop = tk.Entry(Frame_input,bg='#DDDDDD') #結束電壓輸入控件 Entry_v_stop.grid(row=1,column=1) tk.Label(Frame_input,text='步長(V):').grid(row=2,column=0) #步長 Entry_step = tk.Entry(Frame_input,bg='#DDDDDD') #步長輸入控件 Entry_step.grid(row=2,column=1) tk.Label(Frame_input,text='延時(ms):').grid(row=3,column=0) #延時 Entry_delay = tk.Entry(Frame_input,bg='#DDDDDD') #延時 Entry_delay.grid(row=3,column=1) tk.Button(Frame_input,text='保存',width=12,height=3, #保存參數按鍵 bg='#0baef4').grid(row=4,column=0) tk.Button(Frame_input,text='運行',width=12,height=3, #啟動按鍵 bg='#0baef4').grid(row=4,column=1) tk.Button(Frame_input,text='CLR',width=12,height=3, #清空 bg='#0baef4').grid(row=5,column=0) tk.Button(Frame_input,text='退出',width=12,height=3, #退出 command=main_window.quit,bg='#0baef4').grid(row=5,column=1) return Frame_input #---------創建Endurance測試參數輸入界面--------- def Endurance_input_window_init(): #----------參數輸入窗口--------- Frame_input = tk.Frame(main_window) #放置所有組件的框架 tk.Label(Frame_input,text='開始電壓(V):').grid(row=0,column=0) #起始電壓文本 Entry_v_start = tk.Entry(Frame_input,bg='#DDDDDD') #起始電壓輸入控件 Entry_v_start.grid(row=0,column=1) tk.Label(Frame_input,text='結束電壓(V):').grid(row=1,column=0) #結束電壓文本 Entry_v_stop = tk.Entry(Frame_input,bg='#DDDDDD') #結束電壓輸入控件 Entry_v_stop.grid(row=1,column=1) return Frame_input #---------創建模式選擇界面----------- def testmode_switch_init(): Frame_testmode = tk.Frame(main_window,width=900,height=20) #放置所有組件的框架 tk.Button(Frame_testmode,text='I-V測試',width=33,height=2, #I-V測試 command=switch_to_iv,bg='#696969',fg='#FFFFFF', font=("Arial",11)).grid(row=0,column=0) tk.Button(Frame_testmode,text='I-V-t測試',width=33,height=2, #I-V-t測試 command=switch_to_iv_t,bg='#696969',fg='#FFFFFF', font=("Arial",11)).grid(row=0,column=1) tk.Button(Frame_testmode,text='endurance測試',width=33,height=2, #endurrance測試 command=switch_to_endurance,bg='#696969',fg='#FFFFFF', font=("Arial",11)).grid(row=0,column=2) Frame_testmode.place(x=0,y=3) #--------進入IV測試界面---------- def switch_to_iv(): global intput_win1,intput_win2,intput_win3 intput_win1.destroy() intput_win2.destroy() intput_win3.destroy() intput_win1 = IV_input_window_init() #輸入界面初始化 intput_win1.place(x=60,y=200) #放置框架 print('iv') #--------進入IV-t測試界面---------- def switch_to_iv_t(): global intput_win1,intput_win2,intput_win3 intput_win1.destroy() intput_win2.destroy() intput_win3.destroy() intput_win2 = IVt_input_window_init() intput_win2.place(x=60,y=200) #放置框架 #--------進入endurance測試界面---------- def switch_to_endurance(): global intput_win1,intput_win2,intput_win3 intput_win1.destroy() intput_win2.destroy() intput_win3.destroy() intput_win3 = Endurance_input_window_init() intput_win3.place(x=60,y=200) #放置框架 #----------創建matplotlib畫布---------- def data_canvas_init(): fig = plt.figure(figsize=(6,4),dpi=70) #圖像大小和比例 plt.grid() canvas_spice = FigureCanvasTkAgg(fig,main_window) canvas_spice.get_tk_widget().place(x=300,y=100) #放置位置 canvas_spice.draw() return canvas_spice #Test_parameter = parameter_class() #存儲測試參數 #keithley_237 = open_instrument() #打開keithley237設備 main_window = main_window_init() #創建主窗口 #num_of_data = tk.IntVar() #保存掃描點數的變量,可以隨時更新 #----------背景------------ #設置背景一定要在主函數里,否則不會顯示 img_bg = tk.PhotoImage(file="pic/bg_1.gif") #打開圖片 canvas_bg = tk.Canvas(main_window,width=900,height=556) #新建一個畫布 canvas_bg.create_image(440,278,image = img_bg) #放置背景圖片 canvas_bg.place(x=-2,y=0) #放置畫布 #global intput_win1,intput_win2,intput_win3 intput_win1 = IV_input_window_init() #輸入界面初始化 intput_win2 = IVt_input_window_init() intput_win3 = Endurance_input_window_init() intput_win1.place(x=60,y=200) #放置框架 testmode_switch_init() #測試模式選擇界面初始化 canvas_data = data_canvas_init() #圖形化數據部分初始化 main_window.mainloop() #開始主循環
代碼里三個Frame的布局是分別在 IV_input_window_init()、IVt_input_window_init()、Endurance_input_window_init()中完成的,布局完成后並沒有放置Frame,而是返回了一個Frame。所以我在模式切換的界面,testmode_switch_init()中設置了三個按鈕,分別對應了switch_to_iv()、switch_to_iv_t()和switch_to_endurance()三個響應事件。接下來是重點。
我在主函數里用了三個全局變量intput_win1、intput_win2和intput_win3,分別對應三個Frame,開始的時候默認放置intput_win1,所以用了intput_win1.place()函數。在切換界面按鍵按下以后,響應函數依次摧毀intput_win1、intput_win2和intput_win3三個Frame。然后重新對着三個全局變量賦值,賦的是三個新的Frame,最后放置對應的一個Frame就可以了。這里有一點需要注意,在函數中對全局變量賦值的時候需要先用global聲明一下,否則會報錯。
最后展示一下實際的效果,這個是開始的界面
按下IVT測試按鍵后,切換到另一個界面
按下endurane測試按鍵后切換到第三個界面。