вторник, 10 апреля 2012 г.

wxPython in Action. Глава 9. Возможность выбора. Диалоги. (часть 2)

9.2 Использование стандартных диалогов
Практически все операционные системы содержат свои стандартные диалоги для таких повседневных задач, как выбор файла, шрифта или цвета. Это позволяет придерживаться во всех приложениях некоего стандартного внешнего вида и облегчает пользователю работу с вашей программой. Благодаря wxPython Вы тоже можете воспользоваться этим преимуществом; более того, Вы сможете использовать эти диалоги даже на тех платформах, где они не предоставляются операционной системой.
9.2.1 Диалог выбора файла
Диалог выбора файлов обычно стандартный для всех приложений. Класс wx.FileDialog использует родные диалоги для тех систем, где они предусмотрены и свой собственный вид там, где их нет. Версия такого диалога для Windows изображена на рисунке 9.6
рис 9.6
Вы можете указать каталог по умолчанию и маски файлов для отображения, как это сделано в листинге 9.6:
Листинг 9.6
import wx import os if __name__ == "__main__": app = wx.PySimpleApp() wildcard = "Python source (*.py)|*.py|" \ "Compiled Python (*.pyc)|*.pyc|" \ "All files (*.*)|*.*" dialog = wx.FileDialog(None, "Choose a file", os.getcwd(), "", wildcard, wx.OPEN) if dialog.ShowModal() == wx.ID_OK: print dialog.GetPath() dialog.Destroy()
Диалог выбора файла является одним из наиболее сложных, так как имеет несколько свойств, доступных для чтения / записи. Часть этих свойств Вы можете установить при создании экземпляра этого класса:
wx.FileDialog(parent, message="Choose a file", defaultDir="", defaultFile="", wildcard="*.*", style=0, pos=wx.DefaultPosition)
message содержит заголовок диалога, defaultDir указывает на каталог, который будет отображён при открытии диалога. Если он не указан или установлен на несуществующий каталог, то будет показано содержимое рабочего каталога. defaultFile содержит название файла и обычно используется при сохранении файлов. wildcart устанавливает фильтры файлов, доступных для выбора, причём в нем можно использовать шаблоны * и ?. В аргументе может содержаться как один шаблон, например *.py, так и набор шаблонов в таком формате: <описание> | <шаблон> | <описание> | <шаблон>, как в листинге выше:
"Python source (*.py)|*.py|Compiled Python (*.pyc)|*.pyc| All files (*.*)|*.*"
Если Вы используете набор шаблонов, то они будут доступны через выпадающий список, как на рисунке 9.6. И ещё, нет никакой гарантии, что аргумент pos будет учитываться конкретной ОС.
Выбор файла
Два наиболее важных флага стиля для данного диалога - это wx.Open и wx.Save, которые определяют поведение диалогового окна.
Диалог, используемый для открытия файла может содержать ещё два флага стиля, а именно wx.HIDE_READONLY, не позволяющий открыть файл в режиме "только для чтения", и wx.MULTIPLE, который позволяет выбрать несколько файлов в одной директории.
Для диалога сохранения есть один полезный флаг - wx.OVERWRITE_PROMT, который требует подтверждения от пользователя при его попытке перезаписать уже существующий файл.
Другие типы диалога могут использовать флаг wx.CHANGE_DIR. При его наличии выбор файла изменяет директорию по умолчанию для этого диалога на директорию, содержащую этот файл. Так что в следующий раз открытый диалог уже будет находиться в той директории и для этого Вам не надо сохранять где-либо её название.
В отличие от других диалогов, рассмотренных выше, все эти свойства доступны для чтения и записи при помощи соответствующих методов. Это касается свойств directory, filename, style, message и wildcard, для который существуют соответствующие Get- и Set- методы.
После того, как пользователь закрыл диалог и Вы убедились, что он сделал это кнопкой "ОК", Вы можете получить выбранный им файл с помощью метода GetPath(), возвращающего полное имя и путь к файлу в виде строки. Если Вы использовали флаг wx.MULTIPLE, то Вам потребуется метод GetPaths(), который вернёт Вам список из строк. Если же по какой-то причине Вам надо знать, какой фильтр при этом использовался, то метод GetFilterIndex() вернёт Вам индекс этого фильтра. Для программного изменения выбранного фильтра используйте метод SetFilterIndex().
Кроме того, Вы можете использовать следующую функцию вместо создания экземпляра класса:
wx.FileSelector(message, default_path="", default_filename="", default_extension="", wildcard="*.*'', flags=0, parent=None, x=-1, y=-1)
Назначение почти всех аргументов понятно из названия, кроме flags - обычно он называется style и default_extension, указывающий на расширение, которое будет добавлено к имени файла при его сохранении. Если пользователь нажимает на "ОК", Вы получите путь к файлу, иначе Вам достанется лишь пустая строка.
Выбор папки
Если Вам надо предоставить пользователю возможность выбора не файла а папки, используйте диалог wx.DirDialog, отображающий древовидную структуру папок, как показано на рисунке 9.7
Вызов этого диалога несколько проще, чем диалога для выбора файла, как видно из листинга 9.7:
рис 9.7
Листинг 9.7
import wx if __name__ == "__main__": app = wx.PySimpleApp() dialog = wx.DirDialog(None, "Choose a directory:", style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON) if dialog.ShowModal() == wx.ID_OK: print dialog.GetPath() dialog.Destroy()
Практически вся функциональность этого диалога заключена в конструкторе:
wx.DirDialog(parent, message="Choose a directory", defaultPath="", style=0, pos = wx.DefaultPosition, size = wx.DefaultSize, name="wxDirCtrl")
Поскольку message отображается в самом диалоге, Вам нет необходимости (да по всей видимости и возможности - прим. переводчика) в изменении заголовка диалога. defaultPath указывает выбор по умолчанию, пустая строка в данном случае будет означать корень файловой системы. pos и size игнорируются в Windows, а name игнорируется во всех ОС. Флаг стиля wx.DD_NEW_DIR_BUTTON добавляет кнопку создания новой папки, причём он может не работать в старых версиях Winows.
Свойства path, message и style имеют стандартный методы получения и установки. После закрытия диалога можно получит выбранное значение методом GetPath(). Кроме того, вызвать диалог можно и с помощью функции:
wx.DirSelector(message=wx.DirSelectorPromptStr, default_path="", style=0, pos=wxDefaultPosition, parent=None)
Аргументы аналогичны конструктору класса. Функция возвращает путь к папке в виде строки или пустую строку, если была нажата кнопка отмены.
9.2.2 Диалог выбора шрифта
Диалог выбора шрифта отличается от диалога выбора файла, так как он использует дополнительный вспомогательный класс для отображения информации. На рисунке 9.8 можно увидеть этот диалог в ОС Windows.
Листинг 9.8 содержит код, необходимый для создания такого диалога. Как можно заметить, он немного отличается от предыдущих примеров.
рис 9.8
Листинг 9.8
import wx if __name__ == "__main__": app = wx.PySimpleApp() dialog = wx.FontDialog(None, wx.FontData()) if dialog.ShowModal() == wx.ID_OK: data = dialog.GetFontData() font = data.GetChosenFont() colour = data.GetColour() print 'You selected: "%s", %d points\n' % ( font.GetFaceName(), font.GetPointSize()) dialog.Destroy()
Конструктор этого класса намного проще тех, что мы видели до этого:
wx.FontDialog(parent, data)
Вы не можете выбрать сообщение или заголовок для этого диалога, информация же, которая обычно содержится в флагах стиля, на этот раз заключена в аргументе data, являющимся экземпляром класса wx.FontData. Класс wx.FontDialog имеет только один полезный метод - GetFontData(), возвращающий экземпляр wx.FontData.
Экземпляр wx.FontData позволяет установить значения, управляющие отображением диалога выбора шрифта, и он же содержит информацию, выбранную пользователем. Например, в листинге 9.8 мы используем два метода экземпляра этого класса для уточнения деталей выбранного шрифта. Конструктор этого класса не принимает аргументов, все значения устанавливаются методами, приведенными в таблице:
МетодОписание
GetAllowSymbols()
SetAllowSymbols(allowSymbols)
Определяет, отображаются ли символьные шрифты (например, dingbats), аргументом является логическое значение, смысл имеет только в Windows. Начальное значение - True
GetChosenFont()
SetChosenFont(font)
Возвращает объект wx.Font, отражающий шрифт, выбранный пользователем. Никогда не используйте метод установки для этого свойства! Если пользователь нажал на отмену, то возвращается значение None. Класс wx.Font будет более детально обсуждаться в главе 12
GetColour()
SetColour(colour)
Возвращает цвет, выбранный пользователем в качестве экземпляра класса wx.Colour. С помощью Set- метода можно установить значение по умолчанию. Установочный метод принимает экземпляр того же класса или строку с названием цвета. Начальное значение - black
GetEnableEffects()
EnableEffects(enable)
В Windows версии благодаря этому методу можно разрешить или запретить изменение цвета, подчёркивания или зачёркивания шрифта.
GetInitialFont()
SetInitialFont(font)
Возвращает шрифт, установленный по умолчанию для данного приложения. Это свойство должно быть установлено до отображения диалога. Начальное значение - None.
SetRange(min,max)Устанавливает допустимое значение размера шрифта. Начальные значения 0 и 0, что означает отсутствие каких-либо ограничений
GetShowHelp()
SetShowHelp()
Если значение True, то в Windows будет отображаться кнопка справки. Начальное значение - False
У этого диалога так же есть соответствующая функция, сама создающая нужный экземпляр класса wx.FontData:
wx.GetFontFromUser(parent, fontInit)
fontInit является экземпляром wx.Font, используемым для значения по умолчанию. Возвращаемое значение так же является экземпляром wx.Font. При нажатии на "ОК" метод wx.Font.Ok() вернёт True, иначе False.
9.2.3 Диалог выбора цвета
Диалог выбора цвета похож на диалог выбора шрифта, так как он тоже использует дополнительный класс для управления информацией. На рисунке 9.9 отображён вид этого диалога под Windows, а в листинге 9.9 показан его код, похожий на код из предыдущего примера:
рис 9.9
Листинг 9.9
import wx if __name__ == "__main__": app = wx.PySimpleApp() dialog = wx.ColourDialog(None) dialog.GetColourData().SetChooseFull(True) if dialog.ShowModal() == wx.ID_OK: data = dialog.GetColourData() print 'You selected: %s\n' % str(data.GetColour().Get()) dialog.Destroy()
Для выбора цвета в wxPython используется класс wx.ColourDialog (привычным к американскому английскому придётся привыкнуть к такому варианту написания слова). Конструктор этого класса прост и понятен:
wx.ColourDialog(parent, data=None)
data является экземпляром класса wx.ColourData, который проще своего шрифтового товарища. Он содержит только конструктор, не принимающий аргументов, и три свойства:
  • GetChooseFull/SetChooseFull(flag) - логическое свойство, работающее под Windows. Если установлено, то отображается полная версия диалога, включая выбор пользовательских цветов, иначе только урезанная версия.
  • GetColour/SetColour(colour) - принимает значение класса wx.Colour. если диалог закрыт, то с помощью этого метода можно получить выбранный пользователем цвет. До отображения диалога можно установить цвет по умолчанию. Значение по умолчанию - black.
  • GetCustomColour(i)/SetCustomColour(i, colour) - позволяет получить или установить в пользовательскую палитру заданный цвет. i - номер ячейки в палитре, от 0 до 15. Все цвета по умолчанию белые.

Аналогичная функция для этого диалога:
wx.GetColourFromUser(parent, colInit)
colInit - экземпляр класса wx.Colour, который устанавливается как значение по умолчанию. Возвращаемое значение так же является экземпляром этого класса. При нажатии на "ОК" метод wx.Font.Ok() вернёт True, иначе False.
9.2.4 А может можно ещё и картинку выбрать?
Если ваша программа работает с графикой, то бывает полезно предоставить пользователю возможность просмотра миниатюр при выборе файла. Для этого в wxPython есть специальный диалог wx.lib.imagebrowser.ImageDialog. Его пример приведён на рисунке 9.10, а код в листинге 9.10
рис 9.10
Листинг 9.10
import wx import wx.lib.imagebrowser as imagebrowser if __name__ == "__main__": app = wx.PySimpleApp() dialog = imagebrowser.ImageDialog(None) if dialog.ShowModal() == wx.ID_OK: print "You Selected File: " + dialog.GetFile() dialog.Destroy()
Этот класс прост как топор и имеет совсем мало свойств для настройки. Для изменения его поведения обращайтесь к исходному коду, чтобы, например, настроить отображаемые типы файлов. Конструктор принимает всего два аргумента:
ImageDialog(parent, set_dir=None)
set_dir обозначает каталог, содержимое которого будет отображаться при открытии диалога. Если значение при вызове функции не установлено, отображаться будет рабочий диалог. После закрытия диалога получить выбранное значение можно с помощью метода GetFile(), возвращающем строку, содержащую путь к файлу, или метода GetDirectory(), возвращающем выбранную папку.

5 комментариев:

  1. Это всё отлично, но могу ли я выбрать несколько папок, а не одну (для копирования, например)?

    ОтветитьУдалить
    Ответы
    1. за раз? сомневаюсь. это же те тотал коммандер) для этого больше подойдёт list, но переводом о нём я как раз сейчас занят) это глава 13, если у Вас есть оригинал.

      Удалить
    2. да, за раз =) думаю, оригинал можно отыскать, чем, собственно, и займусь. Спасибо за переводы. Кстати, в будущем, когда перевод будет полным и оконченным, создайте pdf своих трудов. Имхо, так удобнее, особенно с оглавлением.

      Удалить
    3. если разберусь, как это делать)
      https://dl.dropbox.com/u/25028662/wxPython_in_Action_%28Manning-2006%29.pdf

      Удалить
    4. LaTeX? =) Нет, не буду предлагать подобные вещи. Наиболее простой вариант - воспользоваться текстовыми процессорами: MS Word под windows, OpenOficce Writer/Abiword под linux. Ничего, нормально.
      За файл благодарю

      Удалить