2017-04-27 49 views
0

我開始做一個簡單的提示窗口,其中用戶將填寫目錄的名稱以抓取圖像以及保存結果.csv文件的位置(以及其他一些信息) 。不知道Tkinter類的結構和佈局

在按下回車鍵後(在這種情況下),我希望這個提示窗口關閉,主窗口將顯示用戶要執行的所有工作。

總之,這是開始爲我的GUI構建類的正確方法嗎?此外,爲什麼行:

frame = Frame(master, height=500,padx=20, pady=20) 

不改變這個初始窗口的格式/佈局?

我覺得一旦我對如何建立這個初始窗口有一個牢固的把握,我將有適當的基礎繼續自己休息。

#imports 
from Tkinter import * 
import glob 
from PIL import Image, ImageTk 
#end imports 

class prompt_window: 

    def __init__(self, master): 

     frame = Frame(master, height=500,padx=20, pady=20) 

     #Build prompt window labels 
     self.source_label = Label(root, text="Source Directory") 
     self.destination_label = Label(root, text="Destination Directory") 
     self.region_sz_label = Label(root, text="Region Size") 
     self.save_file_name_label = Label(root, text="Save File Name") 

     #Build prompt window entry forms 
     self.source_entry = Entry(root) 
     self.destination_entry = Entry(root) 
     self.region_sz_entry = Entry(root) 
     self.save_file_name_entry = Entry(root) 

     #Build enter button 
     self.enter_button = Button(root, text="Enter") 

     #Align labels in prompt window grid 
     self.source_label.grid(row=0) 
     self.destination_label.grid(row=1) 
     self.region_sz_label.grid(row=2) 
     self.save_file_name_label.grid(row=3) 

     #Align entry forms in prompt window grid 
     self.source_entry.grid(row=0, column=1) 
     self.destination_entry.grid(row=1, column=1) 
     self.region_sz_entry.grid(row=2, column=1) 
     self.save_file_name_entry.grid(row=3, column=1) 

     #Add button 
     self.enter_button.grid(row=4,column=2) 

#create root 
root = Tk() 

#create prompt window 
prompt = prompt_window(root) 

#run indefinitely 
root.mainloop() 
+1

您需要在'frame'上調用'.grid()',它可能應該是其他小部件而不是'root'的第一個參數。該類的名稱應該改爲'PromptWindow',以符合[PEP 8 - Python代碼樣式指南](https://www.python.org/dev/peps/pep-0008/)。 – martineau

+0

@martineau能否解釋爲什麼.grid()應該在框架上調用,以及它與維護正確的結構有何關係? –

+0

**如果您的代碼按預期方式正常工作且沒有任何錯誤**,並且您需要關於性能或代碼的建議,則可以在[CodeReview](https://codereview.stackexchange.com/)上發佈問題。當然,在發佈之前,請閱讀他們的旅遊網頁。 – Lafexlos

回答

0

你需要調用你的框架的佈局方法(.pack.grid,或.place)一個以使其可見。在我的程序版本中,我將類名從prompt_window更改爲PromptWindow,以符合PEP-8樣式指南。我也改變了Tkinter導入語句,所以我們不會用所有的Tkinter名稱來混淆我們的命名空間。

組織GUI代碼與組織一個普通的CLI程序有點不同。一旦我們定義了所有我們坐在一個循環中等待事件響應的事件。因此,對於這個程序,我們需要進行設置,以便在提示窗口關閉時打開主窗口並訪問由提示窗口收集的數據。

你說你想讓提示窗口成爲與主窗口不同的窗口,所以我們需要爲它創建一個窗口。 Tkinter程序只能有一個根窗口,所以我們創建一個Toplevel窗口來保存提示框。

您不需要將標籤保存爲PromptWindow實例的屬性,因爲您在創建PromptWindow實例後沒有對它們進行任何操作。

我已經改變了Entry小部件:我已經給每個人一個StringVar來保存他們的數據。這樣可以在提示窗口關閉後訪問該數據。當小部件的父窗口關閉時,您無法再訪問它。因此,不是將每個條目保存爲PromptWindow的屬性,而是保存關聯的StringVar。

當按下「Enter」按鈕或按下提示窗口的關閉窗口小部件時,我們關閉提示窗口並使主窗口可見。

我創建了一個簡單的MainWindow類,其中包含一個按鈕,讓我們可以打印由提示窗口收集的數據。

import Tkinter as tk 

class PromptWindow(object): 
    def __init__(self, master): 
     self.master = master 
     self.win = tk.Toplevel(master) 
     self.win.title("Prompt Window") 

     # Intercept close window events so that when the user closes this window 
     # (via the close widget or the Enter button) the main window reopens 
     self.win.protocol("WM_DELETE_WINDOW", self.close) 

     frame = tk.Frame(self.win, height=500,padx=20, pady=20) 
     frame.pack() 

     # Build prompt window labels 
     tk.Label(frame, text="Source Directory").grid(row=0) 
     tk.Label(frame, text="Destination Directory").grid(row=1) 
     tk.Label(frame, text="Region Size").grid(row=2) 
     tk.Label(frame, text="Save File Name").grid(row=3) 

     # Build prompt window entry widgets 
     self.source = tk.StringVar() 
     tk.Entry(frame, textvariable=self.source).grid(row=0, column=1) 

     self.destination = tk.StringVar() 
     tk.Entry(frame, textvariable=self.destination).grid(row=1, column=1) 

     self.region_sz = tk.StringVar() 
     tk.Entry(frame, textvariable=self.region_sz).grid(row=2, column=1) 

     self.save_file_name = tk.StringVar() 
     tk.Entry(frame, textvariable=self.save_file_name).grid(row=3, column=1) 

     # Build enter button 
     tk.Button(frame, text="Enter", command=self.close).grid(row=4,column=2) 

    def close(self): 
     # Close this window 
     self.win.destroy() 
     # Reopen the main window 
     self.master.deiconify() 

class MainWindow(object): 
    def __init__(self): 
     # Create root window 
     root = tk.Tk() 
     # and make it invisible 
     root.withdraw() 
     root.title("Main Window") 

     # Add some widgets 
     tk.Label(root, text="This is the main window").pack() 
     tk.Button(root, text="Show data", command=self.show_data).pack() 

     # Create prompt window 
     self.prompt = PromptWindow(root) 

     # Loop forever 
     root.mainloop() 

    # Display the data gathered by the prompt window 
    def show_data(self): 
     prompt = self.prompt 
     src = prompt.source.get() 
     dest = prompt.destination.get() 
     region = prompt.region_sz.get() 
     fname = prompt.save_file_name.get() 

     fmt = 'src: {!r}, dest: {!r}, region: {!r}, fname: {!r}' 
     print(fmt.format(src, dest, region, fname)) 

MainWindow()