From 9a4d8b35068b568ed264cf7225390d354ab83154 Mon Sep 17 00:00:00 2001 From: punix Date: Wed, 7 May 2025 08:14:46 +0200 Subject: [PATCH] optimize performance 06-05-2025-23:00 --- __pycache__/common_tools.cpython-312.pyc | Bin 30660 -> 33666 bytes common_tools.py | 83 ++++++++++++++ new_window_for_add_trace_test.py | 45 ++++++++ wirepy.py | 140 +++-------------------- 4 files changed, 146 insertions(+), 122 deletions(-) create mode 100644 new_window_for_add_trace_test.py diff --git a/__pycache__/common_tools.cpython-312.pyc b/__pycache__/common_tools.cpython-312.pyc index bb299c76a01a906ddd52909e90bb88d195b8629c..70ccf6b5d5e3d5b11a7ea809e42816c53901815f 100644 GIT binary patch delta 5113 zcmb6+3s4*9nftGv=z$~z5+H#WgC7bHTb8kD{3IA`6Z}X_Ols^j4SC+;-U-c8cEbec@P!7XH)>p64R%(-`&kT^5f$z7BC zzmeGhfPE1uI`56!1pDCfLg;z2D5+&YD)F98{`|x1TkxP@I%f&O4}{lfFjY zL^TRmX%q_P0;YhWGA_z@)7K-|`6BvyPYSNA6TWx_0|SM8$tnYG-GPrvSRo+lCXZ#E z`B%w$W|(nwqUabC3S|Dxy9QPF8DMg`r+|K8eCy{%hPenqA)bwsQ=Mf&-oP7QVzY7x z=%zS3Vwf@_CTS!uJBrCADQKKBB~9c#I=Er5+QyOWp%~R&2dB{VW8v_PQ z(oDjmx|DIsnzWEFMT?C|%aD(RYrO%Kv`$h-le8qfS;wf?sRGI`1-`*DRIbah|D&8O z$qZEhzZ+dx1sp%6@eyDRCUTo>iKX@Kr5mj;=|oJseT6EPw(GFg~(;@PB=>P8*j5^FyEDNEAA zBd9m!c$~%4D-4fPo1aP2lNDLv72Uxr1oai3cNNdV-^nY!gJ-@&uOwNVEK1g*dkR*P z^d{N6s4L}}{y&sQTvyFZ+lOc#?|xR5ts&1-Hs`T^Z4t@y;Y$uRx=cPwZG@Wa z@h5#rKku3}G0gBjhQX$!FWY=mKFV1&H`<8))w7!Vf6XZ5p8U|p<(?KnR0J$@QEn_I z^3oV5iJUShaHBXj62%kTh$O}o33D+KM4}Uv8CAG32@lI4+AAr8+@s+z7ZrJ~D>~tf zQ)I&nKXkM7_P3bBDfWkn!6 zT#>-AKOEK!`}yHXL!@EzbO_;2O1cSj4UK<_YBlpXreWeqOMU(6gn%bHLr5!1h_N#? z6VZ5&D2&Bpq9ALQTo!J^avgZEVU`Xd5ukN^Y}Q-#-t}lLlc@gn+46fqGCTdGAd!EbsA#{YlY22K+SEL>()|(* z6AOZvjjU)aHhr6xjWJZJnX^5C1sVk&0B{ljlu5JjxrAAAslbCkcHA?2+z&eXM9jG< zIPxilKr|!FMUzaUQLMGFZd#F`wq>IEpBgDx3|9$Uf6z!a{ZNy{#w;vyWp>%Ij|I1yBLV5fyhFjai(M0 z%y`N!+RoeN2A>x%iRr{uhq`H>TDk8Hk6O{Ly4z=(m)xZ}0qK%7Z@yZmZf;X6+ujJP z6&OAc2KxPU*~-COE0#*?W=|}Z)Tt$P>A|Z7*Xkd**42HzBxM|i#wKTH_dgt6RcXcP~JyYrlfq?MQwak#JGbu0vi?s^=hC#-M0|fGHYF` zSeJ@k>Rzm9P%9eJ@* z?Rmkz5UiUmxN}6KFR4sb%$KND+pdOHZl_wja~3TXSEMTE*Q-@cS07Tj-D>gfSp?Pa zUv!;!r5aNk(w_9T^u}xo=c8BAynKz@aoxRh$?aQSLu3B)GRJrV(~Iu=RQG*9c<|No z*H2t?9lblX49%H;lj`5J;1AC@^bCg8((poQWX8E{WgMk*_33K0y#8%_JxxM7tOn|4 zI&L`2=2}%}RVu1FHq4+UXZhT5)mfcJsv|^)*1~hHCtP!la~o2ghf~{98`D+k=5!=m z^J}G%-&(iI+i5R+8!X{3T-qXnFt!|G=#|z#85_ zh{BAmL#t5Qs{T&{Y^Ecb5uw($P;wa62@an$bx?ZYS+lx%@KXR_$|`Cxt-mL z$lq?hu@#HJrI!W0}-vS!s0KZRu7Or7y5qU3+k(YFC zsfnBgx*dRS4sPKz1_k3Mfkps8To|tA_)P%+O0H~)pn9ThsVh2yOpUh;jJar;1$3Eb zGbr)_tw!dF)AM`M*_jYU zA>KgGPkPYLWWKy}4`Tg@{9@N;bb&1Iy5F2F7}>nL68$uDWcQEEY!H#p_l3>h1@Av0 z+gju09{>t{tQq2hm`xaL`}hKRwKa&ICGWJZv+L<`1NBu>&=v^X?u0co63hYkDX^;$ z+0)j8p3gkr_6^qeCm`twDh7!IFf6AM2mO_MfdE%(ycPflKo12#7f}u_pbs(!+Akv( z(SCZc5viF#M>ESk4T9$Y=p|SN3=*#yJ2Acad_hYcATdH+M!+^8;ytnvEoOEe8E2?yHP*@h1T#Zk>QClpCm=n-whN5GN~z)JLoLuRZ;si$ZqR9vA? zWk`yN_z|ig(_@m!pS?yBdAO8jrQ_i*A@6Z8r&~BdF}fCLntpLCg8o8o9s9|HI#=%` zV|E@VsSv%1WN&Nu@2ORp{)|%7IpccUO?p}+u|GC&C@RwJ1UJw-nvo^9IuA7Kjv$w~ z8NdMmx({%U9|Hj1?k;ExFaZ3DBp-PkwPe`i4pas?J50BpSEz<&q<6r$E`uK<8@jq# z2TRU&b+3tm>RtWO3p4- z9F58Jk}2UHS`8&Zx1b?e67h9%>txkhd>Uk|4+<06TO@P?-JRm#Xas;rcAXO0084&& z>J!gBU7z{!W1kt3MqcjoTB<>OJtDvEYtApPB7VE&J|NS5=_tRaTLAn5cr^75N@F74 zL2=v;VATQxeo+g}iohRTbxRG|@Rvb<8o)h~kU#Mcv#o4qw{Q+M=sh(Ba(ZLU0Cra@ zhk*v5m?i(&{~Q|5TpD=XfSx34hRe`X`#J-exN)>hKDzzMCPxDD_Jj)HFHAj zr8hwQ6v+I6{BmS>F>yftTBb_$8rI`3n4B#RzdHkP>(orW z@o3*LU6E2e#%GuGP4ejJCNmsC_yzLp>BHzX^2gI{=nARB74~y0K|M)2aSeKfOyJs% zpM&t%kZ=^eEY_AWg0-rw-iS0rhUTJwTa4R6HKV z_$WjHS;H3qfTg>u^bMc^7$Osi@x6eBHsbwMQM1s+2|Jo*j!W1VK=@?jAJ9- ZUIS{J={+YrA$-CB{vYiYa&~O*e*>?~m2v<8 delta 2569 zcmZWqYitzP6`ni$^mupu1Y_fX!KP$u>KY8i!q~9J5E~N*zd$h|>+#ODcg%QZb7$7O z>jndcC~;CHEhka)P)d^@5pAOi7*$DBh@1wgQQKdQtS0j(iCRU_s7=$*CL${7J+rJ! zoss6#neU$0oO92;bB~HwKP8dhhr^P=Qgp`m3)JV&NHO&*s}$*scZmscrdlcHb|L_fJgwUHV%?e``E_U2pNU?=w@=x z9**AfmpHzRs#rsF3(Z&Bj-)G2v_MhV-@zpoQ`y7_xG3K`+6OciHhv|xQzY^F3up4 zfx*p-H4`W%5mbapgkuOAbZ!|Uui8J}@^wJ`n*h)5h?6vYx#OqgJUrLduxgwuIUX}- zI$oMpt!RL~gk~?pVq1%U6vcB8*|}f*NPv-@A8vI#s%|kK@_vN#2p179ad7;DJ@<4E zALI$1Lv9q|b)9gr|CAkw|f^6KM~*uJ^Cv~ zqu}Y+$O5GLSCItF_tz2yUg_TubAP=QHJ(H$U)3$&ZjK`z<*{s>`5G1y9-U1ZH`vt5MC#6C9#gQ+8-oZz2OGVIKF+dW>WTBXh`lQZ^LBr z+b1w1rW#8*jE_AzdCR-{Ri4BU zp66zg@+#mF&AvdmDZptXRv6sh8QTN5kp5bLU~1R5+AwT_6OJ#DG%`AC!^QmwcT6)( zrD|3Wqv|1qZ=?V(rv}7-68qn&r%02#>xNLz-Fk79mQ_E79Ku@!Z1y6F+5P4tp4DSW z<2~d=to)vjXH;D=GAsd~O>Zn-TIb*OnY+n)`#@%mSb?t;%WUJ=57Eh4%-JW8Ta-nEtRE>IlOkD%@C!7NA(^p*nArrkXP5^=Ps>{-BZp80+fQYQ3>Qw- z)_;O_xO?(<>Qbs-}*3Na29#G~QTNY5soo06iV+Fs<0^SVn loHCTOMmyM9_|4o@#eE{#_So1{be`T2Q2s*kLg(q-{{>N+s5Jlp diff --git a/common_tools.py b/common_tools.py index 1be0ade..e321658 100755 --- a/common_tools.py +++ b/common_tools.py @@ -119,6 +119,89 @@ class LxTools(tk.Tk): def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) + @staticmethod + def center_window_cross_platform(window, width, height): + """ + Centers a window on the primary monitor in a way that works on both X11 and Wayland + + Args: + window: The tkinter window to center + width: Window width + height: Window height + """ + # Calculate the position before showing the window + + # First attempt: Try to use GDK if available (works on both X11 and Wayland) + try: + import gi + gi.require_version('Gdk', '3.0') + from gi.repository import Gdk + + display = Gdk.Display.get_default() + monitor = display.get_primary_monitor() or display.get_monitor(0) + geometry = monitor.get_geometry() + scale_factor = monitor.get_scale_factor() + + # Calculate center position on primary monitor + x = geometry.x + (geometry.width - width // scale_factor) // 2 + y = geometry.y + (geometry.height - height // scale_factor) // 2 + + # Set window geometry + window.geometry(f"{width}x{height}+{x}+{y}") + return + except (ImportError, AttributeError): + pass + + # Second attempt: Try xrandr for X11 + try: + import subprocess + output = subprocess.check_output(["xrandr", "--query"], universal_newlines=True) + + # Parse the output to find the primary monitor + primary_info = None + for line in output.splitlines(): + if "primary" in line: + parts = line.split() + for part in parts: + if "x" in part and "+" in part: + primary_info = part + break + break + + if primary_info: + # Parse the geometry: WIDTHxHEIGHT+X+Y + geometry = primary_info.split("+") + dimensions = geometry[0].split("x") + primary_width = int(dimensions[0]) + primary_height = int(dimensions[1]) + primary_x = int(geometry[1]) + primary_y = int(geometry[2]) + + # Calculate center position on primary monitor + x = primary_x + (primary_width - width) // 2 + y = primary_y + (primary_height - height) // 2 + + # Set window geometry + window.geometry(f"{width}x{height}+{x}+{y}") + return + except (subprocess.SubprocessError, ImportError, IndexError, ValueError): + pass + + # Final fallback: Use standard Tkinter method + screen_width = window.winfo_screenwidth() + screen_height = window.winfo_screenheight() + + # Try to make an educated guess for multi-monitor setups + # If screen width is much larger than height, assume multiple monitors side by side + if screen_width > screen_height * 1.8: # Heuristic for detecting multiple monitors + # Assume primary monitor is on the left half + screen_width = screen_width // 2 + + x = (screen_width - width) // 2 + y = (screen_height - height) // 2 + window.geometry(f"{width}x{height}+{x}+{y}") + + @staticmethod def get_file_name(path: Path, i: int = 5) -> List[str]: """ diff --git a/new_window_for_add_trace_test.py b/new_window_for_add_trace_test.py new file mode 100644 index 0000000..fd87687 --- /dev/null +++ b/new_window_for_add_trace_test.py @@ -0,0 +1,45 @@ +#!/usr/bin/python3 + +import tkinter as tk + +class MainWindow(tk.Tk): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.title("Trace-Test-Window") + self.geometry("400x300") + self.text_label = tk.StringVar() + self.text_forground = tk.StringVar(value="red") + self.text_label.set("This is the main window") + self.label = tk.Label(self, textvariable=self.text_label) + self.label.grid(row=0, column=0, padx=10, pady=10) + self.label.grid_remove() + + self.button_text = tk.StringVar() + self.button_text.set("Drück für andere Text anzeige") + self.button = tk.Button(self, textvariable=self.button_text, command=self.toggle_lable) + self.button.grid(row=1, column=0, padx=10, pady=10) + + self.text_label.trace_add("write", self.update_label) + self.text_forground.trace_add("write", self.update_label) + + def update_label(self, *args): + self.label.configure(foreground=self.text_forground.get()) + + if self.text_label.get(): + self.label.grid() + else: + self.label.grid_remove() + + def toggle_lable(self): + + if 'main window' in self.text_label.get(): + self.text_label.set("gewechseltes label") + self.button_text.set("Drück für main window") + else: + self.text_label.set("This is the main window") + self.button_text.set("Drück für andere Text anzeige") + +if __name__ == "__main__": + window = MainWindow() + window.mainloop() diff --git a/wirepy.py b/wirepy.py index fe4549c..0ecc69e 100755 --- a/wirepy.py +++ b/wirepy.py @@ -29,17 +29,22 @@ class Wirepy(tk.Tk): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + # Hide the window initially + self.withdraw() + self.my_tool_tip = None self.x_width = AppConfig.UI_CONFIG["window_size"][0] self.y_height = AppConfig.UI_CONFIG["window_size"][1] - self.monitor_center_x = int(self.winfo_screenwidth() / 2 - (self.x_width / 2)) - self.monitor_center_y = int(self.winfo_screenheight() / 2 - (self.y_height / 2)) - self.resizable(AppConfig.UI_CONFIG["resizable_window"][0], AppConfig.UI_CONFIG["resizable_window"][1]) + + # Set the window size + self.geometry(f"{self.x_width}x{self.y_height}") + self.resizable(AppConfig.UI_CONFIG["resizable_window"][0], + AppConfig.UI_CONFIG["resizable_window"][1]) self.title(AppConfig.UI_CONFIG["window_title"]) - self.geometry(f"{self.x_width}x{self.y_height}+{self.monitor_center_x}+{self.monitor_center_y}") + self.columnconfigure(0, weight=1) self.rowconfigure(0, weight=1) - self.tk.call("source", f"{AppConfig.SYSTEM_PATHS["tcl_path"]}/water.tcl") + self.tk.call("source", f"{AppConfig.SYSTEM_PATHS['tcl_path']}/water.tcl") ConfigManager.init(AppConfig.SETTINGS_FILE) theme = ConfigManager.get("theme") ThemeManager.change_theme(self, theme) @@ -50,7 +55,14 @@ class Wirepy(tk.Tk): # Set it as the window icon self.iconphoto(True, self.wg_icon) + # Add the widgets FrameWidgets(self).grid() + + # Center the window on the primary monitor + LxTools.center_window_cross_platform(self, self.x_width, self.y_height) + + # Now show the window after it has been positioned + self.after(10, self.deiconify) class FrameWidgets(ttk.Frame): @@ -362,18 +374,7 @@ class FrameWidgets(ttk.Frame): AppConfig.IMAGE_PATHS["icon_error"], AppConfig.IMAGE_PATHS["icon_msg"] ) - ) - - def tooltip(self, tip) -> None: - """ - Aktualisiert die Tooltip-Einstellung im ConfigManager - Args: - tip (bool): True zum Deaktivieren, False zum Aktivieren von Tooltips - """ - # Beachten Sie die umgekehrte Logik: tip=True bedeutet Tooltips deaktivieren - ConfigManager.set("tooltip", not tip) - # Aktualisieren Sie die lokale Variable für sofortige Wirkung - self.tooltip_state = not tip + ) @staticmethod def about() -> None: @@ -389,107 +390,6 @@ class FrameWidgets(ttk.Frame): "Use without warranty!\n") LxTools.msg_window(AppConfig.IMAGE_PATHS["icon_vpn"], AppConfig.IMAGE_PATHS["icon_vpn"], _("Info"), msg_t, _("Go to Wire-Py git"), link_btn) - - def update_ui_for_update_status(self, res): - """Update UI elements based on update check result""" - print(f"Updating UI for result: {res}") # Debug output - - # First, clean up any existing UI elements - if hasattr(self, 'update_btn') and self.update_btn.winfo_exists(): - self.update_btn.grid_forget() - - # Reset all variables to ensure fresh state - self.update_label.set("") - self.update_tooltip.set("") - self.update_foreground.set("black") - - if res == "False": - self.set_update.set(value=1) - self.update_label.set(_("Update search off")) - self.update_tooltip.set(_("Updates you have disabled")) - self.update_foreground.set("red") - - # Display the label - self.updates_lb.configure( - textvariable=self.update_label, - foreground=self.update_foreground.get() - ) - self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) - Tooltip(self.updates_lb, self.update_tooltip.get(), self.tooltip_state) - - elif res == "No Internet Connection!": - self.update_label.set(_("No Server Connection!")) - self.update_foreground.set("red") - - # Display the label - self.updates_lb.configure( - textvariable=self.update_label, - foreground=self.update_foreground.get() - ) - self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) - - elif res == "No Updates": - self.update_label.set(_("No Updates")) - self.update_tooltip.set(_("Congratulations! Wire-Py is up to date")) - self.update_foreground.set("black") - - # Display the label - self.updates_lb.configure( - textvariable=self.update_label, - foreground=self.update_foreground.get() - ) - self.updates_lb.grid(column=4, columnspan=3, row=0, padx=10) - Tooltip(self.updates_lb, self.update_tooltip.get(), self.tooltip_state) - - else: - # We have an update available - self.set_update.set(value=0) - update_text = f"Update {res} {_('available!')}" - - # Hide the label if it's visible - if self.updates_lb.winfo_ismapped(): - self.updates_lb.grid_forget() - - # Create or update the update button - if not hasattr(self, 'update_btn') or not self.update_btn.winfo_exists(): - # Create the update button if it doesn't exist yet - self.update_btn = ttk.Menubutton(self.menu_frame, text=update_text) - self.update_btn.grid(column=4, columnspan=3, row=0, padx=0) - Tooltip(self.update_btn, _("Click to download new version"), self.tooltip_state) - - self.download = tk.Menu(self, relief="flat") - self.update_btn.configure(menu=self.download, style="Toolbutton") - self.download.add_command( - label=_("Download"), - command=lambda: GiteaUpdate.download( - f"{AppConfig.DOWNLOAD_URL}/{res}.zip", - res, - AppConfig.IMAGE_PATHS["icon_info"], - AppConfig.IMAGE_PATHS["icon_vpn"], - AppConfig.IMAGE_PATHS["icon_error"], - AppConfig.IMAGE_PATHS["icon_msg"] - ) - ) - else: - # Update the existing update button - self.update_btn.configure(text=update_text) - # Make sure it's visible - self.update_btn.grid(column=4, columnspan=3, row=0, padx=0) - - # Update the download command - if hasattr(self, 'download'): - self.download.entryconfigure( - 0, # First entry in the menu - command=lambda: GiteaUpdate.download( - f"{AppConfig.DOWNLOAD_URL}/{res}.zip", - res, - AppConfig.IMAGE_PATHS["icon_info"], - AppConfig.IMAGE_PATHS["icon_vpn"], - AppConfig.IMAGE_PATHS["icon_error"], - AppConfig.IMAGE_PATHS["icon_msg"] - ) - ) - def update_setting(self, update_res) -> None: """write off or on in file Args: @@ -532,15 +432,12 @@ class FrameWidgets(ttk.Frame): # If tooltips are disabled, the menu option should be to enable them self.tooltip_label.set(_("Enable Tooltips")) - def tooltips_toggle(self): """Toggles tooltips on/off and updates the menu label""" # Toggle the boolean state new_bool_state = not self.tooltip_state.get() - # Save the converted value in the configuration ConfigManager.set("tooltips", str(new_bool_state)) - print(f"Tooltips are now: {new_bool_state} in ConfigManager") # Update the tooltip_state variable for immediate effect self.tooltip_state.set(new_bool_state) @@ -551,7 +448,6 @@ class FrameWidgets(ttk.Frame): # This assumes it's the third item (index 2) in your menu self.settings.entryconfigure(1, label=self.tooltip_label.get()) - def update_theme_label(self) -> str: """Update the theme label based on current theme""" current_theme = ConfigManager.get("theme")