From 2f2077a8685bf81a6c369e6daa474786c3e81756 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 12:23:09 +0530 Subject: [PATCH 01/23] Add files via upload --- gui.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 gui.py diff --git a/gui.py b/gui.py new file mode 100644 index 0000000..9b22b34 --- /dev/null +++ b/gui.py @@ -0,0 +1,28 @@ +import tkinter as tk +from tkscrolledframe import ScrolledFrame + +root = tk.Tk() +scrolled_frame = ScrolledFrame(master=root) +main_frame = scrolled_frame.display_widget(tk.Frame) +speak_button = tk.Button(master=root, text='Speak', command=lambda: None) + + +def set_speak_command(command): + speak_button.configure(command=command) + + +speak_button.pack(side=tk.LEFT, anchor=tk.SW) + + +def conversation_label(text): + tk.Label(master=main_frame, text=text).pack() + + +def speak(text): + conversation_label(f'Assistant: {text}') + + +scrolled_frame.pack(fill=tk.BOTH) +root.wm_title('Desktop assistant') +root.resizable(False, False) +mainloop = root.mainloop From 935415f8f77b7630783231a2f941e8bb7cd48e4d Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 12:30:04 +0530 Subject: [PATCH 02/23] Update Jarvis2.py --- Jarvis2.py | 154 ++++++++++++++++++++++++++++------------------------- 1 file changed, 82 insertions(+), 72 deletions(-) diff --git a/Jarvis2.py b/Jarvis2.py index b37d890..b6736e5 100755 --- a/Jarvis2.py +++ b/Jarvis2.py @@ -12,6 +12,8 @@ import speech_recognition as sr import wikipedia +import gui + print("Initializing Jarvis....") MASTER = getpass.getuser() @@ -46,6 +48,7 @@ def search(search_query, search_engine): def speak(text): + gui.speak(text) engine.say(text) engine.runAndWait() @@ -95,79 +98,86 @@ def take_command(): speak("Initializing Jarvis....") wish_me() -query = take_command().lower() - -# logic for executing basic tasks -if "wikipedia" in query.lower(): - speak("Searching wikipedia....") - query = query.replace("wikipedia", "") - print_and_speak(wikipedia.summary(query, sentences=2)) - -elif "what's up" in query or "how are you" in query: - st_msgs = ( - "Just doing my thing!", - "I am fine!", - "Nice!", - "I am nice and full of energy", - ) - speak(random.choice(st_msgs)) - -elif "date" in query: - print_and_speak(f"{datetime.datetime.now():%A, %B %d, %Y}") - -elif "time" in query: - print_and_speak(f"{datetime.datetime.now():%I %M %p}") - -elif "open" in query.lower(): - website = query.replace("open", "").strip().lower() - try: - open_url(popular_websites[website]) - except IndexError: # If the website is unknown - print(f"Unknown website: {website}") - speak(f"Sorry, I don't know the website {website}") -elif "search" in query.lower(): - search_query = query.split("for")[-1] - search_engine = query.split("for")[0].replace("search", "").strip().lower() - search(search_query, search_engine) -elif "email" in query: - speak("Who is the recipient? ") - recipient = take_command() +def execute_the_command_said_by_user(): + query = take_command().lower() + + # logic for executing basic tasks + if "wikipedia" in query: + speak("Searching wikipedia....") + query = query.replace("wikipedia", "") + print_and_speak(wikipedia.summary(query, sentences=2)) + + elif "what's up" in query or "how are you" in query: + st_msgs = ( + "Just doing my thing!", + "I am fine!", + "Nice!", + "I am nice and full of energy", + ) + speak(random.choice(st_msgs)) + + elif "date" in query: + print_and_speak(f"{datetime.datetime.now():%A, %B %d, %Y}") + + elif "time" in query: + print_and_speak(f"{datetime.datetime.now():%I %M %p}") - if "me" in recipient: + elif "open" in query.lower(): + website = query.replace("open", "").strip().lower() try: - speak("What should I say? ") - content = take_command() - - server = smtplib.SMTP("smtp.gmail.com", 587) - server.ehlo() - server.starttls() - server.login("Your_Username", "Your_Password") - server.sendmail("Your_Username", "Recipient_Username", content) - server.close() - speak("Email sent!") - except Exception: - speak("Sorry Sir! I am unable to send your message at this moment!") - -elif "nothing" in query or "abort" in query or "stop" in query: - speak("okay") - speak("Bye Sir, have a good day.") - sys.exit() - -elif "hello" in query: - speak("Hello Sir") - -elif "bye" in query: - speak("Bye Sir, have a good day.") - sys.exit() - -elif "play music" in query: - music_folder = "Your_music_folder_path(absolute_path)" - music = ("music1", "music2", "music3", "music4", "music5") - random_music = music_folder + random.choice(music) + ".mp3" - os.system(random_music) - - speak("Playing your request") - -speak("Next Command! Sir!") + open_url(popular_websites[website]) + except IndexError: # If the website is unknown + print(f"Unknown website: {website}") + speak(f"Sorry, I don't know the website {website}") + + elif "search" in query.lower(): + search_query = query.split("for")[-1] + search_engine = query.split("for")[0].replace("search", "").strip().lower() + search(search_query, search_engine) + + elif "email" in query: + speak("Who is the recipient? ") + recipient = take_command() + + if "me" in recipient: + try: + speak("What should I say? ") + content = take_command() + + server = smtplib.SMTP("smtp.gmail.com", 587) + server.ehlo() + server.starttls() + server.login("Your_Username", "Your_Password") + server.sendmail("Your_Username", "Recipient_Username", content) + server.close() + speak("Email sent!") + except Exception: + speak("Sorry Sir! I am unable to send your message at this moment!") + + elif "nothing" in query or "abort" in query or "stop" in query: + speak("okay") + speak("Bye Sir, have a good day.") + sys.exit() + + elif "hello" in query: + speak("Hello Sir") + + elif "bye" in query: + speak("Bye Sir, have a good day.") + sys.exit() + + elif "play music" in query: + music_folder = "Your_music_folder_path(absolute_path)" + music = ("music1", "music2", "music3", "music4", "music5") + random_music = music_folder + random.choice(music) + ".mp3" + os.system(random_music) + + speak("Playing your request") + + speak("Next Command! Sir!") + + +gui.set_speak_command(execute_the_command_said_by_user) +gui.mainloop() From 1caf6f480477aacc03874cc4b6f1dc08f9d89358 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 12:32:05 +0530 Subject: [PATCH 03/23] Update Jarvis2_4windows.py --- Jarvis2_4windows.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py index 0294c51..82d5dac 100644 --- a/Jarvis2_4windows.py +++ b/Jarvis2_4windows.py @@ -9,6 +9,8 @@ import wikipedia from pygame import mixer +import gui + mixer.init() print("Initializing Jarvis....") @@ -45,6 +47,7 @@ def search(search_query, search_engine): def speak(text): + gui.speak(text) engine.say(text) engine.runAndWait() @@ -90,7 +93,9 @@ def take_command(): speak("Initializing Jarvis....") wish_me() -while True: + + +def execute_the_command_said_by_user(): query = take_command() # logic for executing basic tasks @@ -172,3 +177,7 @@ def take_command(): mixer.music.unpause() speak("Next Command! Sir!") + + +gui.set_speak_command(execute_the_command_said_by_user) +gui.mainloop() From f18e410f67f1163632d29834b15e6007adfb81ea Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 12:39:35 +0530 Subject: [PATCH 04/23] Update lint_python.yml --- .github/workflows/lint_python.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index d850a6f..d32ab8b 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -13,7 +13,8 @@ jobs: - run: black --check . || true - run: codespell --ignore-words-list=ans - run: flake8 . --count --max-complexity=19 --max-line-length=88 --show-source --statistics - - run: isort --check-only --profile black . + - run: python3 -m pip install isort + - run: isort --profile black . - run: pip install -r requirements.txt || pip install --editable . || true - run: mkdir --parents --verbose .mypy_cache - run: mypy --ignore-missing-imports --install-types --non-interactive . From 0b542d8d303753717ada756a75ba0b6ba9901cb7 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 12:43:13 +0530 Subject: [PATCH 05/23] Update lint_python.yml --- .github/workflows/lint_python.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index d32ab8b..d850a6f 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -13,8 +13,7 @@ jobs: - run: black --check . || true - run: codespell --ignore-words-list=ans - run: flake8 . --count --max-complexity=19 --max-line-length=88 --show-source --statistics - - run: python3 -m pip install isort - - run: isort --profile black . + - run: isort --check-only --profile black . - run: pip install -r requirements.txt || pip install --editable . || true - run: mkdir --parents --verbose .mypy_cache - run: mypy --ignore-missing-imports --install-types --non-interactive . From 71f1b4301ce15479e5893e21daafbc5a855e4278 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 13:13:02 +0530 Subject: [PATCH 06/23] Create tkscrolledframe --- tkscrolledframe | 317 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100644 tkscrolledframe diff --git a/tkscrolledframe b/tkscrolledframe new file mode 100644 index 0000000..5632098 --- /dev/null +++ b/tkscrolledframe @@ -0,0 +1,317 @@ +# Credit: https://github.com/bmjcode/tkScrolledFrame +"""Implementation of the scrollable frame widget.""" + +import sys + +try: + # Python 3 + import tkinter as tk +except (ImportError): + # Python 2 + import Tkinter as tk + +try: + try: + # Python 3 + import tkinter.ttk as ttk + except (ImportError): + # Python 2 + import ttk +except (ImportError): + # Can't provide ttk's Scrollbar + pass + + +__all__ = ["ScrolledFrame"] + + +class ScrolledFrame(tk.Frame): + """Scrollable Frame widget. + + Use display_widget() to set the interior widget. For example, + to display a Label with the text "Hello, world!", you can say: + + sf = ScrolledFrame(self) + sf.pack() + sf.display_widget(Label, text="Hello, world!") + + The constructor accepts the usual Tkinter keyword arguments, plus + a handful of its own: + + scrollbars (str; default: "both") + Which scrollbars to provide. + Must be one of "vertical", "horizontal," "both", or "neither". + + use_ttk (bool; default: False) + Whether to use ttk widgets if available. + The default is to use standard Tk widgets. This setting has + no effect if ttk is not available on your system. + """ + + def __init__(self, master=None, **kw): + """Return a new scrollable frame widget.""" + + tk.Frame.__init__(self, master) + + # Hold these names for the interior widget + self._interior = None + self._interior_id = None + + # Whether to fit the interior widget's width to the canvas + self._fit_width = False + + # Which scrollbars to provide + if "scrollbars" in kw: + scrollbars = kw["scrollbars"] + del kw["scrollbars"] + + if not scrollbars: + scrollbars = self._DEFAULT_SCROLLBARS + elif not scrollbars in self._VALID_SCROLLBARS: + raise ValueError("scrollbars parameter must be one of " + "'vertical', 'horizontal', 'both', or " + "'neither'") + else: + scrollbars = self._DEFAULT_SCROLLBARS + + # Whether to use ttk widgets if available + if "use_ttk" in kw: + if ttk and kw["use_ttk"]: + Scrollbar = ttk.Scrollbar + else: + Scrollbar = tk.Scrollbar + del kw["use_ttk"] + else: + Scrollbar = tk.Scrollbar + + # Default to a 1px sunken border + if not "borderwidth" in kw: + kw["borderwidth"] = 1 + if not "relief" in kw: + kw["relief"] = "sunken" + + # Set up the grid + self.grid_columnconfigure(0, weight=1) + self.grid_rowconfigure(0, weight=1) + + # Canvas to hold the interior widget + c = self._canvas = tk.Canvas(self, + borderwidth=0, + highlightthickness=0, + takefocus=0) + + # Enable scrolling when the canvas has the focus + self.bind_arrow_keys(c) + self.bind_scroll_wheel(c) + + # Call _resize_interior() when the canvas widget is updated + c.bind("", self._resize_interior) + + # Scrollbars + xs = self._x_scrollbar = Scrollbar(self, + orient="horizontal", + command=c.xview) + ys = self._y_scrollbar = Scrollbar(self, + orient="vertical", + command=c.yview) + c.configure(xscrollcommand=xs.set, yscrollcommand=ys.set) + + # Lay out our widgets + c.grid(row=0, column=0, sticky="nsew") + if scrollbars == "vertical" or scrollbars == "both": + ys.grid(row=0, column=1, sticky="ns") + if scrollbars == "horizontal" or scrollbars == "both": + xs.grid(row=1, column=0, sticky="we") + + # Forward these to the canvas widget + self.bind = c.bind + self.focus_set = c.focus_set + self.unbind = c.unbind + self.xview = c.xview + self.xview_moveto = c.xview_moveto + self.yview = c.yview + self.yview_moveto = c.yview_moveto + + # Process our remaining configuration options + self.configure(**kw) + + def __setitem__(self, key, value): + """Configure resources of a widget.""" + + if key in self._CANVAS_KEYS: + # Forward these to the canvas widget + self._canvas.configure(**{key: value}) + + else: + # Handle everything else normally + tk.Frame.configure(self, **{key: value}) + + # ------------------------------------------------------------------------ + + def bind_arrow_keys(self, widget): + """Bind the specified widget's arrow key events to the canvas.""" + + widget.bind("", + lambda event: self._canvas.yview_scroll(-1, "units")) + + widget.bind("", + lambda event: self._canvas.yview_scroll(1, "units")) + + widget.bind("", + lambda event: self._canvas.xview_scroll(-1, "units")) + + widget.bind("", + lambda event: self._canvas.xview_scroll(1, "units")) + + def bind_scroll_wheel(self, widget): + """Bind the specified widget's mouse scroll event to the canvas.""" + + widget.bind("", self._scroll_canvas) + widget.bind("", self._scroll_canvas) + widget.bind("", self._scroll_canvas) + + def cget(self, key): + """Return the resource value for a KEY given as string.""" + + if key in self._CANVAS_KEYS: + return self._canvas.cget(key) + + else: + return tk.Frame.cget(self, key) + + # Also override this alias for cget() + __getitem__ = cget + + def configure(self, cnf=None, **kw): + """Configure resources of a widget.""" + + # This is overridden so we can use our custom __setitem__() + # to pass certain options directly to the canvas. + if cnf: + for key in cnf: + self[key] = cnf[key] + + for key in kw: + self[key] = kw[key] + + # Also override this alias for configure() + config = configure + + def display_widget(self, widget_class, fit_width=False, **kw): + """Create and display a new widget. + + If fit_width == True, the interior widget will be stretched as + needed to fit the width of the frame. + + Keyword arguments are passed to the widget_class constructor. + + Returns the new widget. + """ + + # Blank the canvas + self.erase() + + # Set width fitting + self._fit_width = fit_width + + # Set the new interior widget + self._interior = widget_class(self._canvas, **kw) + + # Add the interior widget to the canvas, and save its widget ID + # for use in _resize_interior() + self._interior_id = self._canvas.create_window(0, 0, + anchor="nw", + window=self._interior) + + # Call _update_scroll_region() when the interior widget is resized + self._interior.bind("", self._update_scroll_region) + + # Fit the interior widget to the canvas if requested + # We don't need to check fit_width here since _resize_interior() + # already does. + self._resize_interior() + + # Scroll to the top-left corner of the canvas + self.scroll_to_top() + + return self._interior + + def erase(self): + """Erase the displayed widget.""" + + # Clear the canvas + self._canvas.delete("all") + + # Delete the interior widget + del self._interior + del self._interior_id + + # Save these names + self._interior = None + self._interior_id = None + + # Reset width fitting + self._fit_width = False + + def scroll_to_top(self): + """Scroll to the top-left corner of the canvas.""" + + self._canvas.xview_moveto(0) + self._canvas.yview_moveto(0) + + # ------------------------------------------------------------------------ + + def _resize_interior(self, event=None): + """Resize the interior widget to fit the canvas.""" + + if self._fit_width and self._interior_id: + # The current width of the canvas + canvas_width = self._canvas.winfo_width() + + # The interior widget's requested width + requested_width = self._interior.winfo_reqwidth() + + if requested_width != canvas_width: + # Resize the interior widget + new_width = max(canvas_width, requested_width) + self._canvas.itemconfigure(self._interior_id, width=new_width) + + def _scroll_canvas(self, event): + """Scroll the canvas.""" + + c = self._canvas + + if sys.platform.startswith("darwin"): + # macOS + c.yview_scroll(-1 * event.delta, "units") + + elif event.num == 4: + # Unix - scroll up + c.yview_scroll(-1, "units") + + elif event.num == 5: + # Unix - scroll down + c.yview_scroll(1, "units") + + else: + # Windows + c.yview_scroll(-1 * (event.delta // 120), "units") + + def _update_scroll_region(self, event): + """Update the scroll region when the interior widget is resized.""" + + # The interior widget's requested width and height + req_width = self._interior.winfo_reqwidth() + req_height = self._interior.winfo_reqheight() + + # Set the scroll region to fit the interior widget + self._canvas.configure(scrollregion=(0, 0, req_width, req_height)) + + # ------------------------------------------------------------------------ + + # Keys for configure() to forward to the canvas widget + _CANVAS_KEYS = "width", "height", "takefocus" + + # Scrollbar-related configuration + _DEFAULT_SCROLLBARS = "both" + _VALID_SCROLLBARS = "vertical", "horizontal", "both", "neither" From 77b219cf278525fab8073899cd94316d574b8ab1 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 13:13:45 +0530 Subject: [PATCH 07/23] Delete tkscrolledframe --- tkscrolledframe | 317 ------------------------------------------------ 1 file changed, 317 deletions(-) delete mode 100644 tkscrolledframe diff --git a/tkscrolledframe b/tkscrolledframe deleted file mode 100644 index 5632098..0000000 --- a/tkscrolledframe +++ /dev/null @@ -1,317 +0,0 @@ -# Credit: https://github.com/bmjcode/tkScrolledFrame -"""Implementation of the scrollable frame widget.""" - -import sys - -try: - # Python 3 - import tkinter as tk -except (ImportError): - # Python 2 - import Tkinter as tk - -try: - try: - # Python 3 - import tkinter.ttk as ttk - except (ImportError): - # Python 2 - import ttk -except (ImportError): - # Can't provide ttk's Scrollbar - pass - - -__all__ = ["ScrolledFrame"] - - -class ScrolledFrame(tk.Frame): - """Scrollable Frame widget. - - Use display_widget() to set the interior widget. For example, - to display a Label with the text "Hello, world!", you can say: - - sf = ScrolledFrame(self) - sf.pack() - sf.display_widget(Label, text="Hello, world!") - - The constructor accepts the usual Tkinter keyword arguments, plus - a handful of its own: - - scrollbars (str; default: "both") - Which scrollbars to provide. - Must be one of "vertical", "horizontal," "both", or "neither". - - use_ttk (bool; default: False) - Whether to use ttk widgets if available. - The default is to use standard Tk widgets. This setting has - no effect if ttk is not available on your system. - """ - - def __init__(self, master=None, **kw): - """Return a new scrollable frame widget.""" - - tk.Frame.__init__(self, master) - - # Hold these names for the interior widget - self._interior = None - self._interior_id = None - - # Whether to fit the interior widget's width to the canvas - self._fit_width = False - - # Which scrollbars to provide - if "scrollbars" in kw: - scrollbars = kw["scrollbars"] - del kw["scrollbars"] - - if not scrollbars: - scrollbars = self._DEFAULT_SCROLLBARS - elif not scrollbars in self._VALID_SCROLLBARS: - raise ValueError("scrollbars parameter must be one of " - "'vertical', 'horizontal', 'both', or " - "'neither'") - else: - scrollbars = self._DEFAULT_SCROLLBARS - - # Whether to use ttk widgets if available - if "use_ttk" in kw: - if ttk and kw["use_ttk"]: - Scrollbar = ttk.Scrollbar - else: - Scrollbar = tk.Scrollbar - del kw["use_ttk"] - else: - Scrollbar = tk.Scrollbar - - # Default to a 1px sunken border - if not "borderwidth" in kw: - kw["borderwidth"] = 1 - if not "relief" in kw: - kw["relief"] = "sunken" - - # Set up the grid - self.grid_columnconfigure(0, weight=1) - self.grid_rowconfigure(0, weight=1) - - # Canvas to hold the interior widget - c = self._canvas = tk.Canvas(self, - borderwidth=0, - highlightthickness=0, - takefocus=0) - - # Enable scrolling when the canvas has the focus - self.bind_arrow_keys(c) - self.bind_scroll_wheel(c) - - # Call _resize_interior() when the canvas widget is updated - c.bind("", self._resize_interior) - - # Scrollbars - xs = self._x_scrollbar = Scrollbar(self, - orient="horizontal", - command=c.xview) - ys = self._y_scrollbar = Scrollbar(self, - orient="vertical", - command=c.yview) - c.configure(xscrollcommand=xs.set, yscrollcommand=ys.set) - - # Lay out our widgets - c.grid(row=0, column=0, sticky="nsew") - if scrollbars == "vertical" or scrollbars == "both": - ys.grid(row=0, column=1, sticky="ns") - if scrollbars == "horizontal" or scrollbars == "both": - xs.grid(row=1, column=0, sticky="we") - - # Forward these to the canvas widget - self.bind = c.bind - self.focus_set = c.focus_set - self.unbind = c.unbind - self.xview = c.xview - self.xview_moveto = c.xview_moveto - self.yview = c.yview - self.yview_moveto = c.yview_moveto - - # Process our remaining configuration options - self.configure(**kw) - - def __setitem__(self, key, value): - """Configure resources of a widget.""" - - if key in self._CANVAS_KEYS: - # Forward these to the canvas widget - self._canvas.configure(**{key: value}) - - else: - # Handle everything else normally - tk.Frame.configure(self, **{key: value}) - - # ------------------------------------------------------------------------ - - def bind_arrow_keys(self, widget): - """Bind the specified widget's arrow key events to the canvas.""" - - widget.bind("", - lambda event: self._canvas.yview_scroll(-1, "units")) - - widget.bind("", - lambda event: self._canvas.yview_scroll(1, "units")) - - widget.bind("", - lambda event: self._canvas.xview_scroll(-1, "units")) - - widget.bind("", - lambda event: self._canvas.xview_scroll(1, "units")) - - def bind_scroll_wheel(self, widget): - """Bind the specified widget's mouse scroll event to the canvas.""" - - widget.bind("", self._scroll_canvas) - widget.bind("", self._scroll_canvas) - widget.bind("", self._scroll_canvas) - - def cget(self, key): - """Return the resource value for a KEY given as string.""" - - if key in self._CANVAS_KEYS: - return self._canvas.cget(key) - - else: - return tk.Frame.cget(self, key) - - # Also override this alias for cget() - __getitem__ = cget - - def configure(self, cnf=None, **kw): - """Configure resources of a widget.""" - - # This is overridden so we can use our custom __setitem__() - # to pass certain options directly to the canvas. - if cnf: - for key in cnf: - self[key] = cnf[key] - - for key in kw: - self[key] = kw[key] - - # Also override this alias for configure() - config = configure - - def display_widget(self, widget_class, fit_width=False, **kw): - """Create and display a new widget. - - If fit_width == True, the interior widget will be stretched as - needed to fit the width of the frame. - - Keyword arguments are passed to the widget_class constructor. - - Returns the new widget. - """ - - # Blank the canvas - self.erase() - - # Set width fitting - self._fit_width = fit_width - - # Set the new interior widget - self._interior = widget_class(self._canvas, **kw) - - # Add the interior widget to the canvas, and save its widget ID - # for use in _resize_interior() - self._interior_id = self._canvas.create_window(0, 0, - anchor="nw", - window=self._interior) - - # Call _update_scroll_region() when the interior widget is resized - self._interior.bind("", self._update_scroll_region) - - # Fit the interior widget to the canvas if requested - # We don't need to check fit_width here since _resize_interior() - # already does. - self._resize_interior() - - # Scroll to the top-left corner of the canvas - self.scroll_to_top() - - return self._interior - - def erase(self): - """Erase the displayed widget.""" - - # Clear the canvas - self._canvas.delete("all") - - # Delete the interior widget - del self._interior - del self._interior_id - - # Save these names - self._interior = None - self._interior_id = None - - # Reset width fitting - self._fit_width = False - - def scroll_to_top(self): - """Scroll to the top-left corner of the canvas.""" - - self._canvas.xview_moveto(0) - self._canvas.yview_moveto(0) - - # ------------------------------------------------------------------------ - - def _resize_interior(self, event=None): - """Resize the interior widget to fit the canvas.""" - - if self._fit_width and self._interior_id: - # The current width of the canvas - canvas_width = self._canvas.winfo_width() - - # The interior widget's requested width - requested_width = self._interior.winfo_reqwidth() - - if requested_width != canvas_width: - # Resize the interior widget - new_width = max(canvas_width, requested_width) - self._canvas.itemconfigure(self._interior_id, width=new_width) - - def _scroll_canvas(self, event): - """Scroll the canvas.""" - - c = self._canvas - - if sys.platform.startswith("darwin"): - # macOS - c.yview_scroll(-1 * event.delta, "units") - - elif event.num == 4: - # Unix - scroll up - c.yview_scroll(-1, "units") - - elif event.num == 5: - # Unix - scroll down - c.yview_scroll(1, "units") - - else: - # Windows - c.yview_scroll(-1 * (event.delta // 120), "units") - - def _update_scroll_region(self, event): - """Update the scroll region when the interior widget is resized.""" - - # The interior widget's requested width and height - req_width = self._interior.winfo_reqwidth() - req_height = self._interior.winfo_reqheight() - - # Set the scroll region to fit the interior widget - self._canvas.configure(scrollregion=(0, 0, req_width, req_height)) - - # ------------------------------------------------------------------------ - - # Keys for configure() to forward to the canvas widget - _CANVAS_KEYS = "width", "height", "takefocus" - - # Scrollbar-related configuration - _DEFAULT_SCROLLBARS = "both" - _VALID_SCROLLBARS = "vertical", "horizontal", "both", "neither" From 39d5fb5b590f81af621671cef49387add8c66b95 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 13:14:27 +0530 Subject: [PATCH 08/23] Create tkscrolledframe.py --- tkscrolledframe.py | 318 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 318 insertions(+) create mode 100644 tkscrolledframe.py diff --git a/tkscrolledframe.py b/tkscrolledframe.py new file mode 100644 index 0000000..ca0f140 --- /dev/null +++ b/tkscrolledframe.py @@ -0,0 +1,318 @@ +# Credit: https://github.com/bmjcode/tkScrolledFrame +# License: https://github.com/bmjcode/tkScrolledFrame/blob/master/LICENSE +"""Implementation of the scrollable frame widget.""" + +import sys + +try: + # Python 3 + import tkinter as tk +except (ImportError): + # Python 2 + import Tkinter as tk + +try: + try: + # Python 3 + import tkinter.ttk as ttk + except (ImportError): + # Python 2 + import ttk +except (ImportError): + # Can't provide ttk's Scrollbar + pass + + +__all__ = ["ScrolledFrame"] + + +class ScrolledFrame(tk.Frame): + """Scrollable Frame widget. + + Use display_widget() to set the interior widget. For example, + to display a Label with the text "Hello, world!", you can say: + + sf = ScrolledFrame(self) + sf.pack() + sf.display_widget(Label, text="Hello, world!") + + The constructor accepts the usual Tkinter keyword arguments, plus + a handful of its own: + + scrollbars (str; default: "both") + Which scrollbars to provide. + Must be one of "vertical", "horizontal," "both", or "neither". + + use_ttk (bool; default: False) + Whether to use ttk widgets if available. + The default is to use standard Tk widgets. This setting has + no effect if ttk is not available on your system. + """ + + def __init__(self, master=None, **kw): + """Return a new scrollable frame widget.""" + + tk.Frame.__init__(self, master) + + # Hold these names for the interior widget + self._interior = None + self._interior_id = None + + # Whether to fit the interior widget's width to the canvas + self._fit_width = False + + # Which scrollbars to provide + if "scrollbars" in kw: + scrollbars = kw["scrollbars"] + del kw["scrollbars"] + + if not scrollbars: + scrollbars = self._DEFAULT_SCROLLBARS + elif not scrollbars in self._VALID_SCROLLBARS: + raise ValueError("scrollbars parameter must be one of " + "'vertical', 'horizontal', 'both', or " + "'neither'") + else: + scrollbars = self._DEFAULT_SCROLLBARS + + # Whether to use ttk widgets if available + if "use_ttk" in kw: + if ttk and kw["use_ttk"]: + Scrollbar = ttk.Scrollbar + else: + Scrollbar = tk.Scrollbar + del kw["use_ttk"] + else: + Scrollbar = tk.Scrollbar + + # Default to a 1px sunken border + if not "borderwidth" in kw: + kw["borderwidth"] = 1 + if not "relief" in kw: + kw["relief"] = "sunken" + + # Set up the grid + self.grid_columnconfigure(0, weight=1) + self.grid_rowconfigure(0, weight=1) + + # Canvas to hold the interior widget + c = self._canvas = tk.Canvas(self, + borderwidth=0, + highlightthickness=0, + takefocus=0) + + # Enable scrolling when the canvas has the focus + self.bind_arrow_keys(c) + self.bind_scroll_wheel(c) + + # Call _resize_interior() when the canvas widget is updated + c.bind("", self._resize_interior) + + # Scrollbars + xs = self._x_scrollbar = Scrollbar(self, + orient="horizontal", + command=c.xview) + ys = self._y_scrollbar = Scrollbar(self, + orient="vertical", + command=c.yview) + c.configure(xscrollcommand=xs.set, yscrollcommand=ys.set) + + # Lay out our widgets + c.grid(row=0, column=0, sticky="nsew") + if scrollbars == "vertical" or scrollbars == "both": + ys.grid(row=0, column=1, sticky="ns") + if scrollbars == "horizontal" or scrollbars == "both": + xs.grid(row=1, column=0, sticky="we") + + # Forward these to the canvas widget + self.bind = c.bind + self.focus_set = c.focus_set + self.unbind = c.unbind + self.xview = c.xview + self.xview_moveto = c.xview_moveto + self.yview = c.yview + self.yview_moveto = c.yview_moveto + + # Process our remaining configuration options + self.configure(**kw) + + def __setitem__(self, key, value): + """Configure resources of a widget.""" + + if key in self._CANVAS_KEYS: + # Forward these to the canvas widget + self._canvas.configure(**{key: value}) + + else: + # Handle everything else normally + tk.Frame.configure(self, **{key: value}) + + # ------------------------------------------------------------------------ + + def bind_arrow_keys(self, widget): + """Bind the specified widget's arrow key events to the canvas.""" + + widget.bind("", + lambda event: self._canvas.yview_scroll(-1, "units")) + + widget.bind("", + lambda event: self._canvas.yview_scroll(1, "units")) + + widget.bind("", + lambda event: self._canvas.xview_scroll(-1, "units")) + + widget.bind("", + lambda event: self._canvas.xview_scroll(1, "units")) + + def bind_scroll_wheel(self, widget): + """Bind the specified widget's mouse scroll event to the canvas.""" + + widget.bind("", self._scroll_canvas) + widget.bind("", self._scroll_canvas) + widget.bind("", self._scroll_canvas) + + def cget(self, key): + """Return the resource value for a KEY given as string.""" + + if key in self._CANVAS_KEYS: + return self._canvas.cget(key) + + else: + return tk.Frame.cget(self, key) + + # Also override this alias for cget() + __getitem__ = cget + + def configure(self, cnf=None, **kw): + """Configure resources of a widget.""" + + # This is overridden so we can use our custom __setitem__() + # to pass certain options directly to the canvas. + if cnf: + for key in cnf: + self[key] = cnf[key] + + for key in kw: + self[key] = kw[key] + + # Also override this alias for configure() + config = configure + + def display_widget(self, widget_class, fit_width=False, **kw): + """Create and display a new widget. + + If fit_width == True, the interior widget will be stretched as + needed to fit the width of the frame. + + Keyword arguments are passed to the widget_class constructor. + + Returns the new widget. + """ + + # Blank the canvas + self.erase() + + # Set width fitting + self._fit_width = fit_width + + # Set the new interior widget + self._interior = widget_class(self._canvas, **kw) + + # Add the interior widget to the canvas, and save its widget ID + # for use in _resize_interior() + self._interior_id = self._canvas.create_window(0, 0, + anchor="nw", + window=self._interior) + + # Call _update_scroll_region() when the interior widget is resized + self._interior.bind("", self._update_scroll_region) + + # Fit the interior widget to the canvas if requested + # We don't need to check fit_width here since _resize_interior() + # already does. + self._resize_interior() + + # Scroll to the top-left corner of the canvas + self.scroll_to_top() + + return self._interior + + def erase(self): + """Erase the displayed widget.""" + + # Clear the canvas + self._canvas.delete("all") + + # Delete the interior widget + del self._interior + del self._interior_id + + # Save these names + self._interior = None + self._interior_id = None + + # Reset width fitting + self._fit_width = False + + def scroll_to_top(self): + """Scroll to the top-left corner of the canvas.""" + + self._canvas.xview_moveto(0) + self._canvas.yview_moveto(0) + + # ------------------------------------------------------------------------ + + def _resize_interior(self, event=None): + """Resize the interior widget to fit the canvas.""" + + if self._fit_width and self._interior_id: + # The current width of the canvas + canvas_width = self._canvas.winfo_width() + + # The interior widget's requested width + requested_width = self._interior.winfo_reqwidth() + + if requested_width != canvas_width: + # Resize the interior widget + new_width = max(canvas_width, requested_width) + self._canvas.itemconfigure(self._interior_id, width=new_width) + + def _scroll_canvas(self, event): + """Scroll the canvas.""" + + c = self._canvas + + if sys.platform.startswith("darwin"): + # macOS + c.yview_scroll(-1 * event.delta, "units") + + elif event.num == 4: + # Unix - scroll up + c.yview_scroll(-1, "units") + + elif event.num == 5: + # Unix - scroll down + c.yview_scroll(1, "units") + + else: + # Windows + c.yview_scroll(-1 * (event.delta // 120), "units") + + def _update_scroll_region(self, event): + """Update the scroll region when the interior widget is resized.""" + + # The interior widget's requested width and height + req_width = self._interior.winfo_reqwidth() + req_height = self._interior.winfo_reqheight() + + # Set the scroll region to fit the interior widget + self._canvas.configure(scrollregion=(0, 0, req_width, req_height)) + + # ------------------------------------------------------------------------ + + # Keys for configure() to forward to the canvas widget + _CANVAS_KEYS = "width", "height", "takefocus" + + # Scrollbar-related configuration + _DEFAULT_SCROLLBARS = "both" + _VALID_SCROLLBARS = "vertical", "horizontal", "both", "neither" From dc3b05c546e949d05a05567bbc241b5e28804489 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 13:16:34 +0530 Subject: [PATCH 09/23] Create .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a65322e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +tkscrolledframe.py From 3a36996e75b8c054af9f3781b0b0c6a5cc6c1974 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 13:23:02 +0530 Subject: [PATCH 10/23] Update tkscrolledframe.py --- tkscrolledframe.py | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/tkscrolledframe.py b/tkscrolledframe.py index ca0f140..8d073cf 100644 --- a/tkscrolledframe.py +++ b/tkscrolledframe.py @@ -3,26 +3,15 @@ """Implementation of the scrollable frame widget.""" import sys +import tkinter as tk try: # Python 3 - import tkinter as tk -except (ImportError): - # Python 2 - import Tkinter as tk - -try: - try: - # Python 3 - import tkinter.ttk as ttk - except (ImportError): - # Python 2 - import ttk -except (ImportError): + import tkinter.ttk as ttk +except ImportError: # Can't provide ttk's Scrollbar pass - __all__ = ["ScrolledFrame"] @@ -68,7 +57,7 @@ def __init__(self, master=None, **kw): if not scrollbars: scrollbars = self._DEFAULT_SCROLLBARS - elif not scrollbars in self._VALID_SCROLLBARS: + elif scrollbars not in self._VALID_SCROLLBARS: raise ValueError("scrollbars parameter must be one of " "'vertical', 'horizontal', 'both', or " "'neither'") @@ -78,17 +67,17 @@ def __init__(self, master=None, **kw): # Whether to use ttk widgets if available if "use_ttk" in kw: if ttk and kw["use_ttk"]: - Scrollbar = ttk.Scrollbar + scrollbar = ttk.Scrollbar else: - Scrollbar = tk.Scrollbar + scrollbar = tk.Scrollbar del kw["use_ttk"] else: - Scrollbar = tk.Scrollbar + scrollbar = tk.Scrollbar # Default to a 1px sunken border - if not "borderwidth" in kw: + if "borderwidth" not in kw: kw["borderwidth"] = 1 - if not "relief" in kw: + if "relief" not in kw: kw["relief"] = "sunken" # Set up the grid @@ -109,10 +98,10 @@ def __init__(self, master=None, **kw): c.bind("", self._resize_interior) # Scrollbars - xs = self._x_scrollbar = Scrollbar(self, + xs = self._x_scrollbar = scrollbar(self, orient="horizontal", command=c.xview) - ys = self._y_scrollbar = Scrollbar(self, + ys = self._y_scrollbar = scrollbar(self, orient="vertical", command=c.yview) c.configure(xscrollcommand=xs.set, yscrollcommand=ys.set) From df59717d2ce37823e209819bfd611534c68fcada Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 13:23:21 +0530 Subject: [PATCH 11/23] Delete .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index a65322e..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tkscrolledframe.py From 9377f4b1349f11bb4f43786f6145bf08fbdf9a9d Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 22:34:34 +0530 Subject: [PATCH 12/23] Update gui.py Co-authored-by: Christian Clauss --- gui.py | 1 + 1 file changed, 1 insertion(+) diff --git a/gui.py b/gui.py index 9b22b34..b3a70f8 100644 --- a/gui.py +++ b/gui.py @@ -1,4 +1,5 @@ import tkinter as tk + from tkscrolledframe import ScrolledFrame root = tk.Tk() From dffaf84b75c0aa81acc9885fde118e404894d8fd Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 23:00:26 +0530 Subject: [PATCH 13/23] Update gui.py --- gui.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/gui.py b/gui.py index b3a70f8..9bd6397 100644 --- a/gui.py +++ b/gui.py @@ -1,10 +1,9 @@ import tkinter as tk -from tkscrolledframe import ScrolledFrame - root = tk.Tk() -scrolled_frame = ScrolledFrame(master=root) -main_frame = scrolled_frame.display_widget(tk.Frame) +main_frame = tk.Frame(master=root) +chat_listbox = tk.Listbox(master=main_frame, height=200, width=50) +scroll_bar = tk.Scrollbar(master=main_frame) speak_button = tk.Button(master=root, text='Speak', command=lambda: None) @@ -15,15 +14,16 @@ def set_speak_command(command): speak_button.pack(side=tk.LEFT, anchor=tk.SW) -def conversation_label(text): - tk.Label(master=main_frame, text=text).pack() - - def speak(text): - conversation_label(f'Assistant: {text}') + chat_listbox.insert('end', f'Assistant: {text}') + root.geometry('700x500') -scrolled_frame.pack(fill=tk.BOTH) +chat_listbox.pack(fill=tk.Y, side=tk.LEFT) +scroll_bar.pack(side=tk.RIGHT, fill=tk.Y) +scroll_bar.configure(command=chat_listbox.yview) +chat_listbox.configure(yscrollcommand=scroll_bar.set) +main_frame.pack(fill=tk.BOTH) root.wm_title('Desktop assistant') root.resizable(False, False) mainloop = root.mainloop From 6f0af090adcec5540a9cb16641e9a0ffa8cf4dfd Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Fri, 8 Oct 2021 23:00:39 +0530 Subject: [PATCH 14/23] Delete tkscrolledframe.py --- tkscrolledframe.py | 307 --------------------------------------------- 1 file changed, 307 deletions(-) delete mode 100644 tkscrolledframe.py diff --git a/tkscrolledframe.py b/tkscrolledframe.py deleted file mode 100644 index 8d073cf..0000000 --- a/tkscrolledframe.py +++ /dev/null @@ -1,307 +0,0 @@ -# Credit: https://github.com/bmjcode/tkScrolledFrame -# License: https://github.com/bmjcode/tkScrolledFrame/blob/master/LICENSE -"""Implementation of the scrollable frame widget.""" - -import sys -import tkinter as tk - -try: - # Python 3 - import tkinter.ttk as ttk -except ImportError: - # Can't provide ttk's Scrollbar - pass - -__all__ = ["ScrolledFrame"] - - -class ScrolledFrame(tk.Frame): - """Scrollable Frame widget. - - Use display_widget() to set the interior widget. For example, - to display a Label with the text "Hello, world!", you can say: - - sf = ScrolledFrame(self) - sf.pack() - sf.display_widget(Label, text="Hello, world!") - - The constructor accepts the usual Tkinter keyword arguments, plus - a handful of its own: - - scrollbars (str; default: "both") - Which scrollbars to provide. - Must be one of "vertical", "horizontal," "both", or "neither". - - use_ttk (bool; default: False) - Whether to use ttk widgets if available. - The default is to use standard Tk widgets. This setting has - no effect if ttk is not available on your system. - """ - - def __init__(self, master=None, **kw): - """Return a new scrollable frame widget.""" - - tk.Frame.__init__(self, master) - - # Hold these names for the interior widget - self._interior = None - self._interior_id = None - - # Whether to fit the interior widget's width to the canvas - self._fit_width = False - - # Which scrollbars to provide - if "scrollbars" in kw: - scrollbars = kw["scrollbars"] - del kw["scrollbars"] - - if not scrollbars: - scrollbars = self._DEFAULT_SCROLLBARS - elif scrollbars not in self._VALID_SCROLLBARS: - raise ValueError("scrollbars parameter must be one of " - "'vertical', 'horizontal', 'both', or " - "'neither'") - else: - scrollbars = self._DEFAULT_SCROLLBARS - - # Whether to use ttk widgets if available - if "use_ttk" in kw: - if ttk and kw["use_ttk"]: - scrollbar = ttk.Scrollbar - else: - scrollbar = tk.Scrollbar - del kw["use_ttk"] - else: - scrollbar = tk.Scrollbar - - # Default to a 1px sunken border - if "borderwidth" not in kw: - kw["borderwidth"] = 1 - if "relief" not in kw: - kw["relief"] = "sunken" - - # Set up the grid - self.grid_columnconfigure(0, weight=1) - self.grid_rowconfigure(0, weight=1) - - # Canvas to hold the interior widget - c = self._canvas = tk.Canvas(self, - borderwidth=0, - highlightthickness=0, - takefocus=0) - - # Enable scrolling when the canvas has the focus - self.bind_arrow_keys(c) - self.bind_scroll_wheel(c) - - # Call _resize_interior() when the canvas widget is updated - c.bind("", self._resize_interior) - - # Scrollbars - xs = self._x_scrollbar = scrollbar(self, - orient="horizontal", - command=c.xview) - ys = self._y_scrollbar = scrollbar(self, - orient="vertical", - command=c.yview) - c.configure(xscrollcommand=xs.set, yscrollcommand=ys.set) - - # Lay out our widgets - c.grid(row=0, column=0, sticky="nsew") - if scrollbars == "vertical" or scrollbars == "both": - ys.grid(row=0, column=1, sticky="ns") - if scrollbars == "horizontal" or scrollbars == "both": - xs.grid(row=1, column=0, sticky="we") - - # Forward these to the canvas widget - self.bind = c.bind - self.focus_set = c.focus_set - self.unbind = c.unbind - self.xview = c.xview - self.xview_moveto = c.xview_moveto - self.yview = c.yview - self.yview_moveto = c.yview_moveto - - # Process our remaining configuration options - self.configure(**kw) - - def __setitem__(self, key, value): - """Configure resources of a widget.""" - - if key in self._CANVAS_KEYS: - # Forward these to the canvas widget - self._canvas.configure(**{key: value}) - - else: - # Handle everything else normally - tk.Frame.configure(self, **{key: value}) - - # ------------------------------------------------------------------------ - - def bind_arrow_keys(self, widget): - """Bind the specified widget's arrow key events to the canvas.""" - - widget.bind("", - lambda event: self._canvas.yview_scroll(-1, "units")) - - widget.bind("", - lambda event: self._canvas.yview_scroll(1, "units")) - - widget.bind("", - lambda event: self._canvas.xview_scroll(-1, "units")) - - widget.bind("", - lambda event: self._canvas.xview_scroll(1, "units")) - - def bind_scroll_wheel(self, widget): - """Bind the specified widget's mouse scroll event to the canvas.""" - - widget.bind("", self._scroll_canvas) - widget.bind("", self._scroll_canvas) - widget.bind("", self._scroll_canvas) - - def cget(self, key): - """Return the resource value for a KEY given as string.""" - - if key in self._CANVAS_KEYS: - return self._canvas.cget(key) - - else: - return tk.Frame.cget(self, key) - - # Also override this alias for cget() - __getitem__ = cget - - def configure(self, cnf=None, **kw): - """Configure resources of a widget.""" - - # This is overridden so we can use our custom __setitem__() - # to pass certain options directly to the canvas. - if cnf: - for key in cnf: - self[key] = cnf[key] - - for key in kw: - self[key] = kw[key] - - # Also override this alias for configure() - config = configure - - def display_widget(self, widget_class, fit_width=False, **kw): - """Create and display a new widget. - - If fit_width == True, the interior widget will be stretched as - needed to fit the width of the frame. - - Keyword arguments are passed to the widget_class constructor. - - Returns the new widget. - """ - - # Blank the canvas - self.erase() - - # Set width fitting - self._fit_width = fit_width - - # Set the new interior widget - self._interior = widget_class(self._canvas, **kw) - - # Add the interior widget to the canvas, and save its widget ID - # for use in _resize_interior() - self._interior_id = self._canvas.create_window(0, 0, - anchor="nw", - window=self._interior) - - # Call _update_scroll_region() when the interior widget is resized - self._interior.bind("", self._update_scroll_region) - - # Fit the interior widget to the canvas if requested - # We don't need to check fit_width here since _resize_interior() - # already does. - self._resize_interior() - - # Scroll to the top-left corner of the canvas - self.scroll_to_top() - - return self._interior - - def erase(self): - """Erase the displayed widget.""" - - # Clear the canvas - self._canvas.delete("all") - - # Delete the interior widget - del self._interior - del self._interior_id - - # Save these names - self._interior = None - self._interior_id = None - - # Reset width fitting - self._fit_width = False - - def scroll_to_top(self): - """Scroll to the top-left corner of the canvas.""" - - self._canvas.xview_moveto(0) - self._canvas.yview_moveto(0) - - # ------------------------------------------------------------------------ - - def _resize_interior(self, event=None): - """Resize the interior widget to fit the canvas.""" - - if self._fit_width and self._interior_id: - # The current width of the canvas - canvas_width = self._canvas.winfo_width() - - # The interior widget's requested width - requested_width = self._interior.winfo_reqwidth() - - if requested_width != canvas_width: - # Resize the interior widget - new_width = max(canvas_width, requested_width) - self._canvas.itemconfigure(self._interior_id, width=new_width) - - def _scroll_canvas(self, event): - """Scroll the canvas.""" - - c = self._canvas - - if sys.platform.startswith("darwin"): - # macOS - c.yview_scroll(-1 * event.delta, "units") - - elif event.num == 4: - # Unix - scroll up - c.yview_scroll(-1, "units") - - elif event.num == 5: - # Unix - scroll down - c.yview_scroll(1, "units") - - else: - # Windows - c.yview_scroll(-1 * (event.delta // 120), "units") - - def _update_scroll_region(self, event): - """Update the scroll region when the interior widget is resized.""" - - # The interior widget's requested width and height - req_width = self._interior.winfo_reqwidth() - req_height = self._interior.winfo_reqheight() - - # Set the scroll region to fit the interior widget - self._canvas.configure(scrollregion=(0, 0, req_width, req_height)) - - # ------------------------------------------------------------------------ - - # Keys for configure() to forward to the canvas widget - _CANVAS_KEYS = "width", "height", "takefocus" - - # Scrollbar-related configuration - _DEFAULT_SCROLLBARS = "both" - _VALID_SCROLLBARS = "vertical", "horizontal", "both", "neither" From 9d49c4c0e0873b0b79e598e19222fa41e8c2995c Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 17:47:30 +0530 Subject: [PATCH 15/23] Update Jarvis2.py --- Jarvis2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jarvis2.py b/Jarvis2.py index 719003c..657ed84 100755 --- a/Jarvis2.py +++ b/Jarvis2.py @@ -180,4 +180,4 @@ def execute_the_command_said_by_user(): gui.set_speak_command(execute_the_command_said_by_user) -gui.mainloop() \ No newline at end of file +gui.mainloop() From 4ff085bf3231e282ff495716beeda4f167c1ecb3 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 17:49:29 +0530 Subject: [PATCH 16/23] Update Jarvis2_4windows.py --- Jarvis2_4windows.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py index 51443eb..e94dfa2 100644 --- a/Jarvis2_4windows.py +++ b/Jarvis2_4windows.py @@ -6,7 +6,6 @@ import gui -mixer.init() from actions import ( change_rate, change_voice, From 255a7e937c93d132588151cbbacfed833d5f8dca Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 18:06:28 +0530 Subject: [PATCH 17/23] Update Jarvis2_4windows.py --- Jarvis2_4windows.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py index e94dfa2..ff768fe 100644 --- a/Jarvis2_4windows.py +++ b/Jarvis2_4windows.py @@ -92,12 +92,6 @@ def execute_the_command_said_by_user(): gui.mainloop() -def speak(text): - gui.speak(text) - engine.say(text) - engine.runAndWait() - - def run(): master = config['DEFAULT']['master'] From 9dce13121412725e3c19b5136eb04c70f5440b43 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 18:10:30 +0530 Subject: [PATCH 18/23] Update actions.py --- actions.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/actions.py b/actions.py index 4dea1e3..2e3ca95 100644 --- a/actions.py +++ b/actions.py @@ -43,8 +43,16 @@ def open_url(url): def search(search_query, search_engine): open_url(f"{search_engine}/search?q={search_query}") +gui_speak = lambda text: None + + +def set_gui_speak(command): + global gui_speak + gui_speak = command + def speak(text): + gui_speak(text) engine.say(text) engine.runAndWait() From c9f88027d56dd84df802efb7a3930fe10c4f28a1 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 18:12:19 +0530 Subject: [PATCH 19/23] Update Jarvis2_4windows.py --- Jarvis2_4windows.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py index ff768fe..c0d8f7d 100644 --- a/Jarvis2_4windows.py +++ b/Jarvis2_4windows.py @@ -13,6 +13,7 @@ search_engine_selector, speak, wish_me, + set_gui_speak ) from commands import ( command_bye, @@ -89,6 +90,7 @@ def execute_the_command_said_by_user(): speak("Next Command! Sir!") gui.set_speak_command(execute_the_command_said_by_user) + set_gui_speak(gui.speak) gui.mainloop() From 3cd6d57eadffac768277635e6544c8f07874def6 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 18:14:17 +0530 Subject: [PATCH 20/23] Update actions.py --- actions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/actions.py b/actions.py index 2e3ca95..5b28a52 100644 --- a/actions.py +++ b/actions.py @@ -43,7 +43,9 @@ def open_url(url): def search(search_query, search_engine): open_url(f"{search_engine}/search?q={search_query}") -gui_speak = lambda text: None + +def gui_speak(text): + pass def set_gui_speak(command): From 3d1a7cb36dfbe6ac8a87b567a7fbc2c1c77d2c84 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 18:18:29 +0530 Subject: [PATCH 21/23] Update Jarvis2_4windows.py --- Jarvis2_4windows.py | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py index c0d8f7d..d093eb1 100644 --- a/Jarvis2_4windows.py +++ b/Jarvis2_4windows.py @@ -1,34 +1,15 @@ import configparser import os -import speech_recognition as sr - import gui - - -from actions import ( - change_rate, - change_voice, - change_volume, - search_engine_selector, - speak, - wish_me, - set_gui_speak -) -from commands import ( - command_bye, - command_hello, - command_mail, - command_nothing, - command_open, - command_pause_music, - command_play_music, - command_search, - command_stop_music, - command_unpause_music, - command_whatsup, - command_wikipedia, -) +import speech_recognition as sr +from actions import (change_rate, change_voice, change_volume, + search_engine_selector, set_gui_speak, speak, wish_me) +from commands import (command_bye, command_hello, command_mail, + command_nothing, command_open, command_pause_music, + command_play_music, command_search, command_stop_music, + command_unpause_music, command_whatsup, + command_wikipedia) popular_websites = { "google": "https://www.google.com", From e15490322d0864bc94b0ac85ee84798662477f69 Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 18:22:50 +0530 Subject: [PATCH 22/23] Update Jarvis2_4windows.py --- Jarvis2_4windows.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py index d093eb1..49ec3ee 100644 --- a/Jarvis2_4windows.py +++ b/Jarvis2_4windows.py @@ -1,15 +1,15 @@ -import configparser -import os - -import gui -import speech_recognition as sr -from actions import (change_rate, change_voice, change_volume, - search_engine_selector, set_gui_speak, speak, wish_me) -from commands import (command_bye, command_hello, command_mail, - command_nothing, command_open, command_pause_music, - command_play_music, command_search, command_stop_music, - command_unpause_music, command_whatsup, - command_wikipedia) +import configparser # isort: skip +import os # isort: skip + +import gui # isort: skip +import speech_recognition as sr # isort: skip +from actions import (change_rate, change_voice, change_volume, # isort: skip + search_engine_selector, set_gui_speak, speak, wish_me) # isort: skip +from commands import (command_bye, command_hello, command_mail, # isort: skip + command_nothing, command_open, command_pause_music, # isort: skip + command_play_music, command_search, command_stop_music, # isort: skip + command_unpause_music, command_whatsup, # isort: skip + command_wikipedia) # isort: skip popular_websites = { "google": "https://www.google.com", From ba34bd4014bbf0f9338b3037799095a9202228ff Mon Sep 17 00:00:00 2001 From: "B.Jothin kumar" Date: Sat, 9 Oct 2021 18:28:07 +0530 Subject: [PATCH 23/23] Update Jarvis2_4windows.py --- Jarvis2_4windows.py | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/Jarvis2_4windows.py b/Jarvis2_4windows.py index 49ec3ee..4681632 100644 --- a/Jarvis2_4windows.py +++ b/Jarvis2_4windows.py @@ -3,13 +3,29 @@ import gui # isort: skip import speech_recognition as sr # isort: skip -from actions import (change_rate, change_voice, change_volume, # isort: skip - search_engine_selector, set_gui_speak, speak, wish_me) # isort: skip -from commands import (command_bye, command_hello, command_mail, # isort: skip - command_nothing, command_open, command_pause_music, # isort: skip - command_play_music, command_search, command_stop_music, # isort: skip - command_unpause_music, command_whatsup, # isort: skip - command_wikipedia) # isort: skip +from actions import ( # isort: skip + change_rate, + change_voice, + change_volume, + search_engine_selector, + set_gui_speak, + speak, + wish_me +) +from commands import ( # isort: skip + command_bye, + command_hello, + command_mail, + command_nothing, + command_open, + command_pause_music, + command_play_music, + command_search, + command_stop_music, + command_unpause_music, + command_whatsup, + command_wikipedia +) popular_websites = { "google": "https://www.google.com",