From 16794bf488704e155d4297ef8d68ed414f1de990 Mon Sep 17 00:00:00 2001 From: EndMove Date: Wed, 31 Aug 2022 12:07:43 +0200 Subject: [PATCH] Fixing bugs & start creating interface --- .vscode/settings.json | 4 ++ Tkinter-grid-Sticky-Options.png | Bin 0 -> 5636 bytes controller/Frames.py | 2 +- controller/HomeController.py | 12 ++++- controller/InfoController.py | 2 +- controller/MainController.py | 15 ++++++- main.py | 2 +- view/HomeView.py | 76 +++++++++++++++++++++++++++----- view/InfoView.py | 2 +- view/MainWindow.py | 68 ++++++++++++++++++++-------- 10 files changed, 145 insertions(+), 38 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 Tkinter-grid-Sticky-Options.png diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..073e637 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "todo-tree.tree.showBadges": true, + "todo-tree.tree.showCountsInTree": true +} \ No newline at end of file diff --git a/Tkinter-grid-Sticky-Options.png b/Tkinter-grid-Sticky-Options.png new file mode 100644 index 0000000000000000000000000000000000000000..6729df82c5834744e82e821b573cdc4a102b60ed GIT binary patch literal 5636 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 PEx_jdWy?nM>-YW*h-C>M literal 0 HcmV?d00001 diff --git a/controller/Frames.py b/controller/Frames.py index 9ef9766..96a6856 100644 --- a/controller/Frames.py +++ b/controller/Frames.py @@ -15,4 +15,4 @@ class Frames(Enum): @since 2022-08-30 """ Home = 1 # Home view - Info = 2 # Info & copyright view \ No newline at end of file + Info = 2 # Info & copyright view diff --git a/controller/HomeController.py b/controller/HomeController.py index 9d046a1..d3e21a1 100644 --- a/controller/HomeController.py +++ b/controller/HomeController.py @@ -37,7 +37,15 @@ class HomeController: :frame: -> The frame we want to launch. """ - self.__main_controller.change_frame(frame) + #self.__main_controller.change_frame(frame) + self.__view.add_log("Salut comment vas tu ? 1") + self.__view.add_log("Salut comment vas tu ? 2") + self.__view.add_log("Salut comment vas tu ? 3") + self.__view.add_log("Salut comment vas tu ? 4") + self.__view.add_log("Salut comment vas tu ? 5") + self.__view.add_log("Salut comment vas tu ? 6") + self.__view.add_log("Salut comment vas tu ? 7") + self.__view.add_log("Salut comment vas tu ? 8") def on_download_started(self, url: str, name: str) -> None: """ @@ -47,4 +55,4 @@ class HomeController: :name: -> The name of the folder in which put pictures. """ pass - # END View events \ No newline at end of file + # END View events diff --git a/controller/InfoController.py b/controller/InfoController.py index 49a7c4b..e29b50c 100644 --- a/controller/InfoController.py +++ b/controller/InfoController.py @@ -38,4 +38,4 @@ class InfoController: :frame: -> The frame we want to launch. """ self.__main_controller.change_frame(frame) - # END View events \ No newline at end of file + # END View events diff --git a/controller/MainController.py b/controller/MainController.py index ed92b8a..b563274 100644 --- a/controller/MainController.py +++ b/controller/MainController.py @@ -20,18 +20,29 @@ class MainController: def set_view(self, view) -> None: """ [function for view] + => Allow to define the controller view. :view: -> The view that this controller manage. """ self.__view = view - # END view methods + + def on_check_for_update(self) -> None: + """ + [event function for view] + => Event launched when a check for available updates is requested. + """ + # TODO write the function + print("on_check_for_update") + pass + # END View methods # START Controller methods def change_frame(self, frame) -> None: """ [function for controller] + => Allows you to request a frame change in the main window. :frame: -> The frame we want to display on the window instead of the current frame. """ self.__view.show_frame(frame) - # END Controller methods \ No newline at end of file + # END Controller methods diff --git a/main.py b/main.py index 1eb631e..1ad10bb 100644 --- a/main.py +++ b/main.py @@ -35,4 +35,4 @@ if __name__ == '__main__': main_window.show_frame(Frames.Home) # Start main windows looping (launch program) - main_window.mainloop() \ No newline at end of file + main_window.mainloop() diff --git a/view/HomeView.py b/view/HomeView.py index 9a653b5..ef73941 100644 --- a/view/HomeView.py +++ b/view/HomeView.py @@ -1,5 +1,6 @@ import tkinter as tk from tkinter import ttk +from tkinter import scrolledtext as st from controller.Frames import Frames from controller.HomeController import HomeController @@ -21,23 +22,26 @@ class HomeView(ttk.Frame): def __init__(self, parent, controller: HomeController): super().__init__(parent) + # Init view + self.__init_content() + # create widgets # label - self.label = ttk.Label(self, text='Email:') - self.label.grid(row=1, column=0) + # self.label = ttk.Label(self, text='Email:') + # self.label.grid(row=1, column=0) # email entry - self.email_var = tk.StringVar() - self.email_entry = ttk.Entry(self, textvariable=self.email_var, width=30) - self.email_entry.grid(row=1, column=1, sticky=tk.NSEW) + # self.email_var = tk.StringVar() + # self.email_entry = ttk.Entry(self, textvariable=self.email_var, width=30) + # self.email_entry.grid(row=1, column=1, sticky=tk.NSEW) # save button - self.save_button = ttk.Button(self, text='Save', command=self.event_btn) - self.save_button.grid(row=1, column=3, padx=10) + # self.save_button = ttk.Button(self, text='Save', command=self.event_btn) + # self.save_button.grid(row=1, column=3, padx=10) # message - self.message_label = ttk.Label(self, text='coucou toi :D JE SUIS SUPER MAN héhéh', foreground='red') - self.message_label.grid(row=2, column=1, sticky=tk.W) + # self.message_label = ttk.Label(self, text='coucou toi :D JE SUIS SUPER MAN héhéh', foreground='red') + # self.message_label.grid(row=2, column=1, sticky=tk.W) # place this frame # self.grid(row=0, column=0, padx=5, pady=5) @@ -46,7 +50,57 @@ class HomeView(ttk.Frame): # Save and setup main controller self.__controller = controller controller.set_view(self) + + # START Internal function + def __init_content(self) -> None: + """ + [internal function] + => Initialize the view content. + """ + self.columnconfigure(0, weight=1) + self.columnconfigure(1, weight=3) - def event_btn(self) -> None: + # Website link + self.web_label = ttk.Label(self, text="Website URL:") + self.web_label.grid(column=0, row=0, sticky=tk.W, padx=5, pady=5) + self.web_entry = ttk.Entry(self, width=50) # show="-" + self.web_entry.grid(column=1, row=0, sticky=tk.E, padx=5, pady=5, ipadx=2, ipady=2) + + # Download name + self.name_label = ttk.Label(self, text="Download Name:") + self.name_label.grid(column=0, row=1, sticky=tk.W, padx=5, pady=5) + self.name_entry = ttk.Entry(self, width=50) + self.name_entry.grid(column=1, row=1, sticky=tk.E, padx=5, pady=5, ipadx=2, ipady=2) + + # Logs area + self.log_area = st.ScrolledText(self, wrap=tk.WORD, state = tk.DISABLED, width=40, height=8)#, font=("Times New Roman", 15)) + self.log_area.grid(column=0, row=3, sticky=tk.EW, columnspan=2, pady=10, padx=10) + + # Download button + self.download_button = ttk.Button(self, text="Start downloading", command=self.event_btn) + self.download_button.grid(column=1, row=4, sticky=tk.E, padx=5, pady=5, ipadx=5, ipady=2) + # END Internal function + + # START Controller methods + def add_log(self, line: str) -> None: + """ + [function for controller] + TODO desc + """ + print("ADD: ", line) + self.log_area.configure(state=tk.NORMAL) + self.log_area.insert(tk.END, f"{line}\n") + self.log_area.configure(state=tk.DISABLED) + + def clear_log(self) -> None: + """ + [function for controller] + TODO desc + """ + self.log_area.delete(0, tk.END) + + # END Controller methods + + def event_btn(self) -> None:# TODO remove print("you clicked ! And now you are on info page ... :D") - self.__controller.on_change_view(Frames.Info) \ No newline at end of file + self.__controller.on_change_view(Frames.Info) diff --git a/view/InfoView.py b/view/InfoView.py index 1d38a24..f497a44 100644 --- a/view/InfoView.py +++ b/view/InfoView.py @@ -50,4 +50,4 @@ class InfoView(ttk.Frame): def event_btn(self) -> None: print("you clicked on the button that is on the info view!") print("got redirected to the home view :D") - self.__controller.on_change_view(Frames.Home) \ No newline at end of file + self.__controller.on_change_view(Frames.Home) diff --git a/view/MainWindow.py b/view/MainWindow.py index d5e182c..0f54670 100644 --- a/view/MainWindow.py +++ b/view/MainWindow.py @@ -1,7 +1,5 @@ import tkinter as tk -from tracemalloc import Frame from controller.MainController import MainController -from controller.Frames import Frames class MainWindow(tk.Tk): @@ -18,7 +16,7 @@ class MainWindow(tk.Tk): # Variables __controller: MainController = None __views: dict = None - __current_view = None + __frame_id: int = None # Constructor def __init__(self, controller: MainController): @@ -27,19 +25,50 @@ class MainWindow(tk.Tk): # Init view repository self.__views = {} - # Init main window - self.title('Tkinter app') - self.geometry('450x250') - self.resizable(False, False) - self.config(bg='#f7ef38') - - self.rowconfigure(0, weight=1) - self.columnconfigure(0, weight=1) - # Save and setup main controller self.__controller = controller controller.set_view(self) + # Init view components + self.__init_window() + self.__init_top_menu() + + # START Internal methods + def __init_window(self): + """ + [internal function] + => Initialize window parameters + """ + self.title('Tkinter app') + # self.geometry('450x250') + self.resizable(False, False) + self.config(bg='#f7ef38') + + def __init_top_menu(self): + """ + [internal function] + => Initialize top menu of the window. + """ + main_menu = tk.Menu(self) + + col1_menu = tk.Menu(main_menu, tearoff=0) + col1_menu.add_command(label="Open folder", command=self.alert) + col1_menu.add_separator() + col1_menu.add_command(label="Quit", command=self.alert) + main_menu.add_cascade(label="File", menu=col1_menu) + + col2_menu = tk.Menu(main_menu, tearoff=0) + col2_menu.add_command(label="Check for update", command=self.__controller.on_check_for_update) + col2_menu.add_command(label="About", command=self.alert) + main_menu.add_cascade(label="Help", menu=col2_menu) + + self.config(menu=main_menu) + + def alert(self): + # TODO remove + print("You clicked") + # END Internal methods + # START App methods def add_view(self, frame, view): """ @@ -54,15 +83,16 @@ class MainWindow(tk.Tk): def show_frame(self, frame): """ [function for app & controller] + => Allows to display the selected frame provided that it + has been previously added to the frame dictionary. :frame: -> the frame if of the view to display. """ - new_view = self.__views.get(frame) - if new_view: - if self.__current_view: - self.__current_view.pack_forget() - new_view.pack(fill=tk.BOTH, expand=False) - self.__current_view = new_view + if self.__views.get(frame): + if self.__frame_id: + self.__views.get(self.__frame_id).pack_forget() + self.__views.get(frame).pack(fill=tk.BOTH, expand=False) + self.__frame_id = frame else: raise ValueError("Unable to find the requested Frame") - # END Controller methods \ No newline at end of file + # END Controller methods