else
This commit is contained in:
parent
694a3ca1b3
commit
27f13eed96
5 changed files with 474 additions and 12 deletions
423
Clock/clock.py
Normal file
423
Clock/clock.py
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
import tkinter
|
||||||
|
import datetime
|
||||||
|
import math
|
||||||
|
import time
|
||||||
|
|
||||||
|
COLOR_BACKGROUND = '#000'
|
||||||
|
COLOR_FONT = '#666'
|
||||||
|
COLOR_DROPDOWN = '#aaa'
|
||||||
|
COLOR_DROPDOWN_ACTIVE = '#999'
|
||||||
|
|
||||||
|
MODE_CLOCK = 'clock'
|
||||||
|
MODE_COUNTDOWN = 'countdown'
|
||||||
|
MODE_STOPWATCH = 'stopwatch'
|
||||||
|
|
||||||
|
FONT = 'Consolas'
|
||||||
|
# Used for resizing the clock font to fit the frame.
|
||||||
|
# For consolas, 1.33333 is a good value. It may differ
|
||||||
|
# for other fonts
|
||||||
|
FONT_YX_RATIO = 1.33333
|
||||||
|
|
||||||
|
MONTHS = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']
|
||||||
|
MONTHS_DICT = {'jan':1, 'feb':2, 'mar':3, 'apr':4, 'may':5, 'jun':6, 'jul':7, 'aug':8, 'sep':9, 'oct':10, 'nov':11, 'dec':12}
|
||||||
|
|
||||||
|
class Clock:
|
||||||
|
def __init__(self):
|
||||||
|
self.t = tkinter.Tk()
|
||||||
|
self.t.configure(bg=COLOR_BACKGROUND)
|
||||||
|
self.mode_methods = {
|
||||||
|
MODE_CLOCK: self.build_gui_clock,
|
||||||
|
MODE_COUNTDOWN: self.build_gui_countdown,
|
||||||
|
MODE_STOPWATCH: self.build_gui_stopwatch,
|
||||||
|
}
|
||||||
|
self.dropstring = tkinter.StringVar(self.t)
|
||||||
|
self.dropstring.trace('w', self.trigger_choose_mode)
|
||||||
|
modes = list(self.mode_methods.keys())
|
||||||
|
modes.sort(key=lambda x: x.lower())
|
||||||
|
self.drop = tkinter.OptionMenu(self.t, self.dropstring, *modes)
|
||||||
|
self.drop.configure(relief='flat', bg=COLOR_DROPDOWN, activebackground=COLOR_DROPDOWN_ACTIVE, direction='below', highlightthickness=0, anchor='w')
|
||||||
|
self.drop.pack(fill='x', anchor='n')
|
||||||
|
#self.trigger_choose_mode()
|
||||||
|
|
||||||
|
self.frame_applet = tkinter.Frame(self.t, width=400, height=95, bg=COLOR_BACKGROUND)
|
||||||
|
self.frame_applet.pack(side='bottom', anchor='s', expand=True, fill='both')
|
||||||
|
self.frame_applet.pack_propagate(0)
|
||||||
|
self.frame_applet.grid_propagate(0)
|
||||||
|
|
||||||
|
self.elements = []
|
||||||
|
|
||||||
|
# Instance is used to keep track of how many times we have
|
||||||
|
# swapped modes.
|
||||||
|
# This is to make sure that any `self.t.after` loops are broken
|
||||||
|
# when we leave that mode.
|
||||||
|
self.instance = 0
|
||||||
|
|
||||||
|
self.dropstring.set(MODE_COUNTDOWN)
|
||||||
|
|
||||||
|
self.t.mainloop()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self):
|
||||||
|
return self.drop.cget('text')
|
||||||
|
|
||||||
|
def delete_applet_elements(self):
|
||||||
|
self.started = 0
|
||||||
|
self.frame_applet.unbind('<Configure>')
|
||||||
|
for x in range(len(self.elements)):
|
||||||
|
self.elements.pop().destroy()
|
||||||
|
self.frame_applet.rowconfigure(0, weight=0)
|
||||||
|
self.frame_applet.columnconfigure(0, weight=0)
|
||||||
|
|
||||||
|
|
||||||
|
'''clock
|
||||||
|
###### ### ##### ###### ### ###
|
||||||
|
####### ### ####### ####### ### ###
|
||||||
|
### ### ### ### ### #####
|
||||||
|
####### ####### ####### ####### ### ###
|
||||||
|
###### ####### ##### ###### ### ###
|
||||||
|
'''
|
||||||
|
def build_gui_clock(self):
|
||||||
|
def tick_clock():
|
||||||
|
if this_instance != self.instance:
|
||||||
|
# used to break the "after" loop
|
||||||
|
return
|
||||||
|
#now = datetime.datetime.now()
|
||||||
|
#now = now.strftime('%H:%M:%S')
|
||||||
|
now = time.strftime('%H:%M:%S')
|
||||||
|
label_clock.configure(text=now)
|
||||||
|
self.t.after(1000, tick_clock)
|
||||||
|
|
||||||
|
this_instance = self.instance
|
||||||
|
|
||||||
|
label_clock = tkinter.Label(self.frame_applet, text='x', bg=COLOR_BACKGROUND, fg=COLOR_FONT)
|
||||||
|
label_clock.pack(anchor='center', expand=True)
|
||||||
|
self.elements.append(label_clock)
|
||||||
|
|
||||||
|
tick_clock()
|
||||||
|
self.frame_applet.bind('<Configure>', lambda event: self.resize_widget_font(self.frame_applet, label_clock))
|
||||||
|
self.resize_widget_font(self.frame_applet, label_clock)
|
||||||
|
|
||||||
|
|
||||||
|
'''count
|
||||||
|
###### ##### ### ### ##### #######
|
||||||
|
####### ####### ### ### ####### #######
|
||||||
|
### ### ### ### ### ### ### ###
|
||||||
|
####### ####### ####### ### ### ###
|
||||||
|
###### ##### ##### ### ### ###
|
||||||
|
'''
|
||||||
|
def build_gui_countdown(self):
|
||||||
|
|
||||||
|
def toggle_mode():
|
||||||
|
reset_countdown()
|
||||||
|
|
||||||
|
if label_countdown.mode is 'until':
|
||||||
|
for item in elements_until:
|
||||||
|
item.grid_forget()
|
||||||
|
button_reset.grid(row=0, column=6)
|
||||||
|
spinbox_hour.configure(to=999)
|
||||||
|
label_countdown.mode = 'in'
|
||||||
|
else:
|
||||||
|
spinbox_day.grid(row=0, column=1)
|
||||||
|
spinbox_month.grid(row=0, column=2)
|
||||||
|
spinbox_year.grid(row=0, column=3)
|
||||||
|
spinbox_hour.configure(to=23)
|
||||||
|
#button_reset.grid_forget()
|
||||||
|
label_countdown.mode = 'until'
|
||||||
|
button_countdownmode.configure(text=label_countdown.mode)
|
||||||
|
|
||||||
|
def tick_countdown():
|
||||||
|
if this_instance != self.instance:
|
||||||
|
return
|
||||||
|
if not label_countdown.is_running:
|
||||||
|
return
|
||||||
|
|
||||||
|
now = time.time()
|
||||||
|
if now > label_countdown.destination:
|
||||||
|
reset_countdown()
|
||||||
|
return
|
||||||
|
|
||||||
|
until_dest = label_countdown.destination - now
|
||||||
|
hours, minutes, seconds = self.hms_divmod(until_dest)
|
||||||
|
display = '%02d:%02d:%04.1f' % (hours, minutes, seconds)
|
||||||
|
display = display.replace('60.0', '00.0')
|
||||||
|
previous_size = len(label_countdown.cget('text'))
|
||||||
|
label_countdown.configure(text=display)
|
||||||
|
if len(display) != previous_size:
|
||||||
|
self.resize_widget_font(frame_display, label_countdown)
|
||||||
|
self.t.after(100, tick_countdown)
|
||||||
|
|
||||||
|
def start_countdown():
|
||||||
|
if label_countdown.mode is 'until':
|
||||||
|
if label_countdown.destination is None:
|
||||||
|
try:
|
||||||
|
d = int(spinbox_day.get())
|
||||||
|
mo = MONTHS_DICT[spinbox_month.get()]
|
||||||
|
y = int(spinbox_year.get())
|
||||||
|
h = int(spinbox_hour.get())
|
||||||
|
m = int(spinbox_minute.get())
|
||||||
|
s = int(spinbox_second.get())
|
||||||
|
|
||||||
|
strp = '%d %s %d %d %d %d' % (d, mo, y, h, m, s)
|
||||||
|
strp = datetime.datetime.strptime(strp, '%d %m %Y %H %M %S')
|
||||||
|
label_countdown.destination = strp.timestamp()
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
now = time.time()
|
||||||
|
if label_countdown.destination is None:
|
||||||
|
try:
|
||||||
|
h = int(spinbox_hour.get())
|
||||||
|
m = int(spinbox_minute.get())
|
||||||
|
s = int(spinbox_second.get())
|
||||||
|
label_countdown.destination = now + (3600*h) + (60*m) + (s)
|
||||||
|
except ValueError:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
backlog = now - label_countdown.backlog
|
||||||
|
#print(backlog)
|
||||||
|
label_countdown.destination += backlog
|
||||||
|
label_countdown.is_running = True
|
||||||
|
button_toggle.configure(text='stop')
|
||||||
|
tick_countdown()
|
||||||
|
|
||||||
|
def stop_countdown():
|
||||||
|
if label_countdown.mode is 'until':
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
label_countdown.backlog = time.time()
|
||||||
|
label_countdown.is_running = False
|
||||||
|
button_toggle.configure(text='start')
|
||||||
|
|
||||||
|
def reset_countdown():
|
||||||
|
stop_countdown()
|
||||||
|
label_countdown.configure(text='00:00:00.0')
|
||||||
|
label_countdown.destination = None
|
||||||
|
label_countdown.backlog = 0
|
||||||
|
|
||||||
|
def toggle_countdown():
|
||||||
|
if label_countdown.is_running is True:
|
||||||
|
stop_countdown()
|
||||||
|
else:
|
||||||
|
start_countdown()
|
||||||
|
|
||||||
|
def reset_spinboxes():
|
||||||
|
for item in (spinbox_hour, spinbox_minute, spinbox_second, spinbox_day, spinbox_month, spinbox_year):
|
||||||
|
item.configure(bg=COLOR_BACKGROUND, fg=COLOR_FONT, buttonbackground=COLOR_DROPDOWN, activebackground=COLOR_DROPDOWN_ACTIVE)
|
||||||
|
item.delete(0, 'end')
|
||||||
|
|
||||||
|
spinbox_hour.insert(0, 0)
|
||||||
|
spinbox_minute.insert(0, 0)
|
||||||
|
spinbox_second.insert(0, 0)
|
||||||
|
spinbox_day.insert(0, time.strftime('%d'))
|
||||||
|
spinbox_month.insert(0, time.strftime('%b').lower())
|
||||||
|
spinbox_year.insert(0, time.strftime('%Y'))
|
||||||
|
|
||||||
|
this_instance = self.instance
|
||||||
|
|
||||||
|
elements_until = []
|
||||||
|
|
||||||
|
frame_display = tkinter.Frame(self.frame_applet, bg=COLOR_BACKGROUND)
|
||||||
|
frame_controls = tkinter.Frame(self.frame_applet, bg=COLOR_BACKGROUND)
|
||||||
|
frame_spinboxes = tkinter.Frame(frame_controls, bg=COLOR_BACKGROUND)
|
||||||
|
label_countdown = tkinter.Label(frame_display, text='00:00:00.0', bg=COLOR_BACKGROUND, fg=COLOR_FONT)
|
||||||
|
label_countdown.mode = 'until'
|
||||||
|
label_countdown.destination = None
|
||||||
|
label_countdown.backlog = 0
|
||||||
|
label_countdown.is_running = False
|
||||||
|
button_countdownmode = tkinter.Button(frame_controls, text='0', command=toggle_mode, bg=COLOR_DROPDOWN, activebackground=COLOR_DROPDOWN_ACTIVE)
|
||||||
|
button_countdownmode.configure(width=5)
|
||||||
|
button_toggle = tkinter.Button(frame_controls, text='start', command=toggle_countdown, bg=COLOR_DROPDOWN, activebackground=COLOR_DROPDOWN_ACTIVE)
|
||||||
|
button_reset = tkinter.Button(frame_controls, text='reset', command=reset_countdown, bg=COLOR_DROPDOWN, activebackground=COLOR_DROPDOWN_ACTIVE)
|
||||||
|
|
||||||
|
spinbox_hour = tkinter.Spinbox(frame_spinboxes, from_=0, to=999, width=3)
|
||||||
|
spinbox_minute = tkinter.Spinbox(frame_spinboxes, from_=0, to=59, width=2)
|
||||||
|
spinbox_second = tkinter.Spinbox(frame_spinboxes, from_=0, to=59, width=2)
|
||||||
|
|
||||||
|
spinbox_day = tkinter.Spinbox(frame_spinboxes, from_=0, to=31, width=2)
|
||||||
|
spinbox_month = tkinter.Spinbox(frame_spinboxes, values=MONTHS, width=4)
|
||||||
|
spinbox_year = tkinter.Spinbox(frame_spinboxes, from_=2015, to=9999, width=4)
|
||||||
|
|
||||||
|
reset_spinboxes()
|
||||||
|
|
||||||
|
self.frame_applet.rowconfigure(0, weight=1)
|
||||||
|
self.frame_applet.columnconfigure(0, weight=1)
|
||||||
|
frame_controls.columnconfigure(1, weight=1)
|
||||||
|
|
||||||
|
frame_display.grid(row=0, column=0, sticky='news')
|
||||||
|
label_countdown.pack(anchor='center', expand=True)
|
||||||
|
|
||||||
|
frame_controls.grid(row=1, column=0, sticky='ew')
|
||||||
|
button_countdownmode.grid(row=0, column=0, sticky='ew')
|
||||||
|
frame_spinboxes.grid(row=0, column=1, sticky='ew')
|
||||||
|
spinbox_hour.grid(row=0, column=4)
|
||||||
|
spinbox_minute.grid(row=0, column=5)
|
||||||
|
spinbox_second.grid(row=0, column=6)
|
||||||
|
button_toggle.grid(row=0, column=7)
|
||||||
|
|
||||||
|
self.elements.append(frame_display)
|
||||||
|
self.elements.append(frame_controls)
|
||||||
|
self.elements.append(frame_spinboxes)
|
||||||
|
self.elements.append(label_countdown)
|
||||||
|
self.elements.append(button_countdownmode)
|
||||||
|
self.elements.append(spinbox_hour)
|
||||||
|
self.elements.append(spinbox_minute)
|
||||||
|
self.elements.append(spinbox_second)
|
||||||
|
self.elements.append(button_toggle)
|
||||||
|
self.elements.append(button_reset)
|
||||||
|
|
||||||
|
elements_until.append(spinbox_day)
|
||||||
|
elements_until.append(spinbox_month)
|
||||||
|
elements_until.append(spinbox_year)
|
||||||
|
|
||||||
|
toggle_mode()
|
||||||
|
self.frame_applet.bind('<Configure>', lambda event: self.resize_widget_font(frame_display, label_countdown))
|
||||||
|
self.t.update()
|
||||||
|
self.resize_widget_font(frame_display, label_countdown)
|
||||||
|
|
||||||
|
|
||||||
|
'''stop
|
||||||
|
##### ####### ##### ######
|
||||||
|
####### ####### ####### ### ###
|
||||||
|
### ### ### ### ######
|
||||||
|
####### ### ####### ###
|
||||||
|
##### ### ##### ###
|
||||||
|
'''
|
||||||
|
def build_gui_stopwatch(self):
|
||||||
|
|
||||||
|
def tick_stopwatch():
|
||||||
|
if this_instance != self.instance:
|
||||||
|
return
|
||||||
|
if not label_stopwatch.is_running:
|
||||||
|
return
|
||||||
|
elapsed = time.time() - label_stopwatch.started_at
|
||||||
|
elapsed += label_stopwatch.backlog
|
||||||
|
|
||||||
|
hours, minutes, seconds = self.hms_divmod(elapsed)
|
||||||
|
#seconds, centi = divmod(seconds, 100)
|
||||||
|
display = '%02d:%02d:%06.3f' % (hours, minutes, seconds)
|
||||||
|
display = display.replace('60.0', '00.0')
|
||||||
|
previous_size = len(label_stopwatch.cget('text'))
|
||||||
|
label_stopwatch.configure(text=display)
|
||||||
|
if len(display) != previous_size:
|
||||||
|
self.resize_widget_font(frame_display, label_stopwatch)
|
||||||
|
self.t.after(10, tick_stopwatch)
|
||||||
|
|
||||||
|
def toggle_stopwatch(*event):
|
||||||
|
if label_stopwatch.is_running:
|
||||||
|
stop_stopwatch()
|
||||||
|
else:
|
||||||
|
start_stopwatch()
|
||||||
|
|
||||||
|
def stop_stopwatch():
|
||||||
|
if label_stopwatch.started_at is not None:
|
||||||
|
elapsed = time.time() - label_stopwatch.started_at
|
||||||
|
label_stopwatch.backlog += elapsed
|
||||||
|
label_stopwatch.started_at = None
|
||||||
|
label_stopwatch.is_running = False
|
||||||
|
button_toggle.configure(text='start')
|
||||||
|
|
||||||
|
def start_stopwatch():
|
||||||
|
label_stopwatch.started_at = time.time()
|
||||||
|
label_stopwatch.is_running = True
|
||||||
|
button_toggle.configure(text='stop')
|
||||||
|
tick_stopwatch()
|
||||||
|
|
||||||
|
def reset_stopwatch(*event):
|
||||||
|
stop_stopwatch()
|
||||||
|
label_stopwatch.backlog = 0
|
||||||
|
label_stopwatch.configure(text='00:00:00.000')
|
||||||
|
|
||||||
|
this_instance = self.instance
|
||||||
|
|
||||||
|
frame_display = tkinter.Frame(self.frame_applet, bg=COLOR_BACKGROUND)
|
||||||
|
frame_controls = tkinter.Frame(self.frame_applet, bg=COLOR_BACKGROUND)
|
||||||
|
label_stopwatch = tkinter.Label(frame_display, text='00:00:00.000', bg=COLOR_BACKGROUND, fg=COLOR_FONT)
|
||||||
|
label_stopwatch.started_at = None
|
||||||
|
# Backlog keeps track of how much time was on the watch when we stopped it
|
||||||
|
# So when we start it again, the counter starts from 0 and we add the backlog
|
||||||
|
# to get a total.
|
||||||
|
label_stopwatch.backlog = 0
|
||||||
|
label_stopwatch.is_running = False
|
||||||
|
button_toggle = tkinter.Button(frame_controls, text='start', command=toggle_stopwatch, bg=COLOR_DROPDOWN, activebackground=COLOR_DROPDOWN_ACTIVE)
|
||||||
|
button_reset = tkinter.Button(frame_controls, text='reset', command=reset_stopwatch, bg=COLOR_DROPDOWN, activebackground=COLOR_DROPDOWN_ACTIVE)
|
||||||
|
|
||||||
|
self.frame_applet.rowconfigure(0, weight=1)
|
||||||
|
self.frame_applet.columnconfigure(0, weight=1)
|
||||||
|
frame_display.grid(row=0, column=0, sticky='news')
|
||||||
|
label_stopwatch.pack(anchor='center', expand=True)
|
||||||
|
|
||||||
|
frame_controls.grid(row=1, column=0, sticky='ew')
|
||||||
|
frame_controls.columnconfigure(0, weight=1)
|
||||||
|
frame_controls.columnconfigure(1, weight=1)
|
||||||
|
button_toggle.grid(row=0, column=1, sticky='ew')
|
||||||
|
button_reset.grid(row=0, column=0, sticky='ew')
|
||||||
|
|
||||||
|
self.elements.append(frame_display)
|
||||||
|
self.elements.append(frame_controls)
|
||||||
|
self.elements.append(label_stopwatch)
|
||||||
|
self.elements.append(button_toggle)
|
||||||
|
self.elements.append(button_reset)
|
||||||
|
|
||||||
|
self.frame_applet.bind('<Configure>', lambda event: self.resize_widget_font(frame_display, label_stopwatch))
|
||||||
|
# Update so that the window width and height are correct
|
||||||
|
# when we call resize_widget_font
|
||||||
|
self.t.update()
|
||||||
|
self.resize_widget_font(frame_display, label_stopwatch)
|
||||||
|
|
||||||
|
|
||||||
|
'''other
|
||||||
|
##### ####### ### ### ####### ######
|
||||||
|
####### ####### ### ### ##### ### ###
|
||||||
|
### ### ### ####### ### ######
|
||||||
|
####### ### ### ### ##### ### ###
|
||||||
|
##### ### ### ### ####### ### ###
|
||||||
|
'''
|
||||||
|
def resize_widget_font(self, parent, subordinate):
|
||||||
|
self.t.update()
|
||||||
|
frame_w = parent.winfo_width()
|
||||||
|
frame_h = parent.winfo_height()
|
||||||
|
#print(frame_w, frame_h)
|
||||||
|
text = subordinate.cget('text')
|
||||||
|
font = self.font_by_pixels(frame_w, frame_h, text)
|
||||||
|
|
||||||
|
subordinate.configure(font=font)
|
||||||
|
|
||||||
|
def font_by_pixels(self, frame_w, frame_h, text):
|
||||||
|
lines = text.split('\n')
|
||||||
|
label_w = max(len(line) for line in lines)
|
||||||
|
label_h = len(lines)
|
||||||
|
|
||||||
|
# Padding to not look dumb
|
||||||
|
frame_h -= 20
|
||||||
|
|
||||||
|
# At 72 ppi, 1 point = 1 pixel height
|
||||||
|
point_heightbased = int(frame_h / label_h)
|
||||||
|
# but width requires involving the ratio
|
||||||
|
point_widthbased = int(frame_w * FONT_YX_RATIO / label_w)
|
||||||
|
|
||||||
|
point_smaller = min(point_widthbased, point_heightbased)
|
||||||
|
point_smaller = max(point_smaller, 1)
|
||||||
|
font = (FONT, point_smaller)
|
||||||
|
|
||||||
|
return font
|
||||||
|
|
||||||
|
def hms_divmod(self, amount):
|
||||||
|
hours, minutes = divmod(amount, 3600)
|
||||||
|
minutes, seconds = divmod(minutes, 60)
|
||||||
|
|
||||||
|
return hours, minutes, seconds
|
||||||
|
|
||||||
|
def trigger_choose_mode(self, *args):
|
||||||
|
'''
|
||||||
|
This method is fired when the drop-down menu item is selected.
|
||||||
|
It will choose which build_gui method to use based on the value
|
||||||
|
of the optionmenu text.
|
||||||
|
'''
|
||||||
|
mode = self.mode
|
||||||
|
self.t.title(mode)
|
||||||
|
method = self.mode_methods[mode]
|
||||||
|
self.instance += 1
|
||||||
|
self.delete_applet_elements()
|
||||||
|
method()
|
||||||
|
|
||||||
|
c = Clock()
|
|
@ -50,6 +50,20 @@ class TextureTile:
|
||||||
|
|
||||||
self.t.mainloop()
|
self.t.mainloop()
|
||||||
|
|
||||||
|
def fit_into_bounds(self, iw, ih, fw, fh):
|
||||||
|
'''
|
||||||
|
Given the w+h of the image and the w+h of the frame,
|
||||||
|
return new w+h that fits the image into the frame
|
||||||
|
while maintaining the aspect ratio and leaving blank space
|
||||||
|
everywhere else
|
||||||
|
'''
|
||||||
|
ratio = min(fw/iw, fh/ih)
|
||||||
|
|
||||||
|
w = int(iw * ratio)
|
||||||
|
h = int(ih * ratio)
|
||||||
|
|
||||||
|
return (w, h)
|
||||||
|
|
||||||
def file_load_display(self, *event):
|
def file_load_display(self, *event):
|
||||||
filename = self.entry_filename.get()
|
filename = self.entry_filename.get()
|
||||||
# I want to check the spinbox values up
|
# I want to check the spinbox values up
|
||||||
|
@ -79,12 +93,9 @@ class TextureTile:
|
||||||
h = expanded.size[1]
|
h = expanded.size[1]
|
||||||
fw = self.label_image.winfo_width()
|
fw = self.label_image.winfo_width()
|
||||||
fh = self.label_image.winfo_height()
|
fh = self.label_image.winfo_height()
|
||||||
ratio = min(fw/w, fh/h)
|
wh = self.fit_into_bounds(w, h, fw, fh)
|
||||||
|
|
||||||
w = int(w * ratio)
|
|
||||||
h = int(h * ratio)
|
|
||||||
|
|
||||||
expanded = expanded.resize((w, h))
|
expanded = expanded.resize(wh)
|
||||||
image = ImageTk.PhotoImage(expanded)
|
image = ImageTk.PhotoImage(expanded)
|
||||||
self.label_image.configure(image=image)
|
self.label_image.configure(image=image)
|
||||||
self.label_image.dont_garbage_me_bro = image
|
self.label_image.dont_garbage_me_bro = image
|
||||||
|
|
|
@ -3,6 +3,9 @@ Toddo
|
||||||
|
|
||||||
Commandline to-do-list manager.
|
Commandline to-do-list manager.
|
||||||
|
|
||||||
|
07 August 2015
|
||||||
|
- sqlite connection and cursor will now lazy-load instead of loading
|
||||||
|
when the object is instantiated.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://github.com/voussoir/else/blob/master/.GitImages/toddo01.png?raw=true" alt="to-do list manager"/>
|
<img src="https://github.com/voussoir/else/blob/master/.GitImages/toddo01.png?raw=true" alt="to-do list manager"/>
|
||||||
|
|
BIN
Toddo/toddo.db
BIN
Toddo/toddo.db
Binary file not shown.
|
@ -28,16 +28,35 @@ Use `toddo all` to see if there are entries for other tables.'''
|
||||||
|
|
||||||
HELP_REMOVE = '''Provide an ID number to remove.'''
|
HELP_REMOVE = '''Provide an ID number to remove.'''
|
||||||
|
|
||||||
|
DISPLAY_INDIVIDUAL = '''
|
||||||
|
ID: _id_
|
||||||
|
Table: _table_
|
||||||
|
Created: _human_
|
||||||
|
Message: _message_'''
|
||||||
|
|
||||||
class ToddoExc(Exception):
|
class ToddoExc(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Toddo():
|
class Toddo():
|
||||||
def __init__(self, dbname='C:/git/else/toddo/toddo.db'):
|
def __init__(self, dbname='C:/git/else/toddo/toddo.db'):
|
||||||
self.sql = sqlite3.connect(dbname)
|
self.dbname = dbname
|
||||||
self.cur = self.sql.cursor()
|
self._sql = None
|
||||||
self.cur.execute('CREATE TABLE IF NOT EXISTS meta(key TEXT, val TEXT)')
|
self._cur = None
|
||||||
self.cur.execute('CREATE TABLE IF NOT EXISTS todos(id INT, todotable TEXT, created INT, message TEXT)')
|
|
||||||
self.cur.execute('CREATE INDEX IF NOT EXISTS todoindex on todos(id)')
|
@property
|
||||||
|
def sql(self):
|
||||||
|
if self._sql is None:
|
||||||
|
self._sql = sqlite3.connect(self.dbname)
|
||||||
|
return self._sql
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cur(self):
|
||||||
|
if self._cur is None:
|
||||||
|
self._cur = self.sql.cursor()
|
||||||
|
self._cur.execute('CREATE TABLE IF NOT EXISTS meta(key TEXT, val TEXT)')
|
||||||
|
self._cur.execute('CREATE TABLE IF NOT EXISTS todos(id INT, todotable TEXT, created INT, message TEXT)')
|
||||||
|
self._cur.execute('CREATE INDEX IF NOT EXISTS todoindex on todos(id)')
|
||||||
|
return self._cur
|
||||||
|
|
||||||
def add_todo(self, message=None):
|
def add_todo(self, message=None):
|
||||||
'''
|
'''
|
||||||
|
@ -88,8 +107,14 @@ class Toddo():
|
||||||
width = shutil.get_terminal_size()[0] - (messageleft + 1)
|
width = shutil.get_terminal_size()[0] - (messageleft + 1)
|
||||||
message = nicewrap(message, width, messageleft)
|
message = nicewrap(message, width, messageleft)
|
||||||
|
|
||||||
return 'ID: %d\nTable: %s\nCreated: %s\nMessage: %s' % (
|
output = DISPLAY_INDIVIDUAL
|
||||||
todo[SQL_ID], todo[SQL_TODOTABLE], human(todo[SQL_CREATED]), message)
|
output = output.replace('_id_', str(todo[SQL_ID]))
|
||||||
|
output = output.replace('_table_', todo[SQL_TODOTABLE])
|
||||||
|
output = output.replace('_human_', human(todo[SQL_CREATED]))
|
||||||
|
output = output.replace('_message_', message)
|
||||||
|
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
def display_active_todos(self):
|
def display_active_todos(self):
|
||||||
'''
|
'''
|
||||||
|
|
Loading…
Reference in a new issue