From a34b38b2a3619e1de6ef3eee59b4bf97e2f891ab Mon Sep 17 00:00:00 2001 From: Chris Lucian Date: Thu, 28 Jan 2016 00:33:10 -0800 Subject: [PATCH] Separated classes into files and created a setup.py --- Controllers/SpeedReaderController.py | 11 ++++ Controllers/__init__.py | 0 Frames/MainFrame.py | 97 ++++++++++++++++++++++++++++ Frames/__init__.py | 0 SpeedReader.py | 96 +-------------------------- setup.py | 34 ++++++++++ 6 files changed, 143 insertions(+), 95 deletions(-) create mode 100644 Controllers/SpeedReaderController.py create mode 100644 Controllers/__init__.py create mode 100644 Frames/MainFrame.py create mode 100644 Frames/__init__.py create mode 100644 setup.py diff --git a/Controllers/SpeedReaderController.py b/Controllers/SpeedReaderController.py new file mode 100644 index 0000000..ea865db --- /dev/null +++ b/Controllers/SpeedReaderController.py @@ -0,0 +1,11 @@ +from Tkconstants import N, S, E, W +from Tkinter import Tk + +from Frames.MainFrame import MainFrame + + +class SpeedReaderController(Tk): + def __init__(self): + Tk.__init__(self) + main_frame = MainFrame() + main_frame.grid(padx=50, pady=50, sticky=(N, S, E, W)) \ No newline at end of file diff --git a/Controllers/__init__.py b/Controllers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Frames/MainFrame.py b/Frames/MainFrame.py new file mode 100644 index 0000000..9306994 --- /dev/null +++ b/Frames/MainFrame.py @@ -0,0 +1,97 @@ +import thread +import ttk +from Tkconstants import END, N, S, E, W, NORMAL, DISABLED +from Tkinter import Text + +import pyttsx + + +class MainFrame(ttk.Frame): + def __init__(self, **kw): + ttk.Frame.__init__(self, **kw) + self.engine = None + self.spoken_text = '' + self.highlight_index1 = None + self.highlight_index2 = None + self.build_frame_content(kw) + + def build_frame_content(self, kw): + row_index = 0 + self.current_word_label = ttk.Label(self, font=("Georgia", "52")) + self.current_word_label.grid(row=row_index, columnspan=2) + row_index += 1 + + self.speed_label = ttk.Label(self, text="Speed: ") + self.speed_label.grid(row=row_index, column=0, pady=10) + self.speed_entry = ttk.Entry(self) + self.speed_entry.insert(0, "500") + self.speed_entry.grid(row=row_index, column=1, pady=10) + row_index += 1 + + self.text_area = Text(self, height=50, width=190) + self.text_area.insert(END, '') + self.text_area.tag_config(TAG_CURRENT_WORD, foreground="red") + self.text_area.grid(row=row_index, columnspan=2, sticky=(N, S, E, W)) + row_index += 1 + + self.speak_button = ttk.Button(self, text="Speak") + self.speak_button.grid(row=row_index, column=0, pady=10) + self.speak_button['state'] = NORMAL + self.speak_button.bind("", self.speak) + + # self.stop_button = ttk.Button(self, text="Stop") + # self.stop_button.grid(row=row_index, column=1, pady=10) + # self.stop_button['state'] = DISABLED + # self.stop_button.bind("", self.stop) + + # def stop(self, event): + # if self.stop_button['state'].__str__() == NORMAL: + # self.engine.stop() + # self.speak_button['state'] = NORMAL + # self.stop_button['state'] = DISABLED + + def onStart(self, name): + self.speak_button['state'] = DISABLED + # self.stop_button['state'] = NORMAL + print("onStart") + + def onWord(self, name, location, length): + self.current_word_label['text'] = self.spoken_text[location:location + length] + if self.highlight_index1 is not None: + self.text_area.tag_remove(TAG_CURRENT_WORD, self.highlight_index1, self.highlight_index2) + self.highlight_index1 = "1.{}".format(location) + self.highlight_index2 = "1.{}".format(location + length) + self.text_area.tag_add(TAG_CURRENT_WORD, self.highlight_index1, self.highlight_index2) + + def onEnd(self, name, completed): + self.speak_button['state'] = NORMAL + print("onEnd") + + def speak(self, event): + if self.speak_button['state'].__str__() == NORMAL: + + self.spoken_text = self.text_area.get("1.0", END).replace('\n', ' ') + self.text_area.delete("1.0", END) + self.text_area.insert(END, self.spoken_text) + + speech_speed = int(self.speed_entry.get()) + print("starting thread") + thread.start_new_thread(self.speak_on_thread, (speech_speed, self.spoken_text)) + + def speak_on_thread(self, speech_speed, spoken_text): + + if self.engine is None: + self.engine = pyttsx.init() + self.engine.setProperty('rate', speech_speed) + self.engine.connect('started-utterance', self.onStart) + self.engine.connect('started-word', self.onWord) + self.engine.connect('finished-utterance', self.onEnd) + self.engine.say(spoken_text) + self.engine.startLoop() + else: + self.engine.say(spoken_text) + + print("thread finished") + + +TAG_CURRENT_WORD = "current word" \ No newline at end of file diff --git a/Frames/__init__.py b/Frames/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/SpeedReader.py b/SpeedReader.py index f91b21e..dd85323 100644 --- a/SpeedReader.py +++ b/SpeedReader.py @@ -1,97 +1,3 @@ -import ttk -from Tkconstants import END, SEL, N, S, E, W, DISABLED, NORMAL -from Tkinter import Tk, Text -import pyttsx -import thread - -TAG_CURRENT_WORD = "current word" - - -class MainFrame(ttk.Frame): - def __init__(self, **kw): - ttk.Frame.__init__(self, **kw) - - self.spoken_text = '' - self.highlight_index1 = None - self.highlight_index2 = None - self.build_frame_content(kw) - - def build_frame_content(self, kw): - row_index = 0 - self.current_word_label = ttk.Label(self, font=("Georgia", "52")) - self.current_word_label.grid(row=row_index, columnspan=2) - row_index += 1 - - self.speed_label = ttk.Label(self, text="Speed: ") - self.speed_label.grid(row=row_index, column=0, pady=10) - self.speed_entry = ttk.Entry(self) - self.speed_entry.insert(0, "500") - self.speed_entry.grid(row=row_index, column=1, pady=10) - row_index += 1 - - self.text_area = Text(self, height=50, width=190) - self.text_area.insert(END, '') - self.text_area.tag_config(TAG_CURRENT_WORD, foreground="red") - self.text_area.grid(row=row_index, columnspan=2, sticky=(N, S, E, W)) - row_index += 1 - - self.speak_button = ttk.Button(self, text="Speak") - self.speak_button.grid(row=row_index, column=0, pady=10) - self.speak_button['state'] = NORMAL - self.speak_button.bind("", self.speak) - - # self.stop_button = ttk.Button(self, text="Stop") - # self.stop_button.grid(row=row_index, column=1, pady=10) - # self.stop_button['state'] = DISABLED - # self.stop_button.bind("", self.stop) - - # def stop(self, event): - # if self.stop_button['state'].__str__() == NORMAL: - # self.engine.stop() - # self.speak_button['state'] = NORMAL - # self.stop_button['state'] = DISABLED - - def onStart(self, name): - self.speak_button['state'] = DISABLED - # self.stop_button['state'] = NORMAL - - def onWord(self, name, location, length): - self.current_word_label['text'] = self.spoken_text[location:location + length] - if self.highlight_index1 is not None: - self.text_area.tag_remove(TAG_CURRENT_WORD, self.highlight_index1, self.highlight_index2) - self.highlight_index1 = "1.{}".format(location) - self.highlight_index2 = "1.{}".format(location + length) - self.text_area.tag_add(TAG_CURRENT_WORD, self.highlight_index1, self.highlight_index2) - - def onEnd(self, name, completed): - self.speak_button['state'] = NORMAL - - def speak(self, event): - if self.speak_button['state'].__str__() == NORMAL: - - self.spoken_text = self.text_area.get("1.0", END).replace('\n', ' ') - self.text_area.delete("1.0", END) - self.text_area.insert(END, self.spoken_text) - - speech_speed = int(self.speed_entry.get()) - thread.start_new_thread(self.speak_on_thread, (speech_speed, self.spoken_text)) - - def speak_on_thread(self, speech_speed, spoken_text): - self.engine = pyttsx.init() - self.engine.setProperty('rate', speech_speed) - self.engine.connect('started-utterance', self.onStart) - self.engine.connect('started-word', self.onWord) - self.engine.connect('finished-utterance', self.onEnd) - self.engine.say(spoken_text) - self.engine.runAndWait() - - -class SpeedReaderController(Tk): - def __init__(self): - Tk.__init__(self) - main_frame = MainFrame() - main_frame.grid(padx=50, pady=50, sticky=(N, S, E, W)) - - +from Controllers.SpeedReaderController import SpeedReaderController app = SpeedReaderController() app.mainloop() diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..88891e3 --- /dev/null +++ b/setup.py @@ -0,0 +1,34 @@ +import os +from distutils.core import setup + +import pathlib +import py2exe +import sys + +if len(sys.argv) == 1: + sys.argv.append("py2exe") +py2exe_options = { 'includes': ['pyttsx.drivers.sapi5', 'win32com.gen_py.C866CA3A-32F7-11D2-9602-00C04F8EE628x0x5x4'], + 'typelibs': [('{C866CA3A-32F7-11D2-9602-00C04F8EE628}', 0, 5, 4)] } + +tcl__path = '{}\\tcl\\tcl8.5\\init.tcl'.format(os.path.dirname(sys.executable)) +setup( + zipfile=None, + windows=[{"script": 'SpeedReader.py'}], + options = {'py2exe': py2exe_options}, + # data_files=[tcl__path], + requires=['pyttsx']) + +import zipfile + +def zipdir(path, ziph): + # ziph is zipfile handle + for root, dirs, files in os.walk(path): + for file in files: + destination_path = pathlib.Path(*pathlib.Path(os.path.join(root, file)).parts[1:]) + print(destination_path) + ziph.write(os.path.join(root, file), destination_path.__str__()) + +if __name__ == '__main__': + zipf = zipfile.ZipFile('SpeedReader.zip', 'w', zipfile.ZIP_DEFLATED) + zipdir('dist', zipf) + zipf.close() \ No newline at end of file