如何使顶级窗口小部件显示和消失

时间:2014-12-04 14:07:44

标签: python python-2.7 tkinter

我正在创建一个具有两个Toplevel小部件和一个根框架的GUI,我希望其中一个Toplevel小部件在我启动GUI时不可见但可以通过单击根中的按钮来查看帧。我可以插入一行:

win2.withdraw()

在start_window代码中(构建整个GUI),这将使GUI初始化时Toplevel小部件不可见,但我无法弄清楚如何在我想要的时候重新绘制Toplevel小部件可见。我期待命令:

win2.deiconify()

提供所需的功能,但在尝试此操作时收到以下错误消息:

AttributeError: start_window instance has no attribute 'deiconify'

这是我的代码,在mainloop()编辑时创建GUI。我在此代码中使用了两个单独的窗口小部件类,一个用于ScrolledList窗口小部件,第二个用于ScrolledText窗口小部件。当我启动GUI然后通过单击根框架上的按钮使ScrolledText小部件可见时,我希望看不到ScrolledText小部件。

class start_window(Frame):
def __init__(self, parent=None):
    Frame.__init__(self, parent)
    #self.pa()
    Frame.pack(self)
    win1 = Toplevel()
    win2 = Toplevel()
    Label(self, text = 'Bioasys DataBase', width = 30).pack()
    btn = Button(self, text='Make Widget Visible', command=win2.master.deiconify())
    btn.pack(side=TOP)
    win1.title('Company Lookup')
    win2.title('Company Information')
    ScrolledList(win1).pack(side=TOP, fill=BOTH)

    #stock_sym = 'acad'

    #text1, text2 = create_company_information(stock_sym)


    try:
        stco_name = ScrolledText(win2, file=sys.argv[1], width= 50, height=15).pack()
    except IndexError:
        #text1 = 'Company Name - Company Symbol\n\nCompany URL\n\nCompany Address Line 1\nCompany Address Line 2\ncompany Address Line 3\nCompany Address Line 4'
        stco_name = ScrolledText(win2, text= text1, width= 50, height=15).pack()

    try:
        stco_sym = ScrolledText(win2,file=sys.argv[1], width=50, height=15).pack()
    except IndexError:
        #text2 = 'Company Description'
        stco_sym = ScrolledText(win2, text= text2, width=50, height=15).pack()

    win2.withdraw()  # makes the win2 frame invisible at startup
    #win2.pack_forget()
    #win2.master.deiconify()

以下是两个不同的Toplevel小部件的代码,这些小部件类都能正常工作。我包含此代码,以便可以使start_window类正常运行。

class ScrolledList(Frame):
def __init__(self, parent=None):
    Frame.__init__(self, parent)
    self.pack(expand=YES, fill=BOTH)
    self.makeWidgets()
def handleList(self, event):
    index = self.listbox.curselection()
    label = self.listbox.get(index)
    self.runCommand(label)
def fetch(self):
    print 'Input => "%s"' % self.ent.get()

def makeWidgets(self):
    self.ent = Entry(self)
    btn = Button(self, text='ENTER', command=self.fetch)
    sbar = Scrollbar(self)
    list = Listbox(self, relief=SUNKEN)
    self.ent.insert(0, 'Type Stock Symbol Here')
    self.ent.pack(side=TOP, fill=X)
    self.ent.focus()
    self.ent.bind('<Return>', (lambda event: self.fetch()))
    value = self.ent.get()
    btn.pack(side=TOP)
    sbar.config(command=list.yview)
    list.config(yscrollcommand=sbar.set)
    sbar.pack(side=RIGHT, fill=Y)
    list.pack(side=LEFT, expand=YES, fill=BOTH)
    options_init = open_pickled_company_list()  #
    options = [i[1] for i in options_init]      #
    for label in options:
        list.insert('end', label)
    #list.config(selectmode=SINGLE, setgrid=1)
    list.bind('<Double-1>', self.handleList)
    self.listbox = list


def runCommand(self, selection):
    print 'You selected: ', selection
    self.ent.delete(0, END)
    self.ent.insert(0, selection)



class ScrolledText(Frame):
def __init__(self, parent=None, text='', file=None, width='', height=''):
    Frame.__init__(self, parent)
    self.pack(expand=YES, fill=BOTH)                # make me expandable
    self.width = width
    self.height = height
    self.makewidgets()
    self.settext(text, file)
def makewidgets(self):
    sbar = Scrollbar(self)
    text = Text(self, relief=SUNKEN, width=self.width, height=self.height)
    sbar.config(command=text.yview)                  # xlink sbar and text
    text.config(yscrollcommand=sbar.set)             # move one moves other
    sbar.pack(side=RIGHT, fill=Y)                    # pack first=clip last
    text.pack(side=LEFT, expand=YES, fill=BOTH)      # text clipped first
    self.text = text
def settext(self, text='', file=None):
    if file: 
        text = open(file, 'r').read()
    self.text.delete('1.0', END)                     # delete current text
    self.text.insert('1.0', text)                    # add at line 1, col 0
    self.text.mark_set(INSERT, '1.0')                # set insert cursor
    self.text.focus()                                # save user a click
def gettext(self):                                   # returns a string
    return self.text.get('1.0', END+'-1c')           # first through last

这是启动GUI的mainloop()命令:

start_window().mainloop()

总而言之,我希望用一个看不见的Toplevel Win2小部件启动我的GUI,但是通过单击根框架上的按钮,可以使Win2小部件可见。如果有人对如何实现这一点有任何想法,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

您写道:

  

我希望命令:win2.deiconify()能够提供所需的命令   功能,但我尝试时收到以下错误消息   这样:

     

AttributeError:start_window实例没有属性&#39; deiconify&#39;

您所说的内容以及错误消息所说的是两件不同的事情。您不是在呼叫win2.deiconify()而是呼叫start_window.deiconify()

假设win2.deiconify()是对win2实例的引用,

Toplevel确实是如何使一个不可见的顶层窗口可见。

解决方案涉及保存对顶层窗口的引用,以便您可以在回调中引用它。例如:

class start_window(Frame):     def init (self,parent = None):         ...         self.win2 = Toplevel()         ...         btn =按钮(自我,文字=&#39;使小工具可见&#39;,命令= self.win2.deiconify)

您的代码中还有另一个微妙的错误。请注意,在原始代码中,您有command=self.win2.master.deiconif())command属性接受对函数的引用。相反,您正在调用deiconify方法,并且返回的任何内容都将分配给command属性。你还有一个复杂的问题,即self.win2没有master属性。

解决方法是将command属性设置为self.win2(例如:command=self.win2.deiconify)