Tkinter. Диалоговые (всплывающие) окна

Диалоговые окна – важнейшая составляющая взаимодействия приложения с пользователем. С ними вы сталкиваетесь в самых разных ситуациях: когда разрешаете программе определять ваше местоположение, когда подтверждаете свой возраст и в ряде других ситуаций.

Диалоговые окна в Python реализуются с помощью нескольких методов, каждый из которых отвечает за определенный блок. Сами диалоговые окна тоже бывают разными: уведомления, вопросительные, выбора файлов и так далее. Рассмотрим сегодня все тонкости работы с окнами в Python.

Окна уведомлений

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

Окна уведомлений разделяются на три типа: информационные, с предупреждением и с ошибкой. Продемонстрируем механизм их работы на примере такой программы.Tkinter. Диалоговые (всплывающие) окна

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

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

Обратите внимание! При запуске каждое окно будет воспроизводить соответствующий его типу звук. А в зависимости от языка системы будет отличаться текст метки.

Чтобы вызвать стандартное информационное окно, используется метод showinfo. Для вызова предупреждения применим метод showwarning, а для получения ошибки используем showerror.

Когда будете просматривать этот код, обратите внимание: перед использованием всех этих методов необходимо импортировать модуль tkinter.messagebox, а потом вызывать метод непосредственно из того объекта, в котором расположена кнопка. Для этого используется команда self.show_{тип оповещения}.

import tkinter as tk

import tkinter.messagebox as mb

 

class App(tk.Tk):

    def __init__(self):

        super().__init__()

        btn_info = tk.Button(self, text=»Информационное окно»,

                             command=self.show_info)

        btn_warn = tk.Button(self, text=»Окно с предупреждением»,

                             command=self.show_warning)

        btn_error = tk.Button(self, text=»Окно с ошибкой»,

                              command=self.show_error)

 

        opts = {‘padx’: 40, ‘pady’: 5, ‘expand’: True, ‘fill’: tk.BOTH}

        btn_info.pack(**opts)

        btn_warn.pack(**opts)

        btn_error.pack(**opts)

 

    def show_info(self):

        msg = «Ваши настройки сохранены»

        mb.showinfo(«Информация», msg)

 

    def show_warning(self):

        msg = «Временные файлы удалены не правильно»

        mb.showwarning(«Предупреждение», msg)

 

    def show_error(self):

        msg = «Приложение обнаружило неизвестную ошибку»

        mb.showerror(«Ошибка», msg)

 

if __name__ == «__main__»:

    app = App()

    app.mainloop()

Принцип работы окон с уведомлениями

Итак, мы сперва импортируем модуль tkinter.messagebox, а для его задаем алиас mb. Если используется Python 2, то название этого модуля – tkMessageBox. Если же использовать алиас mb, то тогда решатся проблемы, связанные с совместимостью версий.

Тип окна выбирается в зависимости от того, что пользователю хочет предложить программа:

  1. Информационное сообщение. Если было выполнено какое-то действие, и не возникло в процессе никаких проблем, показывается уведомление этого типа. 
  2. Предупреждение. Используется, если действие было выполнено, но в процессе произошли определенные проблемы, о которых и сообщает приложение.
  3. Ошибка. Это если действие не было выполнено по какой-то причине. 

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

Интересно то, что есть возможность отобразить текст сообщения на нескольких строчках. Для этого используется выражение \n

Окна выбора ответа

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

Для демонстрации приведем следующую программу.Tkinter. Диалоговые (всплывающие) окна

Между ними есть определенные различия, поэтому следует более детально описать каждый из этих типов.

Но перед тем, как начинать разбираться, добавим модуль tkinter.messagebox описанным выше способом. Не забывайте этого делать, иначе у вас не получится работать с диалоговыми окнами.

Далее каждая функция вызывается для каждой из кнопок. В целом, программа выглядит следующим образом.

import tkinter as tk

import tkinter.messagebox as mb

 

class App(tk.Tk):

    def __init__(self):

        super().__init__()

        self.create_button(mb.askyesno, «Спросить Да/Нет»,

                           «Вернет True или False»)

        self.create_button(mb.askquestion, «Задать вопрос «,

                           «Вернет ‘yes’ или ‘no'»)

        self.create_button(mb.askokcancel, «Спросить Ок/Отмена»,

                           «Вернет True или False»)

        self.create_button(mb.askretrycancel, «Спросить Повтор/Отмена»,

                           «Вернет True или False»)

        self.create_button(mb.askyesnocancel, «Спросить Да/Нет/Отмена»,

                           «Вернет True, False или None»)

 

    def create_button(self, dialog, title, message):

        command = lambda: print(dialog(title, message))

        btn = tk.Button(self, text=title, command=command)

        btn.pack(padx=40, pady=5, expand=True, fill=tk.BOTH)

 

if __name__ == «__main__»:

    app = App()

    app.mainloop()

А теперь перейдем к разбору принципов работы вопросительных окон.

Принцип работы вопросительных окон

Чтобы не было повторений во время генерации кнопки и функции обратного вызова, необходимо сперва определить метод create_button. Он необходим, чтобы каждая кнопка с диалогами могла работать. Вследствие введенных команд, будет выдаваться результат функции dialog, что дает возможность понимать, какое значение ею возвращается в зависимости от кнопки, нажатой человеком.

Выбор файлов и папок

С помощью диалоговых окон для выбора файлов можно открывать файлы в Python. Возможен выбор одного или нескольких, которые есть в файловой системе. Чтобы воспользоваться этой функцией, в Tkinter существует отдельный модуль – tkinter.filedialog, в котором мы и найдем диалоговые окна для открытия папок и файлов. 

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

Чтобы продемонстрировать возможности модуля, приведем такой пример программы.Tkinter. Диалоговые (всплывающие) окна

Видим, что в ней есть две кнопки: выбора файла и выбора папки. По нажатию на каждую будет открыто соответствующее окно.Tkinter. Диалоговые (всплывающие) окна

После срабатывания функций, которые вызываются при активации события «При нажатии», будет возвращено полное имя файла. Если же пользователь нажал кнопку «Отмена», то не выводится ничего. 

Для вызова окна выбора файла в нашем примере используется функция askopenfilename, а для папок – askdirectory.

Приведем код, который реализует этот функционал.

import tkinter as tk

import tkinter.filedialog as fd

 

class App(tk.Tk):

    def __init__(self):

        super().__init__()

        btn_file = tk.Button(self, text=»Выбрать файл»,

                             command=self.choose_file)

        btn_dir = tk.Button(self, text=»Выбрать папку»,

                             command=self.choose_directory)

        btn_file.pack(padx=60, pady=10)

        btn_dir.pack(padx=60, pady=10)

 

    def choose_file(self):

        filetypes = ((«Текстовый файл», «*.txt»),

                     («Изображение», «*.jpg *.gif *.png»),

                     («Любой», «*»))

        filename = fd.askopenfilename(title=»Открыть файл», initialdir=»/»,

                                      filetypes=filetypes)

        if filename:

            print(filename)

 

    def choose_directory(self):

        directory = fd.askdirectory(title=»Открыть папку», initialdir=»/»)

        if directory:

            print(directory)

 

if __name__ == «__main__»:

    app = App()

    app.mainloop()

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

Принцип работы окон выбора файлов и папок

Функция askopenfilename используется для создания диалогового окна и, как мы поняли раньше, возвращает пустую строку. Также в ней возможно использование некоторых дополнительных аргументов:

  • title. Название окна.
  • initialdir. Папка, которая открывается первоначально.
  • filetypes. Это две строки, которые возвращают тип файла и шаблон поиска файла соответственно.
  • multiple  – разрешение или отсутствие разрешения выбора нескольких файлов.
  • defaultextension – стандартное расширение, добавляемое к файлу.

Сохранение данных в файл

Кроме открытия файла, необходимо уметь сохранять данные в файл. Для этого используется соответствующее диалоговое окно, которое вызывается функцией asksavefile. Чтобы ею воспользоваться, необходимо подключить модуль tkinter.filedialog.

Действия, выполняемые этой функцией, следующие. Это или создание файла в режиме записи, или же возврат значения None в случае закрытия окна.

import tkinter as tk

import tkinter.filedialog as fd

 

class App(tk.Tk):

    def __init__(self):

        super().__init__()

        self.text = tk.Text(self, height=10, width=50)

        self.btn_save = tk.Button(self, text=»Сохранить», command=self.save_file)

 

        self.text.pack()

        self.btn_save.pack(pady=10, ipadx=5)

 

    def save_file(self):

        contents = self.text.get(1.0, tk.END)

        new_file = fd.asksaveasfile(title=»Сохранить файл», defaultextension=».txt»,

                                    filetypes=((«Текстовый файл», «*.txt»),))

        if new_file:

            new_file.write(contents)

            new_file.close()

 

if __name__ == «__main__»:

    app = App()

    app.mainloop()

ОфисГуру
Adblock
detector