Reputation: 91
I am trying to create a calendar app in python.As for now I have manage to create the Gtk.window
, a Gtk.Notebook
with two pages (page1 month calendar, page 2 week calendar) added to the Gtk.window
.I have used Gtk.Calendar
for month and from signal 'day-selected'
I used a function to get_date()
.Also I used a Gtk.TextView
with Gtk.TextBuffer
to input text (as a note).
First question : how to connect the date with the input text and store it in a list or dictionary so i can save it later to a file.
Second:I have activate details with self.calendar.set_property("show-details", True)
and defined a function self.calendar.set_detail_func(self.cal_entry)
for details.
def cal_entry(self, calendar, year, month, date):
if self.textbuffer is not None:
self.calendar.mark_day(self.day)
How to mark the days with notes(text in Gtk.TextBuffer
) because the above function does not work correctly.
Below is a snippet of the code:
class Window(Gtk.ApplicationWindow):
def __init__(self, app):
super(Window, self).__init__(title="Live Calendar", application=app)
self.set_default_size(-1, 400)
self.set_resizable(False)
self.set_border_width(10)
self.create_notebook()
self.entry()
self.refresh_icon()
def refresh_icon(self):
#refreshing the icon of the app
print(get_filename())
subject_lines = read_file(subject)
index = [i for i in range(len(subject_lines)) \
if subject_lines[i].startswith("Icon=")][0]
subject_lines[index] = "Icon=" + get_filename() + "\n"
write_file(subject, subject_lines)
self.set_icon_from_file(get_filename())
timer = threading.Timer(60, self.refresh_icon)
timer.start()
def create_notebook(self):
# Open Buttton
self.openbutton = Gtk.Button("Open")
self.openbutton.set_tooltip_text("Open Notes")
self.openbutton.connect("clicked", self.on_open_clicked)
# Save Button
self.savebutton = Gtk.Button("Save")
self.savebutton.set_tooltip_text("Save Notes")
self.savebutton.connect("clicked", self.on_save_clicked)
# Header
self.header = Gtk.HeaderBar(title="Live Calendar")
self.header.set_property("show_close_button", True)
self.header.pack_start(self.openbutton)
self.header.pack_start(self.savebutton)
self.set_titlebar(self.header)
#page1 month calendar
self.page1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=0)
self.calendar = Gtk.Calendar()
self.calendar.set_property("show-week-numbers", True)
self.calendar.set_detail_height_rows(2)
self.calendar.set_detail_width_chars(2)
self.calendar.set_property("show-details", True)
self.calendar.set_detail_func(self.cal_entry)
self.__connect_signals()
self.page1.add(self.calendar)
#note taking
self.sw = Gtk.ScrolledWindow()
self.sw.set_hexpand(True)
self.sw.set_vexpand(True)
self.textview = Gtk.TextView()
self.textview.set_editable(True)
self.textview.set_wrap_mode(Gtk.WrapMode.WORD_CHAR)
self.textbuffer = self.textview.get_buffer()
self.sw.add(self.textview)
self.page1.pack_start(self.sw, True, True, 0)
#page2 week calendar
......a lot of code.......
#create notebook
self.notebook = Gtk.Notebook()
self.notebook.set_tab_pos(0)
self.notebook.append_page(self.page1, Gtk.Label('Month'))
self.notebook.append_page(self.page2, Gtk.Label('Week'))
self.add(self.notebook)
def __connect_signals(self):
self.day_selected_handle = self.calendar.connect('day-selected', self.entry)
def entry(self, *args):
self.page1.remove(self.label)
self.year, self.month, self.day = self.calendar.get_date()
self.month = self.month + 1
self.entrydate = datetime.date(self.year, self.month, self.day)
self.notedate = self.entrydate.strftime("%d/%m/%y")
self.text = self.entrydate.strftime("%d/%m/%y write your notes here...")
self.label = Gtk.Label(self.text)
self.page1.pack_start(self.label, False, False, 0)
self.show_all()
def cal_entry(self, calendar, year, month, date):
if self.textbuffer is not None:
self.calendar.mark_day(self.day)
#save into file
def on_save_clicked(self, widget):
dialog = Gtk.FileChooserDialog("Save file", self,
Gtk.FileChooserAction.SAVE,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_SAVE, Gtk.ResponseType.OK))
response = dialog.run()
if response == Gtk.ResponseType.OK:
save_file = dialog.get_filename()
start_iter = self.textbuffer.get_start_iter()
end_iter = self.textbuffer.get_end_iter()
text = self.textbuffer.get_text(start_iter, end_iter, True)
with open(save_file, 'w') as f:
f.write(text)
elif response == Gtk.ResponseType.CANCEL:
dialog.destroy()
dialog.destroy()
# open and read the file
def on_open_clicked(self, widget):
dialog = Gtk.FileChooserDialog("Please choose a file", self,
Gtk.FileChooserAction.OPEN,
(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
filter_text = Gtk.FileFilter()
filter_text.set_name("Text files")
filter_text.add_mime_type("text/plain")
dialog.add_filter(filter_text)
response = dialog.run()
if response == Gtk.ResponseType.OK:
selected_file = dialog.get_filename()
with open(selected_file, 'r') as f:
data = f.read()
self.textbuffer.set_text(data)
elif response == Gtk.ResponseType.CANCEL:
dialog.destroy()
dialog.destroy()
def quitApp(self, par):
app.quit()
class Application(Gtk.Application):
def __init__(self):
super(Application, self).__init__()
def do_activate(self):
self.win = Window(self)
self.win.show_all()
def do_startup(self):
Gtk.Application.do_startup(self)
app = Application()
app.run(sys.argv)
Any help will be appriciated.
Thanks in advance
Upvotes: 1
Views: 437
Reputation: 958
For the first question: Depends, but probably a dictionary indexed by a triple for y/m/d
d = dict()
d[(2019, 10, 1)] = "your notes..."
Second question: The way details work is that cal_entry(self, calendar, year, month, day) must return a string to be displayed below the day, in the calendar. So you have to get the text from the dictionary above. You can do that with:
def cal_entry(self, calendar, year, month, day):
self.calendar.mark_day(day)
return dict.get((year, month, day))
Maybe this sample code can help:
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class NotePopover(Gtk.Popover):
def __init__(self, app):
Gtk.Popover.__init__(self)
self.set_size_request(200, 300)
grid = Gtk.Grid()
grid.set_orientation(Gtk.Orientation.VERTICAL)
scrolled_window = Gtk.ScrolledWindow()
self.text_view = Gtk.TextView()
scrolled_window.add(self.text_view)
grid.add(scrolled_window)
button = Gtk.Button(label='Add')
grid.add(button)
grid.show_all()
self.add(grid)
scrolled_window.set_vexpand(True)
scrolled_window.set_hexpand(True)
button.connect('clicked', self.on_button_clicked)
self.app = app
def do_popup(self):
self.popup()
def on_button_clicked(self, widget):
year = app.win.calendar.get_property('year')
month = app.win.calendar.get_property('month')
day = app.win.calendar.get_property('day')
start_iter = self.text_view.get_buffer().get_start_iter()
end_iter = self.text_view.get_buffer().get_end_iter()
app.notes_dict[(year, month, day)] = self.text_view.get_buffer().get_text(start_iter, end_iter, True)
app.win.do_update()
self.text_view.get_buffer().set_text("")
self.popdown()
class Window(Gtk.Window):
def __init__(self, app):
Gtk.Window.__init__(self)
self.set_title('Test GtkCalendar')
self.set_default_size(400, 300)
header_bar = Gtk.HeaderBar()
header_bar.set_show_close_button(True)
self.set_titlebar(header_bar)
button = Gtk.Button(label="Add note")
button.get_style_context().add_class('suggested-action')
button.connect('clicked', self.on_button_clicked)
header_bar.pack_start(button)
grid = Gtk.Grid()
grid.set_orientation(Gtk.Orientation.VERTICAL)
self.calendar = Gtk.Calendar()
scrolled_window = Gtk.ScrolledWindow()
self.text_view = Gtk.TextView()
self.add(grid)
grid.add(self.calendar)
grid.add(scrolled_window)
scrolled_window.add(self.text_view)
self.calendar.set_hexpand(True)
self.calendar.set_halign(Gtk.Align.CENTER)
scrolled_window.set_vexpand(True)
scrolled_window.set_hexpand(True)
self.popover = NotePopover(app)
self.popover.set_relative_to(button)
self.connect('destroy', Gtk.main_quit)
self.calendar.connect('day-selected', self.calendar_changed)
self.calendar.connect('month-changed', self.calendar_changed)
self.show_all()
self.app = app
def on_button_clicked(self, widget):
self.popover.do_popup()
def calendar_changed(self, widget):
self.do_update()
def do_update(self):
year = app.win.calendar.get_property('year')
month = app.win.calendar.get_property('month')
day = app.win.calendar.get_property('day')
text = app.notes_dict.get((year, month, day))
if text is not None:
self.text_view.get_buffer().set_text(text)
else:
self.text_view.get_buffer().set_text("")
class Application:
def __init__(self):
self.notes_dict = dict()
self.win = Window(self)
if __name__ == '__main__':
app = Application()
Gtk.main()
Upvotes: 2