2012-06-19 599 views
4

我一直在研究python3中的tkinter,並發現它很難找到很好的文檔和在線答案。爲了幫助他人解決同樣的問題,我決定發佈一個解決方案,解決一個簡單的問題,那就是沒有在線文檔。解決方案:Python3 Tkinter從一個窗口跳轉到另一個窗口到另一個按鈕

問題:創建一個類似嚮導的程序,向用戶顯示一系列窗口,用戶可以在窗口之間單擊下一步和後退按鈕。

的解決方案是:

  • 創建一個根窗口。
  • 創建儘可能多的框架,因爲您有窗口呈現給用戶。將所有幀附加到根窗口。
  • 填充每個框架與它需要的所有小部件。
  • 當所有的幀都被填充後,用grid_forget()方法隱藏每一幀,但保留第一幀爲非隱藏狀態,使其成爲可見幀。框架上的所有子部件都將隱藏在框架中。
  • 當用戶單擊窗口上的下一個或後退按鈕時,調用隱藏其他框架的子例程(使用grid_forget()),並使需要的框架可見(使用grid())。
  • 如果您希望程序結束,請使用destroy-method作爲根窗口。

因此,您將創建一個窗口並顯示不同的框架。

(順便說一句,最好的地方開始學習Tkinter的是:http://www.tkdocs.com/tutorial/index.html

這裏是Python3一個樣本實現。它有3個簡單的窗口,每個窗口都有一個文本標籤和兩個按鈕來瀏覽不同的窗口。

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
# 

# Creates three "windows" that the user can navigate through using Back and Next - buttons. 

import tkinter 
import tkinter.ttk 

def create_widgets_in_first_frame(): 
    # Create the label for the frame 
    first_window_label = tkinter.ttk.Label(first_frame, text='Window 1') 
    first_window_label.grid(column=0, row=0, pady=10, padx=10, sticky=(tkinter.N)) 

    # Create the button for the frame 
    first_window_quit_button = tkinter.Button(first_frame, text = "Quit", command = quit_program) 
    first_window_quit_button.grid(column=0, row=1, pady=10, sticky=(tkinter.N)) 
    first_window_next_button = tkinter.Button(first_frame, text = "Next", command = call_second_frame_on_top) 
    first_window_next_button.grid(column=1, row=1, pady=10, sticky=(tkinter.N)) 

def create_widgets_in_second_frame(): 
    # Create the label for the frame 
    second_window_label = tkinter.ttk.Label(second_frame, text='Window 2') 
    second_window_label.grid(column=0, row=0, pady=10, padx=10, sticky=(tkinter.N)) 

    # Create the button for the frame 
    second_window_back_button = tkinter.Button(second_frame, text = "Back", command = call_first_frame_on_top) 
    second_window_back_button.grid(column=0, row=1, pady=10, sticky=(tkinter.N)) 
    second_window_next_button = tkinter.Button(second_frame, text = "Next", command = call_third_frame_on_top) 
    second_window_next_button.grid(column=1, row=1, pady=10, sticky=(tkinter.N)) 

def create_widgets_in_third_frame(): 
    # Create the label for the frame 
    third_window_label = tkinter.ttk.Label(third_frame, text='Window 3') 
    third_window_label.grid(column=0, row=0, pady=10, padx=10, sticky=(tkinter.N)) 

    # Create the button for the frame 
    third_window_back_button = tkinter.Button(third_frame, text = "Back", command = call_second_frame_on_top) 
    third_window_back_button.grid(column=0, row=1, pady=10, sticky=(tkinter.N)) 
    third_window_quit_button = tkinter.Button(third_frame, text = "Quit", command = quit_program) 
    third_window_quit_button.grid(column=1, row=1, pady=10, sticky=(tkinter.N)) 

def call_first_frame_on_top(): 
    # This function can be called only from the second window. 
    # Hide the second window and show the first window. 
    second_frame.grid_forget() 
    first_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E)) 

def call_second_frame_on_top(): 
    # This function can be called from the first and third windows. 
    # Hide the first and third windows and show the second window. 
    first_frame.grid_forget() 
    third_frame.grid_forget() 
    second_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E)) 

def call_third_frame_on_top(): 
    # This function can only be called from the second window. 
    # Hide the second window and show the third window. 
    second_frame.grid_forget() 
    third_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E)) 

def quit_program(): 
    root_window.destroy() 

############################### 
# Main program starts here :) # 
############################### 

# Create the root GUI window. 
root_window = tkinter.Tk() 

# Define window size 
window_width = 200 
window_heigth = 100 

# Create frames inside the root window to hold other GUI elements. All frames must be created in the main program, otherwise they are not accessible in functions. 
first_frame=tkinter.ttk.Frame(root_window, width=window_width, height=window_heigth) 
first_frame['borderwidth'] = 2 
first_frame['relief'] = 'sunken' 
first_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E)) 

second_frame=tkinter.ttk.Frame(root_window, width=window_width, height=window_heigth) 
second_frame['borderwidth'] = 2 
second_frame['relief'] = 'sunken' 
second_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E)) 

third_frame=tkinter.ttk.Frame(root_window, width=window_width, height=window_heigth) 
third_frame['borderwidth'] = 2 
third_frame['relief'] = 'sunken' 
third_frame.grid(column=0, row=0, padx=20, pady=5, sticky=(tkinter.W, tkinter.N, tkinter.E)) 

# Create all widgets to all frames 
create_widgets_in_third_frame() 
create_widgets_in_second_frame() 
create_widgets_in_first_frame() 

# Hide all frames in reverse order, but leave first frame visible (unhidden). 
third_frame.grid_forget() 
second_frame.grid_forget() 

# Start tkinter event - loop 
root_window.mainloop() 
+0

那麼問題是什麼?雖然是的,你可以自我回答,你應該通過發佈答案來做到這一點_作爲問題的答案。 –

+1

只是爲了澄清:我創建此線程不要問一個問題,而是發佈一個解決方案,以解決我在許多網站上看到的常見問題。 我需要創建的第一個真正的GUI程序是「安裝嚮導」,經過數小時的挖掘,我找不到任何示例代碼在線。所以,當我最終得到了我的「概念證明」的工作,我決定在這裏發佈它,希望它可以幫助其他人學習tkinter :) –

+1

@Mikael Hartzell:Donal所做的是這樣的:適當的程序爲什麼你所做的就是發明一個問題,然後提供你的答案作爲實際答案。所以,你的問題可以很簡單,「如何製作一個類似嚮導的窗口,可以通過下一個和後一個按鈕在幀之間循環?」。然後,您在原始問題中輸入的所有代碼將會轉到答案。 –

回答

1

正如你已經冒昧發佈答案作爲一個問題。我想發表評論作爲答案,並建議您也許應該向TkDocs貢獻這一點(點擊他們的About tab,他們談論對網站的貢獻)。

我認爲如果該網站改善了更多的例子,而不是將本網站變成食譜,那會更好。我認爲你也可以貢獻於Active State recipes,他們似乎是Tcl/Tk火炬的載體,因此Tkinter的東西也很有意義。

+0

感謝您的好建議,我只是這樣做,並將代碼發送給Mark在TkDocs :) –

0

感謝您的工作 - 我將此作爲本示例的靈感來源,儘管內容極其輕便,但您可以在任意數量的窗口之間進行切換,這是一種很酷的方式。無論你想要什麼,你都可以移動下一個和後退按鈕的位置,將它們變成箭頭。

from tkinter import * 
master=Tk() 

class makeframe(object): 
    def __init__(self,i): 
     self.i=i 
     self.frame=Frame(master) 
     self.nextbutton=Button(self.frame,text='next',command=self.next) 
     self.nextbutton.grid(column=2,row=0) 
     self.backbutton=Button(self.frame,text='back',command=self.back) 
     self.backbutton.grid(column=0,row=0) 
     self.label=Label(self.frame,text='%i'%(self.i+1)).grid(column=1,row=0) 
    def next(self): 
     self.frame.grid_forget() 
     p[self.i+1].frame.grid() 
    def back(self): 
     self.frame.grid_forget() 
     p[self.i-1].frame.grid() 

n=7 
p=[0]*n 
for i in range(n): 
    p[i]=makeframe(i) 
p[0].frame.grid() 
p[0].backbutton.config(state=DISABLED) 
p[-1].nextbutton.config(state=DISABLED) 
相關問題