Диалоговые окна
Пакет tkinter содержит несколько модулей, предоставляющих доступ к уже готовым диалоговым окнам. Это окна различных сообщений, выбора по принципу «да-нет», открытия и сохранения файлов и др. В этом уроке рассмотрим примеры окон из модулей messagebox и filedialog пакета tkinter .
Модули пакета необходимо импортировать отдельно. То есть вы импортируете содержимое tkinter (например, from tkinter import * ) и отдельно входящий в состав пакета tkinter модуль. Способы импорта на примере messagebox и пример вызова одной из функций модуля:
- import tkinter.messagebox → tkinter.messagebox.askyesno()
- from tkinter.messagebox import * → askyesno()
- from tkinter import messagebox → messagebox.askyesno()
- from tkinter import messagebox as mb (вместо mb может быть любой идентификатор) → mb.askyesno()
В уроке мы будем использовать последний вариант.
Модуль messagebox – стандартные диалоговые окна
Окно выбора «да» или «нет» – askyesno :
from tkinter import * from tkinter import messagebox as mb def check(): answer = mb.askyesno(title="Вопрос", message="Перенести данные?") if answer: s = entry.get() entry.delete(0, END) label['text'] = s root = Tk() entry = Entry() entry.pack(pady=10) Button(text='Передать', command=check).pack() label = Label(height=3) label.pack() root.mainloop()
Нажатие «Да» в диалоговом окне возвращает в программу True , «Нет» вернет False (также как закрытие окна через крестик). Таким образом в коде можно обработать выбор пользователя. В данном случае если последний соглашается, то данные переносятся из поля в метку.
Опции title и message являются позиционными, так что можно указывать только значения: askyesno(«Вопрос», «Перенести данные?») .
Подобные окна генерируются при использовании функции askokcancel с надписями на кнопках «ОК» и «Отмена», askquestion (возвращает не True или False , а строки ‘yes’ или ‘no’), askretrycancel («Повторить», «Отмена»), askyesnocancel («Да», «Нет», «Отмена»).
Другую группу составляют окна с одной кнопкой, которые служат для вывода сообщений различного характера. Это showerror , showinfo и showwarning .
from tkinter import * from tkinter import messagebox as mb def check(): s = entry.get() if not s.isdigit(): mb.showerror("Ошибка", "Должно быть введено число") else: entry.delete(0, END) label['text'] = s root = Tk() entry = Entry() entry.pack(pady=10) Button(text='Передать', command=check).pack() label = Label(height=3) label.pack() root.mainloop()
Модуль filedialog – диалоговые окна открытия и сохранения файлов
Рассмотрим две функции из модуля filedialog – askopenfilename и asksaveasfilename . Первая предоставляет диалоговое окно для открытия файла, вторая – для сохранения. Обе возвращают имя файла, который должен быть открыт или сохранен, но сами они его не открывают и не сохраняют. Делать это уже надо программными средствами самого Python.
from tkinter import * from tkinter import filedialog as fd def insert_text(): file_name = fd.askopenfilename() f = open(file_name) s = f.read() text.insert(1.0, s) f.close() def extract_text(): file_name = fd.asksaveasfilename( filetypes=(("TXT files", "*.txt"), ("HTML files", "*.html;*.htm"), ("All files", "*.*"))) f = open(file_name, 'w') s = text.get(1.0, END) f.write(s) f.close() root = Tk() text = Text(width=50, height=25) text.grid(columnspan=2) b1 = Button(text="Открыть", command=insert_text) b1.grid(row=1, sticky=E) b2 = Button(text="Сохранить", command=extract_text) b2.grid(row=1, column=1, sticky=W) root.mainloop()
Опция filetype позволяет перечислить типы файлов, которые будут сохраняться или открываться, и их расширения.
Примечание. В приведенном коде при размещении текстового поля методом grid не указаны аргументы row и column . В таких случаях подразумевается, что их значениями являются нули.
Практическая работа
В приведенной в уроке программе с функциями askopenfilename и asksaveasfilename генерируются исключения, если диалоговые окна были закрыты без выбора или указания имени файлов.
Напишите код обработки данных исключений. При этом для пользователя должно появляться информационное диалоговое окно с сообщением о том, что файл не загружен или не сохранен.
Добавьте кнопку «Очистить», которая удаляет текст из поля. Перед удалением пользователь должен подтвердить свои намерения через соответствующее диалоговое окно.
Курс с примерами решений практических работ: pdf-версия
X Скрыть Наверх
Tkinter. Программирование GUI на Python
6. Tkinter. Диалоговые окна¶
Диалоговые окна, как элементы графического интерфейса, предназначены для вывода сообщений пользователю, получения от него какой-либо информации, а также управления.
Создадим свое диалоговое окно. Для примера оно создается используя несколько виджетов:
from tkinter import * window = Tk() window.title("Message box title") window.geometry("300x75") lbl = Label(window, text="My message content!") btn = Button(window, text="Ok", width=10, command=window.destroy) lbl.pack() btn.pack(side=RIGHT) window.mainloop()
Мы получили простейшее диалоговое окно, и хотя диалоговые окна весьма разнообразны, их вид уже устоялся. Нет необходимости создавать диалоговые окна с нуля, для это можно использовать «заготовки».
6.2. Messagebox — окно с информацией¶
Для информирования пользователя о процессах происходящих в ПК можно использовать Messagebox — окно с информацией. При этом требуется дополнительно импортировать «подмодуль» Tkinter — tkinter messagbox, в котором описаны классы для окон данного типа.
Код созданного информационного окна может быть следующим:
from tkinter import messagebox messagebox.showinfo('Message title', 'Message info content')
Для привлечения внимания можно использовать окно предупреждения:
from tkinter import messagebox messagebox.showwarning('Message warning title', 'Message warning content') #shows warning message
Окно с возникшей ошибкой ПО думаю встречал каждый, на питоне его можно создать, написав следующий код:
from tkinter import messagebox messagebox.showerror('Message error title', 'Message error content') #shows error message
6.3. Messagebox — окно с вопросом¶
Следующие примеры диалоговых окон, служат для ведения диалога с пользователем и сохранением его ответа в переменной. Попробуйте создать следующие примеры диалоговых окон, подумайте об их различий и где они могут применяться? Напишите комментарий в коде к каждому диалоговому окну:
from tkinter import messagebox res = messagebox.askquestion('Message title', 'Message ask content') res = messagebox.askyesno('Message title', 'Message y/n content') res = messagebox.askyesnocancel('Message title', 'Message y/n/cancel content') res = messagebox.askokcancel('Message title', 'Message ok/cancel content') res = messagebox.askretrycancel('Message title', 'Message retry/cancel content')
6.4. Окна открытия и сохранения файлов¶
Рассмотрим, как запрограммировать с помощью Tkinter вызов диалоговых окон открытия и сохранения файлов и работу с ними. При этом требуется дополнительно импортировать «подмодуль» Tkinter — tkinter.filedialog, в котором описаны классы для окон данного типа:
from tkinter import * from tkinter.filedialog import * root = Tk() op = askopenfilename() sa = asksaveasfilename() root.mainloop()
Здесь создаются два объекта (op и sa): один вызывает диалоговое окно «Открыть», а другой «Сохранить как…». При выполнении скрипта, они друг за другом выводятся на экран после появления главного окна. Если не создать root, то оно все-равно появится на экране, однако при попытке его закрытия в конце возникнет ошибка.
Оглавление
- 6. Tkinter. Диалоговые окна
- 6.1. Создание диалогового окна
- 6.2. Messagebox — окно с информацией
- 6.3. Messagebox — окно с вопросом
- 6.4. Окна открытия и сохранения файлов
Tkinter как сделать всплывающее окно
Tkinter обладает рядом встроенных диалоговых окон для различных задач. Рассмотрим некоторые из них.
filedialog
Модуль filedialog предоставляет функциональность файловых диалоговых окон, которые позволяют выбрать файл или каталог для различных задач. В частности в модуле для работы с файлами определены следующие функции:
- askopenfilename() : открывает диалоговое окно для выбора файла и возвращает путь к выбранному файлу. Если файл не выбран, возвращается пустая строка «»
- askopenfilenames() : открывает диалоговое окно для выбора файлов и возвращает список путей к выбранным файлам. Если файл не выбран, возвращается пустая строка «»
- asksaveasfilename() : открывает диалоговое окно для сохранения файла и возвращает путь к сохраненному файлу. Если файл не выбран, возвращается пустая строка «»
- asksaveasfile() : открывает диалоговое окно для сохранения файла и возвращает сохраненный файл. Если файл не выбран, возвращается None
- askdirectory() : открывает диалоговое окно для выбора каталога и возвращает путь к выбранному каталогу. Если файл не выбран, возвращается пустая строка «»
- askopenfile() : открывает диалоговое окно для выбора файла и возвращает выбранный файл. Если файл не выбран, возвращается None
- askopenfiles() : открывает диалоговое окно для выбора файлов и возвращает список выбранных файлов
Рассмотрим открытие и сохранение файла на примере:
from tkinter import * from tkinter import ttk from tkinter import filedialog root = Tk() root.title("METANIT.COM") root.geometry("250x200") root.grid_rowconfigure(index=0, weight=1) root.grid_columnconfigure(index=0, weight=1) root.grid_columnconfigure(index=1, weight=1) text_editor = Text() text_editor.grid(column=0, columnspan=2, row=0) # открываем файл в текстовое поле def open_file(): filepath = filedialog.askopenfilename() if filepath != "": with open(filepath, "r") as file: text =file.read() text_editor.delete("1.0", END) text_editor.insert("1.0", text) # сохраняем текст из текстового поля в файл def save_file(): filepath = filedialog.asksaveasfilename() if filepath != "": text = text_editor.get("1.0", END) with open(filepath, "w") as file: file.write(text) open_button = ttk.Button(text="Открыть файл", command=open_file) open_button.grid(column=0, row=1, sticky=NSEW, padx=10) save_button = ttk.Button(text="Сохранить файл", command=save_file) save_button.grid(column=1, row=1, sticky=NSEW, padx=10) root.mainloop()
Здесь определены две кнопки. По нажатию по на кнопку open_button вызывается функция filedialog.askopenfilename() . Она возвращает путь к выбранному файлу. И если в диалоговом окне не нажата кнопка отмены (то есть путь к файлу не равен пустой строке), то считываем содержимое текстового файла и добавляем его в виджет Text
def open_file(): filepath = filedialog.askopenfilename() if filepath != "": with open(filepath, "r") as file: text =file.read() text_editor.delete("1.0", END) text_editor.insert("1.0", text)
По нажатию на кнопку save_button срабатывает функция filedialog.asksaveasfilename() , которая возвращает путь к файлу для сохранения текста из виджета Text. И если файл выбран, то открываем его и сохраняем в него текст:
def save_file(): filepath = filedialog.asksaveasfilename() if filepath != "": text = text_editor.get("1.0", END) with open(filepath, "w") as file: file.write(text)
Эти функции могут принимать ряд параметров:
- confirmoverwrite : нужно ли подтверждение для перезаписи файла (для диалогового окна сохранения файла)
- defaultextension : расширение по умолчанию
- filetypes : шаблоны типов файлов
- initialdir : стартовый каталог, который открывается в окне
- initialfile : файл по умолчанию
- title : заголовок диалогового окна
- typevariable : переменная, к которой привязан выбранный файл
filedialog.askopenfiles(title="Выбор файла", initialdir="D://tkinter", defaultextension="txt", initialfile="hello.txt")
Выбор шрифта
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") label = ttk.Label(text="Hello World") label.pack(anchor=NW, padx=10, pady=10) def font_changed(font): label["font"] = font def select_font(): root.tk.call("tk", "fontchooser", "configure", "-font", label["font"], "-command", root.register(font_changed)) root.tk.call("tk", "fontchooser", "show") open_button = ttk.Button(text="Выбрать шрифт", command=select_font) open_button.pack(anchor=NW, padx=10, pady=10) root.mainloop()
По нажатию на кнопку вызывается функция select_font, в которой вначале производится настройка диалогового окна установки шрифта
root.tk.call("tk", "fontchooser", "configure", "-font", label["font"], "-command", root.register(font_changed))
В частности, значение «configure» указывает, что в данном случае производится настройка диалогового окна. Аргумент «-font» указывает, что следующее значение представляет настройка шрифта, который будет выбран в диалоговом окне по умолчанию. В качестве такового здесь используется шрифт метки label.
Аргумент «-command» указывает, что дальше идет определение функции, которая будет срабатывать при выборе шрифта. Здесь такой функцией является функция font_changed . Функция выбора шрифта должна принимать один параметр — через него будет передаваться выбранный шрифт. В данном случае просто переустанавливаем шрифт метки.
Для отображения окна выбора шрифта выполняется вызов
root.tk.call("tk", "fontchooser", "show")
Таким образом, при нажатии на кнопку откроется окно выбора шрифта, а после его выбора он будет применен к метке:
Выбор цвета
Для выбора цвета применяется функции из модуля colorchooser.askcolor() :
from tkinter import * from tkinter import ttk from tkinter import colorchooser root = Tk() root.title("METANIT.COM") root.geometry("250x200") label = ttk.Label(text="Hello World") label.pack(anchor=NW, padx=10, pady=10) def select_color(): result = colorchooser.askcolor(initialcolor="black") label["foreground"] = result[1] open_button = ttk.Button(text="Выбрать цвет", command=select_color) open_button.pack(anchor=NW, padx=10, pady=10) root.mainloop()
Здесь по нажатию на кнопку вызывается функция select_color. В этой функции вызывается функция colorchooser.askcolor . С помощью параметра initialcolor устанавливаем цвет, который выбран по умолчанию в диалоговом окне. В данном случае это черный цвет («black»)
Результатом функции является кортеж с определениями выбранного цвета. Например, для красного цвета кортеж будет выглядеть следующим образом: ((255, 0, 0), «#ff0000») . То есть, обратившись к второму элементу кортежа, можно получить шестнадцатиричное значение цвета. Здесь выбранный цвет применяется для установки цвета шрифта метки:
label["foreground"] = result[1]
Как в Tkinter сделать так, чтобы одновременно могло быть открыто лишь одно такое окно?
К примеру всплывающие окна. Как сделать, чтобы при нажатии это окно не открывалось, если уже открыта его копия?
- Добавляете в ваш класс булевую переменную, например: popup_init: bool = False ,
- В методе, который открывает попап проверяете значение данной переменной, и не даёте открыть его повторно или деактивируете клавишу поп-апа если значение is False .
- При нажатии на клавишу открытия поп-апа или при закрытии его меняете значение переменной.
Отслеживать
ответ дан 28 мар 2021 в 18:40
Andrew Holovko Andrew Holovko
1,058 5 5 серебряных знаков 13 13 бронзовых знаков
Если несложно,прикрепите пожалуйста реальный пример,просто ниразу не использовал popup
28 мар 2021 в 19:03
Формируйте вопрос таким образом, чтобы было понятно что вы ждёте.
28 мар 2021 в 19:15
Отредачил вопрос
28 мар 2021 в 19:26
По прежнему мой ответ — совпадает с вашим вопросом)
31 мар 2021 в 7:56В итоге, в коде можно использовать способ о котором сказал Андрей,но как по мне, проще просто зафокусить окно с помощью:
root.grab_set()
root.focus_get()