Как скрыть окно tkinter в python
Перейти к содержимому

Как скрыть окно tkinter в python

  • автор:

Окна в tkinter

В этом уроке рассмотрим основные настройки окон, в которых располагаются виджеты. Обычные окна в Tkinter порождаются не только от класса Tk , но и Toplevel . От Tk принято создавать главное окно. Если создается многооконное приложение, то остальные окна создаются от Toplevel. Методы обоих классов схожи.

Размер и положение окна

По умолчанию окно приложения появляется в верхнем левом углу экрана. Его размер (ширина и высота) определяется совокупностью размеров расположенных в нем виджетов. В случае если окно пустое, то tkinter устанавливает его размер в 200 на 200 пикселей.

С помощью метода geometry можно изменить как размер окна, так и его положение. Метод принимает строку определенного формата.

from tkinter import * root = Tk() root.geometry('600x400+200+100') root.mainloop()

Первые два числа в строке-аргументе geometry задают ширину и высоту окна. Вторая пара чисел обозначает смещение на экране по осям x и y . В примере окно размерностью 600 на 400 будет смещено от верхней левой точки экрана на 200 пикселей вправо и на 100 пикселей вниз.

Если перед обоими смещениями вместо плюса указывается минус, то расчет происходит от нижних правых углов экрана и окна. Так выражение root.geometry(‘600×400-0-0’) заставит окно появиться в нижнем правом углу.

В аргументе метода geometry можно не указывать либо размер, либо смещение. Например, чтобы сместить окно, но не менять его размер, следует написать root.geometry(‘+200+100’) .

Бывает удобно, чтобы окно появлялось в центре экрана. Методы winfo_screenwidth и winfo_screenheight возвращают количество пикселей экрана, на котором появляется окно. Рассмотрим, как поместить окно в центр, если размер окна известен:

from tkinter import * root = Tk() w = root.winfo_screenwidth() h = root.winfo_screenheight() w = w // 2 # середина экрана h = h // 2 w = w - 200 # смещение от середины h = h - 200 root.geometry(f'400x400++') root.mainloop()

Здесь мы вычитаем половину ширины и высоты окна (по 200 пикселей). Иначе в центре экрана окажется верхний левый угол окна, а не его середина.

Если размер окна неизвестен, то его можно получить с помощью того же метода geometry , но без аргументов. В этом случае метод возвращает строку, содержащую сведения о размерах и смещении, из которой можно извлечь ширину и высоту окна.

from tkinter import * root = Tk() Button(text="Button", width=20).pack() Label(text="Label", width=20, height=3).pack() Button(text="Button", width=20).pack() root.update_idletasks() s = root.geometry() s = s.split('+') s = s[0].split('x') width_root = int(s[0]) height_root = int(s[1]) w = root.winfo_screenwidth() h = root.winfo_screenheight() w = w // 2 h = h // 2 w = w - width_root // 2 h = h - height_root // 2 root.geometry('+<>+<>'.format(w, h)) root.mainloop()

Метод update_idletasks позволяет перезагрузить данные об окне после размещения на нем виджетов. Иначе geometry вернет строку, где ширина и высота равняются по одному пикселю. Видимо таковы параметры на момент запуска приложения.

По умолчанию пользователь может разворачивать окно на весь экран, а также изменять его размер, раздвигая границы. Эти возможности можно отключить с помощью метода resizable . Так root.resizable(False, False) запретит изменение размеров главного окна как по горизонтали, так и вертикали. Развернуть на весь экран его также будет невозможно, при этом соответствующая кнопка разворота исчезает.

resizable.png

Заголовок окна

По умолчанию в заголовке окна находится надпись «tk». Для установки собственного названия используется метод title .

… root.title("Главное окно")

root_title.png

Если необходимо, заголовок окна можно вообще убрать. В программе ниже второе окно ( Toplevel ) открывается при клике на кнопку, оно не имеет заголовка, так как к нему был применен метод overrideredirect с аргументом True . Через пять секунд данное окно закрывается методом destroy .

from tkinter import * def about(): a = Toplevel() a.geometry('200x150') a['bg'] = 'grey' a.overrideredirect(True) Label(a, text="About this").pack(expand=1) a.after(5000, lambda: a.destroy()) root = Tk() root.title("Главное окно") Button(text="Button", width=20).pack() Label(text="Label", width=20, height=3).pack() Button(text="About", width=20, command=about).pack() root.mainloop()

overrideredirect

Практическая работа

Напишите программу, в которой на главном окне находятся холст и кнопка «Добавить фигуру». Кнопка открывает второе окно, включающее четыре поля для ввода координат и две радиокнопки для выбора, рисовать ли на холсте прямоугольник или овал. Здесь же находится кнопка «Нарисовать», при клике на которую соответствующая фигура добавляется на холст, а второе окно закрывается. Проверку корректности ввода в поля можно опустить.

Программа на tkinter

Курс с примерами решений практических работ: pdf-версия

X Скрыть Наверх

Tkinter. Программирование GUI на Python

Как убрать окно tkinter

Как сделать так, чтобы при использовании модуля из tkinter не открывалось окно tkinter?
Как сделать так, чтобы при использовании модуля из tkinter не открывалось окно tkinter? Я пишу.

Как вывести изображение на окно в tkinter?
Как можно вывести изображение на окно в tkinter?

Как встроить терминал в окно tkinter на python3?
Допустим при нажатии кнопки, прямо в окне будет открываться терминал bash. И как можно будет.

Как в tkinter создать диалоговое окно с пользовательскими кнопками?
Я хотел бы узнать, как в Tkinter создать диалоговое окно, в котором количество кнопок и надписи на.

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

Как сделать, чтобы даже если окно tkinter открыто, программа всё равно работала
Когда работает tkinter(открыто окно tkinter’а, например время или калькулятор), цикл в программе.

Как в python tkinter при выводе содержимого entry в консоль убрать «.!»?
from tkinter import * from tkinter import messagebox def show(): print(entry) .

Tkinter — модальное окно
Имеется форма сделанная в Tkinter. Как вызвать вызвать из нее по нажатию кнопки модальное окно? К.

Парсер с выводом в окно tkinter
Пытаюсь написать парсер с выводом в окно tkinter, но в консоль выводит нормально такую строку.

Закрыть дочернее окно в tkinter
Скажите пожалуйста как закрыть дочернее окно в tkinter? Конечно можно использовать статичный.

Убрать консоль при компиляции Tkinter
Здравствуйте. задействована Tkinter для GUI При компиляции и запуске приложения .

Окно в Tkinter не видит методы в классе
В классе ‘Form’ реализован метод ‘Send_Message’, возникает проблема при реализации события, пытался.

Как скрыть окно tkinter в python

На этом шаге мы рассмотрим процесс создания таких окон .

Модальное вторичное окно , в отличие от обычного, при открытии блокирует все остальные окна приложения, в результате чего пользователь теряет доступ к ним. Остальные окна становятся доступными только после закрытия модального окна. Такие окна обычно применяются в качестве диалоговых окон для запроса каких-либо данных, необходимых для дальнейшей работы приложения.

К сожалению, библиотека Tkinter не предоставляет никаких инструментов для вывода модальных окон. Однако мы можем превратить обычное вторичное окно в модальное, вызвав у его контейнера или у него самого метод grab_set() (см. 11 шаг). Этот метод задает для контейнера или окна режим перехвата событий, в результате чего остальные окна перестают реагировать на действия пользователя. Как только окно, для которого был установлен перехват событий, закрывается и удаляется из памяти, перехват событий перестает работать, и остальные окна приложения становятся доступными для пользователя.

Есть еще один неприятный момент, связанный с реализацией модальных окон. Если после запуска приложения и вывода модального вторичного окна мы посмотрим на панель задач Windows , то увидим, что там присутствуют оба окна: и главное, и вторичное. Но присутствие модального окна на панели задач говорит о плохом стиле программирования. Чтобы скрыть вторичное окно, следует вызвать у него метод transient() (см. 21 шаг), передав ему ссылку на главное окно. Этот метод, в частности, отменит представление вторичного окна на панели задач.

Вот фрагмент кода контейнера, который превратит окно, в котором выведен, в модальное:

class Secondary(tkinter.ttk.Frame): def __init__(self, master=None): . . . . . self.master.transient(parent) self.grab_set()

В качестве примера давайте модифицируем приложение из предыдущего шага таким образом, чтобы выводимое им вторичное окно стало модальным. Текст ниже показывает исправленный код класса контейнера вторичного окна.

import tkinter import tkinter.ttk # Объявляем класс контейнера для вторичного окна class Secondary(tkinter.ttk.Frame): # Конструктор этого класса поддерживает дополнительный параметр # parent, с которым передается ссылка на главное окно. Она # понадобится нам, чтобы вывести занесенное значение в главном окне def __init__(self, master=None, parent=None): super().__init__(master) # Сохраним ссылку на главное окно в атрибуте self.parent = parent self.pack() self.create_widgets() self.master.title("Вторичное окно") self.master.transient(parent) self.grab_set() def create_widgets(self): self.varValue = tkinter.StringVar() self.varValue.set("Значение") entValue = tkinter.ttk.Entry(self, textvariable=self.varValue) entValue.pack() btnOK = tkinter.ttk.Button(self, text="OK", command=self.ok) btnOK.pack(side="left") btnCancel = tkinter.ttk.Button(self, text="Отмена", command=self.master.destroy) btnCancel.pack(side="right") def ok(self): self.parent.lblValue["text"] = self.varValue.get() self.master.destroy() def show_value(self): self.parent.lblValue["text"] = self.varValue.get() class Application(tkinter.ttk.Frame): def __init__(self, master=None): super().__init__(master) self.pack() self.create_widgets() self.master.title("Модальное вторичное окно") self.master.resizable(False, False) def create_widgets(self): btnShowWindow = tkinter.ttk.Button(self, text="Вывести окно", command=self.show_window) btnShowWindow.pack() # Опция width компонента Label задает ширину надписи # в символах текста self.lblValue = tkinter.ttk.Label(self, text="", width=50) self.lblValue.pack() def show_window(self): # Выводим вторичное окно, не забыв указать в параметре parent # конструктора ссыпку на главное окно Secondary(master=tkinter.Toplevel(), parent=self) root = tkinter.Tk() app = Application(master=root) root.mainloop()

Архив с файлом можно взять здесь.

Результат работы приложения приведен на рисунке 1.

Рис.1. Результат работы приложения

На следующем шаге мы рассмотрим управление жизненным циклом приложения .

Python-сообщество

[RSS Feed]

  • Начало
  • » GUI
  • » Скрыть окно Tkinter

#1 Апрель 1, 2013 13:39:03

vanvanov Зарегистрирован: 2013-03-31 Сообщения: 252 Репутация: 4 Профиль Отправить e-mail

Скрыть окно Tkinter

Использую messagebox, который, помимо диалога, создает пустое окно root . Для скрытия этого окна на форумах предлагается использовать root.withdraw(), но после этого я не всегда могу снова использовать окна Tkinter, потому что он ждет, пока я закрою скрытое окно root. Если же не скрывать пустые окна, они плодятся . Могу ли я как-нибудь по-другому избавиться от этого окна или полностью закрыть все окна Tkinter перед его повторным использованием?

#2 Апрель 1, 2013 20:38:55

Griffon От: Ukrain, Zaporozhie Зарегистрирован: 2009-03-04 Сообщения: 324 Репутация: 11 Профиль Отправить e-mail

Скрыть окно Tkinter

Возможно вы не хотите закрывать главное окно и потом заново его создавать. Возможно вы просто хотите скрывать и вновь отображать одно и то же главное окно, а что на нем отображается можно менять как вам угодно.
Если же вы действительно хотите то о чем просите, то вам просто необходимо использовать метод destroy экземпляра Tk (root в вашем случае). Но мне кажется что вы ставите задачу не совсем правильно.

#3 Апрель 2, 2013 00:11:09

4kpt От: Харьков Зарегистрирован: 2010-11-03 Сообщения: 998 Репутация: 63 Профиль Отправить e-mail

Скрыть окно Tkinter

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. Надеюсь это оно…

Отредактировано 4kpt (Апрель 2, 2013 01:09:16)

#4 Апрель 2, 2013 00:59:50

vanvanov Зарегистрирован: 2013-03-31 Сообщения: 252 Репутация: 4 Профиль Отправить e-mail

Скрыть окно Tkinter

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('', 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 тоже?

Отредактировано vanvanov (Апрель 2, 2013 01:04:14)

#5 Апрель 2, 2013 01:10:28

4kpt От: Харьков Зарегистрирован: 2010-11-03 Сообщения: 998 Репутация: 63 Профиль Отправить e-mail

Скрыть окно Tkinter

Ответьте на один вопрос.
Зачем нужна эта строчка?

root.mainloop() 

#6 Апрель 2, 2013 01:40:02

vanvanov Зарегистрирован: 2013-03-31 Сообщения: 252 Репутация: 4 Профиль Отправить e-mail

Скрыть окно Tkinter

4kpt
Ответьте на один вопрос.Зачем нужна эта строчка?

Показывает окно?

#7 Апрель 2, 2013 02:03:23

4kpt От: Харьков Зарегистрирован: 2010-11-03 Сообщения: 998 Репутация: 63 Профиль Отправить e-mail

Скрыть окно Tkinter

Неверно…
Разберитесь…
По Вашему коду. Поменяйте местами эти две строки:

root.mainloop() root.destroy() 

P.S. Я настоятельно не рекомендую использовать инструкцию from tkinter import*

Отредактировано 4kpt (Апрель 2, 2013 02:07:31)

#8 Апрель 2, 2013 03:25:19

vanvanov Зарегистрирован: 2013-03-31 Сообщения: 252 Репутация: 4 Профиль Отправить e-mail

Скрыть окно Tkinter

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 — метод, запускающий цикл обработки событий.

Отредактировано vanvanov (Апрель 2, 2013 03:26:15)

#9 Апрель 2, 2013 09:39:30

Griffon От: Ukrain, Zaporozhie Зарегистрирован: 2009-03-04 Сообщения: 324 Репутация: 11 Профиль Отправить e-mail

Скрыть окно Tkinter

Подумайте об архитектуре вашего приложения.
Нет смысла десять раз создавать обьект 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() 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *