将值从对话框传递到其父窗口

时间:2013-08-02 12:12:58

标签: python python-2.7 tkinter

我创建了自己的Dialog类版本,该类用作具有自定义字段的不同对话框窗口的父类。底部是Dialog类的代码。在其中一个Dialog类型的窗口中有一个Combobox(下拉框),允许用户输入自己的值。如果他们输入自己的值(他们的名字)并且它没有包含在客户列表中(来自文件),它会询问用户是否要添加新客户。如果他们选择是,我希望它将他们输入的名称传递给父窗口(应用程序的根目录),关闭他们输入名称的对话框,然后打开另一个对话框输入新客户的信息(包含他们之前输入的名字)。除了传递价值之外,其中的每个部分都有效。起初我尝试使用自定义异常传递值,由于Tkinter如何处理异常,因此无效。

我应该如何传递此值?我最初的想法是通过自定义Tkinter事件。我找不到有关如何做到这一点的信息。

创建第一个子对话框的Root方法:

def check_in(self):
    log_diag = LoggerDialog(self,self.customers)
    try:
        log_diag.show()
    except NewCustomerException, (instance):
        self.new_customer(str(instance))
    except:
        print instance

Inside Child对话框:

def new_customer_error(self):
    #parse name and preset values in the new customer dialog
    name = self.name.get()

    if askquestion(title="New Customer?",
        message="Add new customer: " + name,
        parent = self.root) == 'yes':
        raise NewCustomerException(name)

对话类:

class Dialog:
    def __init__(self, master, title, class_=None, relx=0.5, rely=0.3):
        self.master = master
        self.title = title
        self.class_ = class_
        self.relx = relx
        self.rely = rely

    def setup(self):
        if self.class_:
            self.root = Toplevel(self.master, class_=self.class_)
        else:
            self.root = Toplevel(self.master)

        self.root.title(self.title)
        self.root.iconname(self.title)

    def enable(self):
        ### enable
        self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)
        self._set_transient(self.relx, self.rely)
        self.root.wait_visibility()
        self.root.grab_set()
        self.root.mainloop()
        self.root.destroy()

    def _set_transient(self, relx=0.5, rely=0.3):
        widget = self.root
        widget.withdraw() # Remain invisible while we figure out the geometry
        widget.transient(self.master)
        widget.update_idletasks() # Actualize geometry information
        if self.master.winfo_ismapped():
            m_width = self.master.winfo_width()
            m_height = self.master.winfo_height()
            m_x = self.master.winfo_rootx()
            m_y = self.master.winfo_rooty()
        else:
            m_width = self.master.winfo_screenwidth()
            m_height = self.master.winfo_screenheight()
            m_x = m_y = 0
        w_width = widget.winfo_reqwidth()
        w_height = widget.winfo_reqheight()
        x = m_x + (m_width - w_width) * relx
        y = m_y + (m_height - w_height) * rely
        if x+w_width > self.master.winfo_screenwidth():
            x = self.master.winfo_screenwidth() - w_width
        elif x < 0:
            x = 0
        if y+w_height > self.master.winfo_screenheight():
            y = self.master.winfo_screenheight() - w_height
        elif y < 0:
            y = 0
        widget.geometry("+%d+%d" % (x, y))
        widget.deiconify() # Become visible at the desired location

    def wm_delete_window(self):
        self.root.quit() 

我尝试使用generate_event()并传递自定义参数(名称),我收到此错误:

TclError: bad option "-name": must be -when, -above, -borderwidth, 
-button, -count, -data, -delta, -detail, -focus, -height, -keycode, 
-keysym, -mode, -override, -place, -root, -rootx, -rooty, -sendevent, 
-serial, -state, -subwindow, -time, -warp, -width, -window, -x, or -y

我已经尝试重写其中一些的价值,并且我不断收到错误,告诉我我传的错误类型。 (mode是一个int,detail必须是特定对象列表的一个实例)这似乎不是一个非常优雅的解决方案。

以下是我确定的解决方案:

子对象中的代码(用于处理不在数据库中的名称):

def new_customer_error(self):

    if askquestion(title="New Customer?",
        message="Add new customer: " + self.name.get(),
        parent = self.root) == 'yes':
        self.master.event_generate('<<NewCustomer>>')

__init__根窗口中: self.bind('<<NewCustomer>>',self.new_customer)

稍后在root对象中:

def new_customer(self, event=None):
    #if evert this came as a new customer entry through check in
    if event:
        temp = self.logger_diag.name.get().split(' ')
        self.newc_diag.fname.set(temp[0])
        if len(temp) == 2:
            self.newc_diag.lname.set(temp[1])
        elif len(temp) == 3:
            self.newc_diag.mname.set(temp[1])
            self.newc_diag.lname.set(temp[2])
        elif len(temp) > 3:
            self.newc_diag.mname.set(temp[1])
            self.newc_diag.lname.set(' '.join(temp[2:4]))

0 个答案:

没有答案