不确定Tkinter类的结构和布局

时间:2017-04-27 01:09:31

标签: python class user-interface tkinter

我首先创建一个简单的提示窗口,用户将填写目录名称以从中获取图像以及保存结果.csv文件的位置(以及其他一些信息)。

按下Enter键(在这种情况下)我希望此提示窗口关闭,主窗口将显示用户将要执行的所有工作。

简而言之,这是开始为我的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 个答案:

答案 0 :(得分:0)

您需要在框架上调用其中一种布局方法(.pack.grid.place)以使其可见。在我的程序版本中,我已将类名从prompt_window更改为PromptWindow以符合PEP-8样式指南。我还更改了Tkinter import语句,因此我们不会使用所有这些Tkinter名称来混淆我们的命名空间。

组织GUI代码与组织普通CLI程序略有不同。一旦我们定义了所有内容,我们就会坐在循环中等待事件响应。因此,对于这个程序,我们需要进行设置,以便当提示窗口关闭时,主窗口打开,并且它可以访问提示窗口收集的数据。

你说你想让提示窗口成为主窗口的不同窗口,所以我们需要为它创建一个窗口。 Tkinter程序只能有一个根窗口,因此我们创建一个Toplevel窗口来保存提示框。

您不需要将标签保存为PromptWindow实例的属性,因为您在创建它们后没有对它们执行任何操作。

我稍微更改了Entry小部件:我给它们每个都有一个StringVar来保存它们的数据。这使得在关闭提示窗口后可以访问该数据。当窗口小部件的父窗口关闭时,您无法再访问它。因此,我们不是将每个Entry保存为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()