Tkinter之五

Dialog Windows

  可用wait_window来完成对话框。wait_window由自己的local event loop, 直到窗口销毁后才返回。

        widget.wait_window(window)

 
#File: dialog1.py



from Tkinter import *



class MyDialog:

    def __init__(self, parent):

        top = self.top = Toplevel(parent)

        Label(top, text = "Value").pack()

        self.e = Entry(top)

        self.e.pack(padx = 5)



        b = Button(top, text = "OK", command = self.ok)

        b.pack(pady = 5)



    def ok(self):

        print "value is", self.e.get()

        self.top.destroy()



root = Tk()

Button(root, text = "Hello!").pack()

root.update()



d = MyDialog(root)



root.wait_window(d.top)

  

分析如下:

         函数并没有调用root.mainloop()这个event loop,而是使用wait_windows()控制的local event loop。存在的问题:


   
   
  • root window仍然存在,并且显示dialog后,root window仍是active的。
  • 需要明确的点击entry field,才能拥有输入焦点,只有在按OK后,输入才有效,按Enter并没有效。
  • 可以运用WM_DELETE_WINDOW protocol来完成dialog window的撤销。

第一个问题可以用grab_set()来完成;第二个问题可以用focus_set()来设定text entry的输入焦点,并且需要绑定Enter键。

 

改进后的dialog:

from Tkinter import * import os class Dialog(Toplevel): def __init__(self, parent, title = None): Toplevel.__init__(self, parent) self.transient(parent) if title: self.title(title) self.parent = parent self.result = None body = Frame(self) self.initial_focus = self.body(body) body.pack(padx = 5, pady = 5) self.buttonbox() self.grab_set() if not self.initial_focus: self.initial_focus = self self.protocol("WM_DELETE_WINDOW", self.cancel) self.geometry("+%d+%d" % (parent.winfo_rootx() + 50, parent.weinfo_rooty() + 50)) self.initial_focus.focus_set() self.wait_window(self) def body(self, master): pass def buttonbox(self): box = Frame(self) w = Button(box, text = "OK", width = 10, command = self.ok, default = ACTIVE) w.pack(side = LEFT, padx = 5, pady = 5) w = Button(box, text = "Cancel", width = 10, command = self.cancel) w.pack(side = LEFT, padx = 5, pady = 5) self.bind("<Return>", self.ok) self.bind("<Escape>", self.cancel) box.pack() def ok(self, event = None): if not self.validate(): self.initial_focus.focus_set() return self.withdraw() self.update_idletasks() self.apply() self.cancel() def cancel(self, event = None): self.parent.focus_set() self.destroy() def validate(self): return 1 def apply(self): pass 其中,transient()用于将当前窗口和父窗口关联起来,grab_set()用于激发对话框模式,geometry()用于设定dialog相对于其父窗口的位置,focus_set()设置输入焦点,最后进入wait_window这个event loop.这样一来,便可以用上述类生成新的dialog类了

from Tkinter import * import tkSimpleDialog import string class MyDialog(tkSimpleDialog.Dialog): def body(self, master): Label(master, text = "First:").grid(row = 0) Label(master, text = "Second:").grid(row = 1) self.e1 = Entry(master) self.e2 = Entry(master) self.e1.grid(row = 0, column = 1) self.e2.grid(row = 1, column = 1) return self.e1 def apply(self): first = string.atoi(self.e1.get()) second = string.atoi(self.e2.get()) print first, second

 

Grid Layouts
         Grid manager将master widget分成2维的网格,可以用grid()来完成layout。其中的sticky表示对齐方式。而padx,pady则是为widget添加额外的空隙。
 
Validating Data

 可以用try/except来完成的对输入数据的验证。

def validate(self):        try:              first= int(self.e1.get())              second = int(self.e2.get())              self.result = first, second              return 1       except ValueError:            tkMessageBox.showwarning(              "Bad input",            "Illegal values, please try again"            )            return 0 def apply(self):        dosomething(self.result)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值