1

我创建了自己的 Dialog 类版本,该类用作具有自定义字段的不同对话框窗口的父类。底部是 Dialog 类的代码。在其中一个对话框类型窗口中有一个组合框(下拉框),它允许用户也输入他们自己的值。如果他们输入自己的值(他们的名字)并且它不包含在客户列表中(来自文件),它会询问用户是否要添加新客户。如果他们选择是,我希望它将他们输入的名称传递给父窗口(应用程序的根),关闭他们输入名称的对话框,然后打开另一个对话框以输入新客户的信息(包含他们之前输入的名称)。除了向上传递值之外,这一切都有效。

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

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

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

内部子对话框:

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)

稍后在根对象中:

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]))
4

0 回答 0