From 412c7c2600d191d68c9583049b5a1dbb8beccbf4 Mon Sep 17 00:00:00 2001 From: gitea Date: Sun, 9 Jun 2024 21:32:10 +0800 Subject: [PATCH] =?UTF-8?q?[aio.py]:=20=E6=96=B0=E5=A2=9Etabview=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=EF=BC=8C=E5=8C=BA=E5=88=86=E6=95=B0=E6=8D=AE=E5=A4=84?= =?UTF-8?q?=E7=90=86=E5=92=8C=E8=87=AA=E5=8A=A8=E5=8C=96=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- aio/aio.py | 91 +++++++++++++++++++++++------------------------- aio/layout.xlsx | Bin 10272 -> 12096 bytes 3 files changed, 44 insertions(+), 49 deletions(-) diff --git a/.gitignore b/.gitignore index 838b054..66c8375 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -./test.py +test.py .idea/ aio/.idea/ aio/__pycache__/ diff --git a/aio/aio.py b/aio/aio.py index 8ec46fc..3160a48 100644 --- a/aio/aio.py +++ b/aio/aio.py @@ -12,7 +12,7 @@ customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark customtkinter.set_default_color_theme("blue") # Themes: "blue" (standard), "green", "dark-blue" customtkinter.set_widget_scaling(1.1) # widget dimensions and text size customtkinter.set_window_scaling(1.1) # window geometry dimensions -socket.setdefaulttimeout(1) +socket.setdefaulttimeout(10) # global vars btns = { 'start': {'btn': '', 'row': 1, 'text': '开始运行'}, @@ -21,23 +21,23 @@ btns = { 'end': {'btn': '', 'row': 4, 'text': '结束运行'}, } widgits = { - 'path': {'label': '', 'entry': '', 'row': 0, 'col': 2, 'text': '数据文件夹路径'}, - 'av': {'label': '', 'entry': '', 'row': 1, 'col': 2, 'text': '角速度'}, - 'rc': {'label': '', 'entry': '', 'row': 1, 'col': 4, 'text': 'optional'}, - 'rpm': {'label': '', 'entry': '', 'row': 1, 'col': 6, 'text': '额定转速'}, - 'rr': {'label': '', 'entry': '', 'row': 1, 'col': 8, 'text': '减速比'}, - 'dur': {'label': '', 'entry': '', 'row': 1, 'col': 10, 'text': '周期时间'}, - 'axis': {'label': '', 'optionmenu': '', 'row': 2, 'col': 2, 'text': ''}, - 'vel': {'label': '', 'optionmenu': '', 'row': 2, 'col': 4, 'text': ''}, - 'trq': {'label': '', 'optionmenu': '', 'row': 2, 'col': 6, 'text': ''}, - 'trqh': {'label': '', 'optionmenu': '', 'row': 2, 'col': 8, 'text': ''}, - 'sto': {'label': '', 'optionmenu': '', 'row': 2, 'col': 10, 'text': ''}, - 'rc1': {'label': '', 'entry': '', 'row': 3, 'col': 2, 'text': '额定电流'}, - 'rc2': {'label': '', 'entry': '', 'row': 3, 'col': 4, 'text': '额定电流'}, - 'rc3': {'label': '', 'entry': '', 'row': 3, 'col': 6, 'text': '额定电流'}, - 'rc4': {'label': '', 'entry': '', 'row': 3, 'col': 8, 'text': '额定电流'}, - 'rc5': {'label': '', 'entry': '', 'row': 3, 'col': 10, 'text': '额定电流'}, - 'rc6': {'label': '', 'entry': '', 'row': 3, 'col': 12, 'text': '额定电流'}, + 'path': {'label': '', 'entry': '', 'row': 1, 'col': 2, 'text': '数据文件夹路径'}, + 'av': {'label': '', 'entry': '', 'row': 2, 'col': 2, 'text': '角速度'}, + 'rc': {'label': '', 'entry': '', 'row': 2, 'col': 4, 'text': 'optional'}, + 'rpm': {'label': '', 'entry': '', 'row': 2, 'col': 6, 'text': '额定转速'}, + 'rr': {'label': '', 'entry': '', 'row': 2, 'col': 8, 'text': '减速比'}, + 'dur': {'label': '', 'entry': '', 'row': 2, 'col': 10, 'text': '周期时间'}, + 'axis': {'label': '', 'optionmenu': '', 'row': 3, 'col': 2, 'text': ''}, + 'vel': {'label': '', 'optionmenu': '', 'row': 3, 'col': 4, 'text': ''}, + 'trq': {'label': '', 'optionmenu': '', 'row': 3, 'col': 6, 'text': ''}, + 'trqh': {'label': '', 'optionmenu': '', 'row': 3, 'col': 8, 'text': ''}, + 'sto': {'label': '', 'optionmenu': '', 'row': 3, 'col': 10, 'text': ''}, + 'rc1': {'label': '', 'entry': '', 'row': 4, 'col': 2, 'text': '额定电流'}, + 'rc2': {'label': '', 'entry': '', 'row': 4, 'col': 4, 'text': '额定电流'}, + 'rc3': {'label': '', 'entry': '', 'row': 4, 'col': 6, 'text': '额定电流'}, + 'rc4': {'label': '', 'entry': '', 'row': 4, 'col': 8, 'text': '额定电流'}, + 'rc5': {'label': '', 'entry': '', 'row': 4, 'col': 10, 'text': '额定电流'}, + 'rc6': {'label': '', 'entry': '', 'row': 4, 'col': 12, 'text': '额定电流'}, } @@ -53,7 +53,7 @@ class App(customtkinter.CTk): self.geometry("1180x550+30+30") self.protocol("WM_DELETE_WINDOW", self.func_end_callback) self.config(bg='#E9E9E9') - self.grid_rowconfigure(4, weight=1) + self.grid_rowconfigure(5, weight=1) self.grid_columnconfigure((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13), weight=1) self.minsize(1180, 550) # ===================================================================== @@ -72,51 +72,46 @@ class App(customtkinter.CTk): btns['log']['btn'].configure(command=lambda: self.thread_it(self.func_log_callback)) btns['end']['btn'].configure(command=lambda: self.thread_it(self.func_end_callback)) # create version info - self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.1.4\nDate: 06/06/2024", font=self.my_font, text_color="#4F4F4F") + self.label_version = customtkinter.CTkLabel(self.frame_func, justify='left', text="Vers: 0.1.5\nDate: 06/12/2024", font=self.my_font, text_color="#4F4F4F") self.frame_func.rowconfigure(6, weight=1) self.label_version.grid(row=6, column=0, padx=20, pady=20, sticky='s') # ===================================================================== - # create frame - self.frame_param = customtkinter.CTkFrame(self, corner_radius=5, fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD') - self.frame_param.grid(row=0, column=1, rowspan=3, columnspan=13, sticky='new', ipadx=20, ipady=10, padx=10, pady=(5, 10)) + # create tabviews + self.tabview = customtkinter.CTkTabview(self, width=10000, height=100, anchor='w', fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD') + self.tabview.grid(row=0, column=1, padx=10, pady=5, sticky="nsew") + self.tabview.add("Data Process") + self.tabview.add("Automatic Test") # create main menu - self.menu_main = customtkinter.CTkOptionMenu(self.frame_param, values=["INIT", "brake", "current", "iso"], font=self.my_font, text_color='yellow', button_color='red', fg_color='green', command=self.func_main_callback) - self.menu_main.grid(row=0, column=1, sticky='we', padx=(20, 10), pady=(10, 5)) + self.menu_main = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), values=["INIT", "brake", "current", "iso"], font=self.my_font, text_color='yellow', button_color='red', fg_color='green', command=self.func_main_callback) + self.menu_main.grid(row=1, column=1, sticky='we', padx=5, pady=5) self.menu_main.set("Start Here!") # create sub menu - self.menu_sub = customtkinter.CTkOptionMenu(self.frame_param) - # ===================================================================== - # create path related - self.label_path = customtkinter.CTkLabel(self.frame_param, text="PATH", font=self.my_font) - self.label_path.grid(row=0, column=2, sticky='e', pady=(10, 5)) - self.entry_path = customtkinter.CTkEntry(self.frame_param, width=670, placeholder_text="数据文件夹路径", font=self.my_font) - self.entry_path.grid(row=0, column=3, columnspan=11, padx=(5, 10), pady=(10, 5), sticky='we') - self.entry_path.configure(state='disabled') + self.menu_sub = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process')) # ===================================================================== # create widgits for widgit in widgits: if widgit == 'path': - widgits[widgit]['label'] = customtkinter.CTkLabel(self.frame_param, text=f'{widgit.upper()}', font=self.my_font) - widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=(10, 5)) - widgits[widgit]['entry'] = customtkinter.CTkEntry(self.frame_param, width=670, placeholder_text=widgits[widgit]['text'], font=self.my_font) - widgits[widgit]['entry'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=(10, 5), sticky='we') + widgits[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f'{widgit.upper()}', font=self.my_font) + widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=5) + widgits[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Data Process'), width=670, placeholder_text=widgits[widgit]['text'], font=self.my_font) + widgits[widgit]['entry'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, columnspan=11, padx=(5, 10), pady=5, sticky='we') widgits[widgit]['entry'].configure(state='disabled') elif widgit in ['av', 'rc', 'rpm', 'rr', 'dur', 'rc1', 'rc2', 'rc3', 'rc4', 'rc5', 'rc6']: - widgits[widgit]['label'] = customtkinter.CTkLabel(self.frame_param, text=f"{widgit.upper()}", font=self.my_font) - widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=(5, 5)) - widgits[widgit]['entry'] = customtkinter.CTkEntry(self.frame_param, width=self.w_param, placeholder_text=f"{widgits[widgit]['text']}", font=self.my_font) - widgits[widgit]['entry'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, padx=(5, 10), pady=(5, 5), sticky='w') + widgits[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f"{widgit.upper()}", font=self.my_font) + widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=5) + widgits[widgit]['entry'] = customtkinter.CTkEntry(self.tabview.tab('Data Process'), width=self.w_param, placeholder_text=f"{widgits[widgit]['text']}", font=self.my_font) + widgits[widgit]['entry'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, padx=(5, 10), pady=5, sticky='w') widgits[widgit]['entry'].configure(state='disabled') elif widgit in ['axis', 'vel', 'trq', 'trqh', 'sto']: - widgits[widgit]['label'] = customtkinter.CTkLabel(self.frame_param, text=f"{widgit.upper()}", font=self.my_font) - widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=(5, 5)) - widgits[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.frame_param, button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font) - widgits[widgit]['optionmenu'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, padx=(5, 10), pady=(5, 5), sticky='w') + widgits[widgit]['label'] = customtkinter.CTkLabel(self.tabview.tab('Data Process'), text=f"{widgit.upper()}", font=self.my_font) + widgits[widgit]['label'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col'], sticky='e', pady=5) + widgits[widgit]['optionmenu'] = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), button_color='#708090', fg_color='#778899', values=["1", "2", "3", "4", "5", "6", "7"], width=self.w_param, font=self.my_font) + widgits[widgit]['optionmenu'].grid(row=widgits[widgit]['row'], column=widgits[widgit]['col']+1, padx=(5, 10), pady=5, sticky='w') widgits[widgit]['optionmenu'].configure(state='disabled') # ===================================================================== # create textbox self.textbox = customtkinter.CTkTextbox(self, wrap='none', font=customtkinter.CTkFont(family="consolas", size=14), text_color="blue", fg_color='#E9E9E9', border_width=2, border_color='#CDCDCD', border_spacing=5) - self.textbox.grid(row=4, column=1, rowspan=3, columnspan=13, ipadx=10, ipady=10, padx=10, pady=(5, 10), sticky='nsew') + self.textbox.grid(row=5, column=1, rowspan=2, columnspan=13, ipadx=10, ipady=10, padx=10, pady=(5, 10), sticky='nsew') self.textbox.configure(state='disabled') # ===================================================================== # version check @@ -161,8 +156,8 @@ class App(customtkinter.CTk): widgits[widgit]['label'].configure(text_color="red") widgits[widgit]['optionmenu'].configure(state='normal') elif func_name == 'current': - self.menu_sub = customtkinter.CTkOptionMenu(self.frame_param, values=["max", "avg", "cycle"], font=self.my_font, button_color='red', fg_color='green', command=self.func_sub_callback) - self.menu_sub.grid(row=1, column=1, sticky='we', padx=(20, 10), pady=(5, 5)) + self.menu_sub = customtkinter.CTkOptionMenu(self.tabview.tab('Data Process'), values=["max", "avg", "cycle"], font=self.my_font, button_color='red', fg_color='green', command=self.func_sub_callback) + self.menu_sub.grid(row=2, column=1, sticky='we', padx=5, pady=5) self.menu_sub.set("--select--") self.menu_sub.configure(text_color='yellow') diff --git a/aio/layout.xlsx b/aio/layout.xlsx index ac11973f023dda75e940e1c125d2a20351ceae76..476231a74729bc29c0cd7abc6a33206aa5953965 100644 GIT binary patch delta 8750 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