Skip to content

Commit

Permalink
Add Tkinter variant, along with some refactoring
Browse files Browse the repository at this point in the history
Remove obsolete ui/common.py.
  • Loading branch information
tifv committed Aug 20, 2013
1 parent b0c1bba commit 2715043
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 106 deletions.
4 changes: 3 additions & 1 deletion __init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
def main(*, seconds, precision=0, flavour, ui, immediate, font_size):
def main(*, seconds, precision, flavour, ui, immediate, font_size):
if flavour == 'regular':
from .core import TimerCore as FlavourTimerCore
title = 'Regular timer'
Expand All @@ -14,6 +14,8 @@ def main(*, seconds, precision=0, flavour, ui, immediate, font_size):
from .ui.gtk import GtkTimerCore as UITimerCore
elif ui == 'qt':
from .ui.qt import QtTimerCore as UITimerCore
elif ui == 'tk':
from .ui.tk import TkTimerCore as UITimerCore
else:
raise ValueError(ui)
class TheTimerCore(UITimerCore, FlavourTimerCore):
Expand Down
19 changes: 12 additions & 7 deletions __main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@

import argparse
parser = argparse.ArgumentParser(
prog=PROG, description="Timer" )
prog=PROG, description='Timer' )
parser.add_argument('seconds', type=float,
metavar='DURATION', help='timer duration' )
parser.add_argument('-p', '--precision', type=int,
default=0, const=1, nargs='?',
help='print fractions of seconds' )
parser.add_argument('-i', '--immediate',
action='store_true',
help='start timer immediately')

parser.add_argument('-f', '--font-size', type=float, default=100,
help='label font size')
help='start timer immediately' )
parser.add_argument('-f', '--font-size', type=float,
default=100,
help='label font size' )

flavour_group = parser.add_mutually_exclusive_group()
flavour_group.add_argument('-P', '--poisson',
Expand All @@ -36,11 +36,16 @@
ui_group.add_argument('--qt',
action='store_const', dest='ui', const='qt',
help='use Qt 4 (default)' )
parser.set_defaults(ui='qt')
ui_group.add_argument('--tk',
action='store_const', dest='ui', const='tk',
help='use Qt 4 (default)' )
parser.set_defaults(ui='tk')

args = parser.parse_args()
if (args.precision < 0):
if args.precision < 0:
parser.error('precision must be non-negative')
if args.precision > 0 and args.flavour == 'poisson':
parser.error('Poisson timer does not allow non-zero precision')

main(**vars(args))

21 changes: 19 additions & 2 deletions core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ def __init__(self, seconds, precision):

self.state = 'paused'

self.update_label()

def time(self):
return time()

Expand All @@ -19,12 +21,15 @@ def interact(self):
self.start()
elif self.state in {'exhausted'}:
self.shutdown()
elif self.state in {'shutdown'}:
raise AssertionError

def close(self):
try:
if self.state in {'running', 'paused'}:
self.print_remained()
finally:
self.state = 'shutdown'
self.shutdown()

def update(self):
Expand All @@ -34,7 +39,8 @@ def update(self):
self.stop_timeout()

def update_label(self):
self.show_remained(self.get_remained())
remained = self.get_remained()
self.set_label_text(self.format_remained(remained), finished=remained <= 0.0)

def get_remained(self):
if self.state in {'running'}:
Expand All @@ -48,16 +54,20 @@ def get_remained(self):
return self.remained
if self.state in {'exhausted'}:
return 0.0
if self.state in {'shutdown'}:
raise AssertionError

def start(self):
assert self.state in {'paused'}
assert self.remained > 0.0
self.registered_time = self.time()
self.state = 'running'
self.start_timeout()

def pause(self):
assert self.state in {'running'}
self.update_time()
self.stop_timeout()
if self.remained <= 0.0:
self.state = 'exhausted'
else:
Expand Down Expand Up @@ -95,5 +105,12 @@ def mainloop(self):
def shutdown(self):
raise NotImplementedError

def show_remained(self, remained):
def set_label_text(self, text, finished=False):
raise NotImplementedError

def start_timeout(self):
raise NotImplementedError

def stop_timeout(self):
raise NotImplementedError

7 changes: 4 additions & 3 deletions flavour/poisson.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
from ..core import TimerCore

class PoissonTimerCore(TimerCore):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.remained = int(self.remained)
def __init__(self, seconds, precision, *args, **kwargs):
seconds = int(seconds)
assert precision == 0
super().__init__(seconds, precision, *args, **kwargs)

def update_time(self):
passed_time = self.time() - self.registered_time
Expand Down
6 changes: 3 additions & 3 deletions flavour/wiener.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from ..core import TimerCore

class WienerTimerCore(TimerCore):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.remained = sqrt(self.remained)
def __init__(self, seconds, *args, **kwargs):
seconds = sqrt(seconds)
super().__init__(seconds, *args, **kwargs)

def get_remained(self):
remained = super().get_remained()
Expand Down
52 changes: 0 additions & 52 deletions ui/common.py

This file was deleted.

34 changes: 12 additions & 22 deletions ui/gtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
from ..core import TimerCore

class GtkTimerCore(TimerCore):
def __init__(self, *args, title='timer', font_size=100, **kwargs):
super().__init__(*args, **kwargs)

def __init__(self, *args, title, font_size, **kwargs):
def close_handler(widget, event):
self.close()
def clicked_handler(widget):
Expand All @@ -17,25 +15,22 @@ def clicked_handler(widget):
self.master.add(self.label)
self.label_font_size = int(1000 * font_size)

self.control_master = Gtk.Window(
self.control = Gtk.Window(
title=title + ' (control)',
default_width=150, default_height=150
)
self.control_master.connect('delete-event', close_handler)
self.control.connect('delete-event', close_handler)
self.button = Gtk.Button()
self.button.set_label('Start/Pause')
self.button.connect('clicked', clicked_handler)
self.control_master.add(self.button)
self.control.add(self.button)

self.timeout_id = None
self.update_label()

self.master.show_all()
self.control_master.show_all()
self.control.show_all()

def start(self):
super().start()
self.start_timeout()
super().__init__(*args, **kwargs)

def start_timeout(self):
assert self.timeout_id is None
Expand All @@ -44,10 +39,6 @@ def timeout_call():
return True # continue timeout
self.timeout_id = GObject.timeout_add(25, timeout_call)

def pause(self):
super().pause()
self.stop_timeout()

def stop_timeout(self):
assert self.timeout_id is not None
GObject.source_remove(self.timeout_id)
Expand All @@ -59,12 +50,11 @@ def mainloop(self):
def shutdown(self):
Gtk.main_quit()

def show_remained(self, remained):
self.set_label_markup(self.format_remained(remained),
colour='black' if remained > 0.0 else 'red' )

def set_label_markup(self, label, colour='black'):
def set_label_text(self, text, finished=False):
self.label.set_markup(
'<span font_size="{size}" foreground="{colour}">{label}</span>'
.format(label=label, colour=colour, size=self.label_font_size) )
'<span font_size="{size}" foreground="{colour}">{text}</span>'
.format(text=text,
colour='black' if not finished else 'red',
size=self.label_font_size )
)

21 changes: 5 additions & 16 deletions ui/qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
from ..core import TimerCore

class QtTimerCore(TimerCore):
def __init__(self, *args, title='timer', font_size=100, **kwargs):
super().__init__(*args, **kwargs)

def __init__(self, *args, title, font_size, **kwargs):
self.qapp = QtGui.QApplication([])

self.master = MasterWindow()
Expand Down Expand Up @@ -36,22 +34,15 @@ def __init__(self, *args, title='timer', font_size=100, **kwargs):
self.control.setLayout(control_layout)

self.master.timer_callback = self.update
self.update_label()

self.master.show()
self.control.show()

def start(self):
super().start()
self.start_timeout()
super().__init__(*args, **kwargs)

def start_timeout(self):
self.timer_id = self.master.startTimer(25)

def pause(self):
super().pause()
self.stop_timeout()

def stop_timeout(self):
self.master.killTimer(self.timer_id)

Expand All @@ -61,11 +52,9 @@ def mainloop(self):
def shutdown(self):
return self.qapp.quit()

def show_remained(self, remained):
self.label.setText(self.format_remained(remained))
if remained > 0.0:
pass
else:
def set_label_text(self, text, finished=False):
self.label.setText(text)
if finished:
self.label.setStyleSheet('QLabel { color : red; }')

class Window(QtGui.QWidget):
Expand Down
53 changes: 53 additions & 0 deletions ui/tk.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from tkinter import Tk, Toplevel, Label, Button

from ..core import TimerCore

class TkTimerCore(TimerCore):
def __init__(self, *args, title, font_size, **kwargs):
def close_handler(event):
self.close()
def clicked_handler(event):
self.interact()

self.master = Tk()
self.master.wm_title(title)
self.master.bind('<Destroy>', close_handler)
self.label = Label(self.master, font='Sans {}'.format(font_size))
self.label.pack(expand=True)

self.control = Toplevel()
self.control.wm_title(title + ' (control)')
self.control.minsize(150, 150)
self.control.bind('<Destroy>', close_handler)
self.button = Button(self.control, text='Start/Pause')
self.button.bind('<ButtonRelease>', clicked_handler)
self.button.pack(expand=True)

self.timeout_running = False

super().__init__(*args, **kwargs)

def start_timeout(self):
assert self.timeout_running is False
def timeout_call():
self.update()
if self.timeout_running:
self.master.after(25, timeout_call)
self.timeout_running = True
timeout_call()

def stop_timeout(self):
assert self.timeout_running is True
self.timeout_running = False

def mainloop(self):
return self.master.mainloop()

def shutdown(self):
self.master.quit()

def set_label_text(self, text, finished=False):
self.label.config(text=text)
if finished:
self.label.config(fg='red')

0 comments on commit 2715043

Please sign in to comment.