optimize performance 06-05-2025-23:00

This commit is contained in:
Désiré Werner Menrath 2025-05-07 08:14:46 +02:00
parent dba6138aa7
commit 9a4d8b3506
4 changed files with 146 additions and 122 deletions

View File

@ -119,6 +119,89 @@ class LxTools(tk.Tk):
def __init__(self, *args: Any, **kwargs: Any) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs) 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 @staticmethod
def get_file_name(path: Path, i: int = 5) -> List[str]: def get_file_name(path: Path, i: int = 5) -> List[str]:
""" """

View File

@ -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()

138
wirepy.py
View File

@ -29,17 +29,22 @@ class Wirepy(tk.Tk):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# Hide the window initially
self.withdraw()
self.my_tool_tip = None self.my_tool_tip = None
self.x_width = AppConfig.UI_CONFIG["window_size"][0] self.x_width = AppConfig.UI_CONFIG["window_size"][0]
self.y_height = AppConfig.UI_CONFIG["window_size"][1] 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)) # Set the window size
self.resizable(AppConfig.UI_CONFIG["resizable_window"][0], AppConfig.UI_CONFIG["resizable_window"][1]) 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.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.columnconfigure(0, weight=1)
self.rowconfigure(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) ConfigManager.init(AppConfig.SETTINGS_FILE)
theme = ConfigManager.get("theme") theme = ConfigManager.get("theme")
ThemeManager.change_theme(self, theme) ThemeManager.change_theme(self, theme)
@ -50,8 +55,15 @@ class Wirepy(tk.Tk):
# Set it as the window icon # Set it as the window icon
self.iconphoto(True, self.wg_icon) self.iconphoto(True, self.wg_icon)
# Add the widgets
FrameWidgets(self).grid() 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): class FrameWidgets(ttk.Frame):
""" """
@ -364,17 +376,6 @@ class FrameWidgets(ttk.Frame):
) )
) )
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 @staticmethod
def about() -> None: def about() -> None:
""" """
@ -389,107 +390,6 @@ class FrameWidgets(ttk.Frame):
"Use without warranty!\n") "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) 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: def update_setting(self, update_res) -> None:
"""write off or on in file """write off or on in file
Args: Args:
@ -532,15 +432,12 @@ class FrameWidgets(ttk.Frame):
# If tooltips are disabled, the menu option should be to enable them # If tooltips are disabled, the menu option should be to enable them
self.tooltip_label.set(_("Enable Tooltips")) self.tooltip_label.set(_("Enable Tooltips"))
def tooltips_toggle(self): def tooltips_toggle(self):
"""Toggles tooltips on/off and updates the menu label""" """Toggles tooltips on/off and updates the menu label"""
# Toggle the boolean state # Toggle the boolean state
new_bool_state = not self.tooltip_state.get() new_bool_state = not self.tooltip_state.get()
# Save the converted value in the configuration # Save the converted value in the configuration
ConfigManager.set("tooltips", str(new_bool_state)) 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 # Update the tooltip_state variable for immediate effect
self.tooltip_state.set(new_bool_state) 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 # This assumes it's the third item (index 2) in your menu
self.settings.entryconfigure(1, label=self.tooltip_label.get()) self.settings.entryconfigure(1, label=self.tooltip_label.get())
def update_theme_label(self) -> str: def update_theme_label(self) -> str:
"""Update the theme label based on current theme""" """Update the theme label based on current theme"""
current_theme = ConfigManager.get("theme") current_theme = ConfigManager.get("theme")