Диалоговые окна

Пакет tkinter содержит несколько модулей, предоставляющих доступ к уже готовым диалоговым окнам. Это окна различных сообщений, выбора по принципу "да-нет", открытия и сохранения файлов и др. В этом уроке рассмотрим примеры окон из модулей messagebox и filedialog пакета tkinter.

Модули пакета необходимо импортировать отдельно. То есть вы импортируете содержимое tkinter (например, from tkinter import *) и отдельно входящий в состав пакета tkinter модуль. Способы импорта на примере messagebox и пример вызова одной из функций модуля:

  • import tkinter.messageboxtkinter.messagebox.askyesno()

  • from tkinter.messagebox import *askyesno()

  • from tkinter import messageboxmessagebox.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 == True:
        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()

messagebox.askyesno()

Нажатие "Да" в диалоговом окне возвращает в программу True, "Нет" вернет False (также как закрытие окна через крестик). Таким образом в коде можно обработать выбор пользователя. В данном случае если последний соглашается, то данные переносятся из поля в метку.

Опции title и message являются позиционными, так что можно указывать только значения: askyesno("Вопрос", "Перенести данные?").

Подобные окна генерируются при использовании функции askokcancel() с надписями на кнопках "ОК" и "Отмена", askquestion() (возвращает не True или False, а строки 'yes' или 'no'), askretrycancel() ("Повторить", "Отмена"), askyesnocancel() ("Да", "Нет", "Отмена").

Другую группу составляют окна с одной кнопкой, которые служат для вывода сообщений различного характера. Это showerror(), showinfo() и showwarning().

def check():
    s = entry.get()
    if s.isdigit() == False:
        mb.showerror("Ошибка", "Должно быть введено число")
    else:
        entry.delete(0, END)
        label['text'] = s
… 

messagebox.showerror()

Модуль filedialog – диалоговые окна открытия и сохранения файлов

Рассмотрим две функции из модуля filedialog – askopenfilename() и asksaveasfilename(). Первая предоставляет диалоговое окно для открытия файла, вторая – для сохранения. Обе возвращают имя файла, который должен быть открыт или сохранен, но сами они его не открывают и не сохраняют. Делать это уже надо программными средствами самого Python.

from tkinter import *
from tkinter import filedialog as fd
 
def insertText():
    file_name = fd.askopenfilename()
    f = open(file_name)
    s = f.read()
    text.insert(1.0, s)
    f.close()
 
def extractText():
    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=insertText)
b1.grid(row=1, sticky=E)
b2 = Button(text="Сохранить", command=extractText)
b2.grid(row=1, column=1, sticky=W)
 
root.mainloop()

filedialog.asksaveasfilename()

Опция filetype позволяет перечислить типы файлов, которые будут сохраняться или открываться, и их расширения.

Примечание. В приведенном коде при размещении текстового поля методом grid() не указаны аргументы row и column. В таких случаях подразумевается, что их значениями являются нули.

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

В приведенной в уроке программе с функциями askopenfilename() и asksaveasfilename() генерируются исключения, если диалоговые окна были закрыты без выбора или указания имени файлов.

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

Добавьте кнопку "Очистить", которая удаляет текст из поля. Перед удалением пользователь должен подтвердить свои намерения через соответствующее диалоговое окно.

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

Комментарии

Практическая работа
from tkinter import *
from tkinter import messagebox as mb
from tkinter import filedialog as fd
def insert_text():
    try:
        file_name=fd.askopenfilename()
        f=open(file_name)
        s=f.read()
        text.insert(1.0,s)
        f.close()
    except FileNotFoundError:
        mb.showinfo("Внимание", "Файл не загружен")
 
def extract_text():
    try:
        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()
    except FileNotFoundError:
        mb.showinfo("Внимание", "Файл не сохранён")
 
def delete_text():
    answer=mb.askyesno("Подтверждение", message="Вы хотите удалить текст?")
    if answer==True:
        text.delete(0.0, END)             
 
root=Tk()
text=Text(width=50, height=25)
text.grid(columnspan=2)
Button(text="Открывать", command=insert_text).grid(row=1, sticky=E)
Button(text="Сохранить", command=extract_text).grid(row=1, column=1, sticky=W)
Button(text="Очистить", command=delete_text).grid(row=1, column=1)
root.mainloop()

Спасибо за урок)))
from tkinter import *
from tkinter import messagebox as mb
from tkinter import filedialog as fd
def openr():
    try:
        window=fd.askopenfilename()
        file=open(window)
        s=file.read()
        b.delete(0.0, END)
        b.insert(1.0,s)
        file.close()
    except:
        mb.showerror("Ошибка!", "Ошибка!")
def text_delete():
    delete=mb.askyesno(title="Вы уверены?", message="Вы уверены?")
    if delete==True:
        b.delete(0.0, END)
def save():
    try:
        window=fd.asksaveasfilename()
        file=open(window, "w")
        s=b.get(1.0, END)
        file.write(s)
        file.close()
    except:
        mb.showerror("Ошибка!", "Ошибка!")
root=Tk()
root.title("Редактор файлов")
a=Button(text="Выбрать файл", bg="yellow", command=openr)
b=Text(width=100,
       height=25,
       bg="darkgreen",
       fg="white",
       wrap=WORD)
c=Button(text="Очистить", bg="yellow", command=text_delete)
d=Button(text="Сохранить", bg="yellow", command=save)
a.pack()
b.pack()
c.pack()
d.pack()
root.mainloop()
<python>