Найти - Пользователи
Полная версия: Скрыть окно Tkinter
Начало » GUI » Скрыть окно Tkinter
1
vanvanov
Использую messagebox, который, помимо диалога, создает пустое окно root . Для скрытия этого окна на форумах предлагается использовать root.withdraw(), но после этого я не всегда могу снова использовать окна Tkinter, потому что он ждет, пока я закрою скрытое окно root. Если же не скрывать пустые окна, они плодятся . Могу ли я как-нибудь по-другому избавиться от этого окна или полностью закрыть все окна Tkinter перед его повторным использованием?
Griffon
Возможно вы не хотите закрывать главное окно и потом заново его создавать. Возможно вы просто хотите скрывать и вновь отображать одно и то же главное окно, а что на нем отображается можно менять как вам угодно.
Если же вы действительно хотите то о чем просите, то вам просто необходимо использовать метод destroy экземпляра Tk (root в вашем случае). Но мне кажется что вы ставите задачу не совсем правильно.
4kpt
Griffon Вы абсолютно правы. Вопрос поставлен неккоректно.
Вопрос должен быть следующим:
“Каким образом удалить корневое окно, вывод которого скрыт методом .withdraw()?”
В результате имеет то, что окна размножаются при каждом вызове и естественно, обращение к ним блокируется.
Ну так удаляйте их. Кто за Вас это будет делать? Пример кода:
import Tkinter
import tkMessageBox
root = Tkinter.Tk()
root.withdraw()
mes = tkMessageBox.askyesno(message = "first question")
print mes
root.destroy()
root = Tkinter.Tk()
root.withdraw()
mes2 = tkMessageBox.askyesno(message = "second question")
print mes2
root.destroy()
root.mainloop()

P.S. Подход, построенный на удалении корневых окон изначально ущербен. Легче удалять не окна (а потом их заново создавать), а рамки в которые покуются все виджеты данного сеанса или страницы программы (как Вам будет удобно). Таким образом, корневое окно не будет мучаться, а виджеты будут скрываться. Кстати, есть еще альтернативный механизм - метод _forget() который скрывает рассположение рамки с упакованными виджетами. Если снова понадобиться, можно заново ее разместить :)

P.S.S. Надеюсь это оно…
vanvanov
4kpt
Ну так удаляйте их. Кто за Вас это будет делать?
Дело в следующем. У меня есть следующий код.
def ok_cancel(message):
	root=Tk()
	# Иначе будет показываться лишнее пустое окно
	root.withdraw()
	if messagebox.askokcancel('Подтвердите:',message):
		return True
	else:
		return False
	root.mainloop()
	root.destroy()
# Вернуть отредактированный текст 
def text_field_edit(title,array):
	root, res = Tk(), [None]
	def callback(): res[0] = txt.get(1.0,END); root.destroy()
	root.title(title)
	scrollbar = Scrollbar(root,jump=0)
	txt = Text(root,font="14",wrap=WORD,yscrollcommand=scrollbar.set)
	txt.insert(END,array)
	# Позволяет использовать мышь для управления скроллбаром
	scrollbar.config(command=txt.yview)
	scrollbar.pack(side=RIGHT,fill=Y)
	txt.pack()
	# Выход по клику кнопки
	ok = Button(root, text='Запомнить и выйти',command=callback)
	ok.pack()
	# Выход по нажатию Enter и Пробел на кнопке (навигация по Shift+Tab)
	ok.bind('<Return>', lambda e:callback())
	txt.focus_set()
	root.mainloop()
	if str(res[0])=='None' or str(res[0])==default_line_break:
		my_error(empty_field_error_msg)
	return res[0]
Я попеременно выполняю то ok_cancel, то text_field_edit. ok_cancel завершается нормально, но после text_field_edit остается пустое окно (в случае root.iconify()), а в случае withdraw скрипт перестает что-то делать. Где ошибка, я же делаю root.destroy() в text_field_edit тоже?
4kpt
Ответьте на один вопрос.
Зачем нужна эта строчка?
root.mainloop()
vanvanov
4kpt
Ответьте на один вопрос.Зачем нужна эта строчка?
Показывает окно?
4kpt
Неверно…
Разберитесь…
По Вашему коду. Поменяйте местами эти две строки:
root.mainloop()
root.destroy()

P.S. Я настоятельно не рекомендую использовать инструкцию from tkinter import*
vanvanov
4kpt
Неверно…Разберитесь…По Вашему коду. Поменяйте местами эти две строки:
Поменял. Осталось как раньше - окна messagebox нормально убиваются, а после text_field_edit остается пустое root-окно, хотя если использовать только text_field_edit, все завершается нормально. Куда в этой функции (text_field_edit) я могу поместить mainloop? Если до кнопок - кнопки не отображаются, если последней строкой - скрипт не сможет вернуть тот текст, который пользователь вводит в окно. Вырубаю в терминале
File "/usr/local/bin/main.py", line 785, in text_field_edit
root.mainloop()
File "/usr/lib/python3.1/tkinter/__init__.py", line 1012, in mainloop
self.tk.mainloop(n)
KeyboardInterrupt
Похоже да, какие-то проблемы именно с mainloop. Но где тогда он должен стоять? Разве где-то в другом месте?

Отвечая на ваш вопрос, mainloop - метод, запускающий цикл обработки событий.
Griffon
Подумайте об архитектуре вашего приложения.
Нет смысла десять раз создавать обьект Tk.

Разберитесь вот с этим:
# -*- coding: UTF-8 -*-
from Tkinter import *
import tkMessageBox as messagebox
from tkFont import Font
root = Tk()
root.withdraw()
yesno = messagebox.askokcancel("OMG", "Не нажмайте ОК!")
my_frame = Frame(root)
my_frame.pack()
my_label = Label(my_frame, text="Мы используем все то же главное окно!")
my_label.pack()
root.update_idletasks()
root.deiconify()
yesno = messagebox.askokcancel("OMG", "Удалить окно?")
root.withdraw()
my_frame.forget()
yesno = messagebox.askokcancel("OMG", "Новое окно?")
my_label.configure(text="Все тоже главное окно, тот же фрейм, та же надпись.")
my_frame.pack()
root.update_idletasks()
root.deiconify()
yesno = messagebox.askokcancel("OMG", "Может всетаки новое окно?")
my_frame.destroy()
my_frame = Frame(root)
my_frame.pack()
font = Font(family="Helvetica", size=16)
text = Text(my_frame, font=font)
text.pack()
text.insert(END, "Все новое - хорошо забытое старое.\n")
text.insert(END, "В нашем случае, это не пустые слова.")
Button(my_frame, text="Выход", command=root.destroy).pack()
root.mainloop()
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB