Виджет Calendar это эффективный способ для отображения или получения дат. Он очень прост в создании и работе.
Создание виджета gtk.Calendar также просто как:
calendar = gtk.Calendar() |
По умолчанию календарь будет отображать текущий месяц и год.
Случается, что вам нужно изменить большое количество информации в этом виджете, и следующие методы позволяют делать множественные изменения в виджете Calendar, без мерцания обновлений на экране.
calendar.freeze() calendar.thaw() |
Они работают также как методы freeze/thaw на любом другом виджете.
Виджет Calendar имеет несколько настроек, которые позволяют изменить внешний вид виджета, управляются они с помощью метода:
calendar.display_options(flags) |
Аргумент flags может быть создан смешиванием следующих пяти опций с помощью операции логического сложения OR (|):
CALENDAR_SHOW_HEADING | Эта опция указывает что месяц и год должны быть отображены на календаре. |
CALENDAR_SHOW_DAY_NAMES | Эта опция указывает что необходимо отображать трёхбуквенные названия дней недели (Пнд, Втр, Ср и т.д.) |
CALENDAR_NO_MONTH_CHANGE | Эта опция задаёт что пользователь не должен и не может изменять отображаемый месяц. Это может быть полезно когда вам нужно отобразить определённый месяц, так, если нужно отобразить 12 календарей на каждый месяц определённого года. |
CALENDAR_SHOW_WEEK_NUMBERS | Эта опция указывает что номер каждой недели должен быть показан слева от календаря. (так 1 Янв = 1 неделя, 31 Дек = 52 неделя). |
CALENDAR_WEEK_START_MONDAY | Эта опция задаёт начало календарной недели с понедельника, а не с воскресенья как выбрано по умолчанию. Это влияет только на порядок в котором дни отображаются слева направо. Заметим, что в PyGTK 2.4 и выше эта опция считается устаревшей. |
Следующие методы используются для установки отображаемой даты:
result = calendar.select_month(month, year) calendar.select_day(day) |
Логическое значение возвращаемое после метода select_month() показывает успешность выбора.
С методом select_day() указывается номер дня в текущем месяце, если это возможно. День 0 снимает любой текущий выбор.
В дополнение к выбору, любое число дней в месяце могут быть “отмечены”. Отмеченный день выделяется подсветкой. Следующие методы предоставлены для управления отмеченными днями:
result = calendar.mark_day(day) result = calendar.unmark_day(day) calendar.clear_marks() |
mark_day() и unmark_day() возвращают логическое значение, показывающее успешность выполнения. Заметим что метки сохраняются при изменении месяца или года.
Последний метод виджета Calendar используется для получения текущей выбранной даты, месяца и/или года.
year, month, day = calendar.get_date() |
Виджет Calendar может генерировать несколько сигналов означающих выбор даты и её изменение. Названия говорят сами за себя, вот они:
month_changed day_selected day_selected_double_click prev_month next_month prev_year next_year |
Остаётся нам только поместить все это в наш пример calendar.py. Рисунок 9.12, “Пример календаря” показывает интерфейс программы:
Исходный код calendar.py:
#!/usr/bin/env python # -*- coding:utf-8 -*- # example calendar.py # # Copyright (C) 1998 Cesar Miquel, Shawn T. Amundson, Mattias Gronlund # Copyright (C) 2000 Tony Gale # Copyright (C) 2001-2004 John Finlay # Copyright (C) 2011 Sergey Zavgorodniy, Grigoriy Kramarenko # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. import pygtk pygtk.require('2.0') import gtk, pango import time class CalendarExample: DEF_PAD = 10 DEF_PAD_SMALL = 5 TM_YEAR_BASE = 1900 calendar_show_header = 0 calendar_show_days = 1 calendar_month_change = 2 calendar_show_week = 3 def calendar_date_to_string(self): year, month, day = self.window.get_date() mytime = time.mktime((year, month+1, day, 0, 0, 0, 0, 0, -1)) return time.strftime("%x", time.localtime(mytime)) def calendar_set_signal_strings(self, sig_str): prev_sig = self.prev_sig.get() self.prev2_sig.set_text(prev_sig) prev_sig = self.last_sig.get() self.prev_sig.set_text(prev_sig) self.last_sig.set_text(sig_str) def calendar_month_changed(self, widget): buffer = "month_changed: %s" % self.calendar_date_to_string() self.calendar_set_signal_strings(buffer) def calendar_day_selected(self, widget): buffer = "day_selected: %s" % self.calendar_date_to_string() self.calendar_set_signal_strings(buffer) def calendar_day_selected_double_click(self, widget): buffer = "day_selected_double_click: %s" buffer = buffer % self.calendar_date_to_string() self.calendar_set_signal_strings(buffer) year, month, day = self.window.get_date() if self.marked_date[day-1] == 0: self.window.mark_day(day) self.marked_date[day-1] = 1 else: self.window.unmark_day(day) self.marked_date[day-1] = 0 def calendar_prev_month(self, widget): buffer = "prev_month: %s" % self.calendar_date_to_string() self.calendar_set_signal_strings(buffer) def calendar_next_month(self, widget): buffer = "next_month: %s" % self.calendar_date_to_string() self.calendar_set_signal_strings(buffer) def calendar_prev_year(self, widget): buffer = "prev_year: %s" % self.calendar_date_to_string() self.calendar_set_signal_strings(buffer) def calendar_next_year(self, widget): buffer = "next_year: %s" % self.calendar_date_to_string() self.calendar_set_signal_strings(buffer) def calendar_set_flags(self): options = 0 for i in range(5): if self.settings[i]: options = options + (1<<i) if self.window: self.window.display_options(options) def calendar_toggle_flag(self, toggle): j = 0 for i in range(5): if self.flag_checkboxes[i] == toggle: j = i self.settings[j] = not self.settings[j] self.calendar_set_flags() def calendar_font_selection_ok(self, button): self.font = self.font_dialog.get_font_name() if self.window: font_desc = pango.FontDescription(self.font) if font_desc: self.window.modify_font(font_desc) def calendar_select_font(self, button): if not self.font_dialog: window = gtk.FontSelectionDialog("Диалог выбора шрифта") self.font_dialog = window window.set_position(gtk.WIN_POS_MOUSE) window.connect("destroy", self.font_dialog_destroyed) window.ok_button.connect("clicked", self.calendar_font_selection_ok) window.cancel_button.connect_object("clicked", lambda wid: wid.destroy(), self.font_dialog) window = self.font_dialog if not (window.flags() & gtk.VISIBLE): window.show() else: window.destroy() self.font_dialog = None def font_dialog_destroyed(self, data=None): self.font_dialog = None def __init__(self): flags = [ "Показать заголовок", "Показать название дня", "Не изменять месяц", "Показать номера недель", ] self.window = None self.font = None self.font_dialog = None self.flag_checkboxes = 5*[None] self.settings = 5*[0] self.marked_date = 31*[0] window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.set_title("Пример календаря") window.set_border_width(5) window.connect("destroy", lambda x: gtk.main_quit()) window.set_resizable(False) vbox = gtk.VBox(False, self.DEF_PAD) window.add(vbox) # Верхняя часть окна, календарь, флаги и выбор шрифта. hbox = gtk.HBox(False, self.DEF_PAD) vbox.pack_start(hbox, True, True, self.DEF_PAD) hbbox = gtk.HButtonBox() hbox.pack_start(hbbox, False, False, self.DEF_PAD) hbbox.set_layout(gtk.BUTTONBOX_SPREAD) hbbox.set_spacing(5) # Календарь frame = gtk.Frame("Календарь") hbbox.pack_start(frame, False, True, self.DEF_PAD) calendar = gtk.Calendar() self.window = calendar self.calendar_set_flags() calendar.mark_day(19) self.marked_date[19-1] = 1 frame.add(calendar) calendar.connect("month_changed", self.calendar_month_changed) calendar.connect("day_selected", self.calendar_day_selected) calendar.connect("day_selected_double_click", self.calendar_day_selected_double_click) calendar.connect("prev_month", self.calendar_prev_month) calendar.connect("next_month", self.calendar_next_month) calendar.connect("prev_year", self.calendar_prev_year) calendar.connect("next_year", self.calendar_next_year) separator = gtk.VSeparator() hbox.pack_start(separator, False, True, 0) vbox2 = gtk.VBox(False, self.DEF_PAD) hbox.pack_start(vbox2, False, False, self.DEF_PAD) # Создаём рамку справа, с флагами внутри frame = gtk.Frame("Флаги") vbox2.pack_start(frame, True, True, self.DEF_PAD) vbox3 = gtk.VBox(True, self.DEF_PAD_SMALL) frame.add(vbox3) for i in range(len(flags)): toggle = gtk.CheckButton(flags[i]) toggle.connect("toggled", self.calendar_toggle_flag) vbox3.pack_start(toggle, True, True, 0) self.flag_checkboxes[i] = toggle # Создаём кнопку выбора шрифта button = gtk.Button("Шрифт...") button.connect("clicked", self.calendar_select_font) vbox2.pack_start(button, False, False, 0) # Создаём часть сигнал-событие. frame = gtk.Frame("События сигналов") vbox.pack_start(frame, True, True, self.DEF_PAD) vbox2 = gtk.VBox(True, self.DEF_PAD_SMALL) frame.add(vbox2) hbox = gtk.HBox (False, 3) vbox2.pack_start(hbox, False, True, 0) label = gtk.Label("Сигнал:") hbox.pack_start(label, False, True, 0) self.last_sig = gtk.Label("") hbox.pack_start(self.last_sig, False, True, 0) hbox = gtk.HBox (False, 3) vbox2.pack_start(hbox, False, True, 0) label = gtk.Label("Предыдущий сигнал:") hbox.pack_start(label, False, True, 0) self.prev_sig = gtk.Label("") hbox.pack_start(self.prev_sig, False, True, 0) hbox = gtk.HBox (False, 3) vbox2.pack_start(hbox, False, True, 0) label = gtk.Label("Второй предыдущий сигнал:") hbox.pack_start(label, False, True, 0) self.prev2_sig = gtk.Label("") hbox.pack_start(self.prev2_sig, False, True, 0) bbox = gtk.HButtonBox () vbox.pack_start(bbox, False, False, 0) bbox.set_layout(gtk.BUTTONBOX_END) button = gtk.Button(gtk.STOCK_CLOSE, gtk.STOCK_CLOSE) button.connect("clicked", lambda w: gtk.main_quit()) bbox.add(button) button.set_flags(gtk.CAN_DEFAULT) button.grab_default() window.show_all() def main(): gtk.main() return 0 if __name__ == "__main__": CalendarExample() main()
Предыдущая страница | На уровень выше | Следующая страница |
9.11. Комбинированный список (gtk.Combo) | К оглавлению | 9.13. Выбор цвета (gtk.ColorSelection) |