2014-12-04 2 views
0

Я создаю графический интерфейс с двумя виджетами Toplevel и корневым фреймом, где я хочу, чтобы один из виджетов Toplevel был невидим, когда я запускаю графический интерфейс, но который можно сделать можно увидеть, нажав кнопку в корневом фрейме. Я могу вставить строку:Как создать виджет Toplevel и исчезнуть

win2.withdraw() 

в коде start_window (который строит весь GUI), который сделает Toplevel виджет невидимым, когда GUI инициализируется, но я не могу понять, как заново рисовать Виджет Toplevel, когда я хочу, чтобы он был видимым. Я ожидал, что команда:

win2.deiconify() 

для обеспечения требуемой функциональности, но я получаю следующее сообщение об ошибке при попытке это:

AttributeError: start_window instance has no attribute 'deiconify' 

Вот мой код, который при MainLoop() ред создает GUI. У меня есть два отдельных класса виджетов, которые я использую в этом коде, один для виджета ScrolledList, а второй для виджета ScrolledText. Виджет 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 

А вот команда MainLoop(), что intiates графический интерфейс:

start_window().mainloop() 

Итак, подведем итог, я ищу, чтобы начать свой графический интерфейс с невидимым Toplevel win2 виджета, но при нажатии на кнопку на корневой рамкой виджет Win2 можно сделать видимым. Если у кого-нибудь есть идеи о том, как это сделать, я был бы признателен за помощь.

ответ

0

Вы писали:

I expected the command: win2.deiconify() to provide the desired functionality but I get the following error message when I attempt this:

AttributeError: start_window instance has no attribute 'deiconify'

То, что вы говорите, и то, что сообщение об ошибке говорит две разные вещи. Вы не звоните win2.deiconify(), а скорее start_window.deiconify().

win2.deiconify() Действительно, как вы делаете невидимое окно верхнего уровня видимым, считая, что win2 является ссылкой на экземпляр Toplevel.

Решение включает сохранение ссылки на окно верхнего уровня, чтобы вы могли ссылаться на него в обратном вызове. Например:

класс start_window (Frame): Защиту INIT (я, родитель = None): ... self.win2 = Toplevel() ... БТН = Кнопка (я, текст = 'Make Widget Visible', command = self.win2.deiconify)

У вас есть еще одна тонкая ошибка в коде. Обратите внимание, что в исходном коде у вас есть command=self.win2.master.deiconif()). Атрибут command принимает ссылку на функцию. Вместо этого вы вызываете метод deiconify, и все, что возвращается, присваивается атрибуту command. У вас есть еще одно осложнение.win2 не имеет атрибута master.

Решение установить атрибут command в self.win2 (например: command=self.win2.deiconify))

+0

Здравствуйте, Спасибо за ваш ответ. Я понимаю, что start_window является подклассом Frame и, следовательно, (в соответствии с сообщением об ошибке) не имеет метода deiconify, я не понимаю, как это сделать, так это заставить метод deiconify работать в моей текущей настройке кода. Должен ли я не сделать свой класс start_window подклассом Frame? Спасибо за вашу помощь. С уважением, George – user3798654

+0

В сообщении об ошибке может быть сказано: «У экземпляра start_window нет атрибута« deiconify », но команда, которую я использую, -« command = win2.master.deiconify() »(основная часть - это опечатка, команда I am использование на самом деле win2.deiconify()). Поэтому я не понимаю, почему я указываю win2, но сообщение об ошибке указывает start_window. Верно, что кнопка/команда, которую я использую, находится в пределах start_window, но не возможно ли управлять одним аспектом Gui (в данном случае win2) из ​​корневого фрейма (в этом случае start_window подклассифицируется в Frame)? Я ценю вашу помощь. С уважением, George – user3798654

+0

@ user3798654: вы должны дважды проверить свой код. Ошибки Python обычно не лежат. Если он говорит, что есть ошибка с 'start_window.deiconify()', можно с уверенностью предположить, что именно этот код был вызван. –

Смежные вопросы