Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
781488c16f | |||
cf0288b519 |
@ -5,12 +5,6 @@ Changelog for shared_libs
|
|||||||
- add Info Window for user in delete logfile
|
- add Info Window for user in delete logfile
|
||||||
bevore delete logfile.
|
bevore delete logfile.
|
||||||
|
|
||||||
### Added
|
|
||||||
15-06-2025
|
|
||||||
|
|
||||||
- Update MessageDialog Class description
|
|
||||||
- import LxTools with try exception.
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
14-06-2025
|
14-06-2025
|
||||||
|
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
# shared_libs
|
# shared_libs
|
||||||
|
|
||||||
Module Project for apps by git.ilunix.de
|
Module Project for apps by git.ilunix.de
|
||||||
Examples with a Theme from Projekt Wire-Py
|
|
||||||
|
|
||||||
# Screenshots
|
|
||||||
[](https://fb.ilunix.de/share/KtaTPMMq)
|
|
||||||
[](https://fb.ilunix.de/share/cRO_ksrM)
|
|
||||||
[](https://fb.ilunix.de/share/1JEdSJcI)
|
|
||||||
[](https://fb.ilunix.de/share/1XxNey7y7)
|
|
||||||
[](https://fb.ilunix.de/share/4HCxiNwB)
|
|
||||||
[](https://fb.ilunix.de/share/uui8b1xx)
|
|
@ -10,7 +10,7 @@ import shutil
|
|||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from typing import Optional, Dict, Any, NoReturn
|
from typing import Optional, Dict, Any, NoReturn
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from tkinter import Toplevel
|
from tkinter import ttk, Toplevel
|
||||||
|
|
||||||
|
|
||||||
class CryptoUtil:
|
class CryptoUtil:
|
||||||
|
1
gitea.py
1
gitea.py
@ -5,6 +5,7 @@ import requests
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
import shutil
|
import shutil
|
||||||
|
from shared_libs.common_tools import LxTools
|
||||||
from shared_libs.message import MessageDialog
|
from shared_libs.message import MessageDialog
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ from shared_libs.common_tools import (
|
|||||||
)
|
)
|
||||||
import sys
|
import sys
|
||||||
from file_and_dir_ensure import prepare_app_environment
|
from file_and_dir_ensure import prepare_app_environment
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
|
|
||||||
class LogViewer(tk.Tk):
|
class LogViewer(tk.Tk):
|
||||||
|
224
message.py
224
message.py
@ -2,104 +2,155 @@ import os
|
|||||||
from typing import List, Optional, Dict
|
from typing import List, Optional, Dict
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import ttk
|
from tkinter import ttk
|
||||||
|
from manager import Center
|
||||||
|
|
||||||
try:
|
"""
|
||||||
from manager import LxTools
|
####################################################
|
||||||
except (ModuleNotFoundError, NameError):
|
Attention! MessageDialog returns different values.
|
||||||
from shared_libs.common_tools import LxTools
|
From 3 buttons with Cancel, Cancel and the Close (x)
|
||||||
|
None returns. otherwise always False.
|
||||||
|
####################################################
|
||||||
|
Usage Examples
|
||||||
|
1. Basic Info Dialog
|
||||||
|
from tkinter import Tk
|
||||||
|
|
||||||
|
root = Tk()
|
||||||
|
dialog = MessageDialog(
|
||||||
|
message_type="info",
|
||||||
|
text="This is an information message.",
|
||||||
|
buttons=["OK"],
|
||||||
|
master=root,
|
||||||
|
)
|
||||||
|
result = dialog.show()
|
||||||
|
print("User clicked OK:", result)
|
||||||
|
|
||||||
|
-----------------------------------------------------
|
||||||
|
My Favorite Example,
|
||||||
|
for simply information message:
|
||||||
|
|
||||||
|
MessageDialog(text="This is an information message.")
|
||||||
|
result = MessageDialog(text="This is an information message.").show()
|
||||||
|
-----------------------------------------------------
|
||||||
|
Explanation: if you need the return value e.g. in the vaiable result,
|
||||||
|
you need to add .show(). otherwise only if no root.mainloop z.b is used to test the window.
|
||||||
|
#####################################################
|
||||||
|
|
||||||
|
2. Error Dialog with Custom Icon and Command
|
||||||
|
def on_cancel():
|
||||||
|
print("User canceled the operation.")
|
||||||
|
|
||||||
|
root = Tk()
|
||||||
|
result = MessageDialog(
|
||||||
|
message_type="error",
|
||||||
|
text="An error occurred during processing.",
|
||||||
|
buttons=["Retry", "Cancel"],
|
||||||
|
commands=[None, on_cancel],
|
||||||
|
icon="/path/to/custom/error_icon.png",
|
||||||
|
title="Critical Error"
|
||||||
|
).show()
|
||||||
|
|
||||||
|
print("User clicked Retry:", result)
|
||||||
|
|
||||||
|
-----------------------------------------------------
|
||||||
|
My Favorite Example,
|
||||||
|
for simply Error message:
|
||||||
|
|
||||||
|
MessageDialog(
|
||||||
|
"error",
|
||||||
|
text="An error occurred during processing.",
|
||||||
|
).show()
|
||||||
|
|
||||||
|
#####################################################
|
||||||
|
|
||||||
|
3. Confirmation Dialog with Yes/No Buttons
|
||||||
|
def on_confirm():
|
||||||
|
print("User confirmed the action.")
|
||||||
|
|
||||||
|
root = Tk()
|
||||||
|
dialog = MessageDialog(
|
||||||
|
message_type="ask",
|
||||||
|
text="Are you sure you want to proceed?",
|
||||||
|
buttons=["Yes", "No"],
|
||||||
|
commands=[on_confirm, None], # Either use comando or work with the values True and False
|
||||||
|
)
|
||||||
|
result = dialog.show()
|
||||||
|
print("User confirmed:", result)
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
My Favorite Example,
|
||||||
|
for simply Question message:
|
||||||
|
|
||||||
|
dialog = MessageDialog(
|
||||||
|
"ask",
|
||||||
|
text="Are you sure you want to proceed?",
|
||||||
|
buttons=["Yes", "No"]
|
||||||
|
).show()
|
||||||
|
#####################################################
|
||||||
|
|
||||||
|
4. Warning Dialog with Custom Title
|
||||||
|
|
||||||
|
root = Tk()
|
||||||
|
dialog = MessageDialog(
|
||||||
|
message_type="warning",
|
||||||
|
text="This action cannot be undone.",
|
||||||
|
buttons=["Proceed", "Cancel"],
|
||||||
|
title="Warning: Irreversible Action"
|
||||||
|
)
|
||||||
|
result = dialog.show()
|
||||||
|
print("User proceeded:", result)
|
||||||
|
-----------------------------------------------------
|
||||||
|
And a special example for a "open link" button:
|
||||||
|
Be careful not to forget to import it into the script in which this dialog is used!!!
|
||||||
|
import webbrowser
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
dialog = MessageDialog(
|
||||||
|
"ask",
|
||||||
|
text="Are you sure you want to proceed?",
|
||||||
|
buttons=["Yes", "Go to Exapmle"],
|
||||||
|
commands=[
|
||||||
|
None, # Default on "OK"
|
||||||
|
partial(webbrowser.open, "https://exapmle.com"),
|
||||||
|
],
|
||||||
|
icon="/pathh/to/custom/icon.png",
|
||||||
|
title="Example",
|
||||||
|
).show()
|
||||||
|
|
||||||
|
|
||||||
|
In all dialogues, a font can also be specified as a tuple. With font=("ubuntu", 11)
|
||||||
|
and wraplength=300, the text is automatically wrapped.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class MessageDialog:
|
class MessageDialog:
|
||||||
"""
|
"""
|
||||||
A customizable message dialog window using tkinter for user interaction.
|
A customizable message dialog window using tkinter.
|
||||||
|
|
||||||
This class creates modal dialogs for displaying information, warnings, errors,
|
This class creates modal dialogs for displaying information, warnings, errors,
|
||||||
or questions to the user. It supports multiple button configurations, custom
|
or questions to the user. It supports multiple button configurations and custom
|
||||||
icons, keyboard navigation, and command binding. The dialog is centered on the
|
icons. The dialog is centered on the screen and handles user interactions.
|
||||||
screen and handles user interactions with focus management and accessibility.
|
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
message_type (str): Type of message ("info", "error", "warning", "ask").
|
message_type (str): Type of message ("info", "error", "warning", "ask").
|
||||||
text (str): Main message content to display.
|
text (str): Main message content.
|
||||||
buttons (List[str]): List of button labels (e.g., ["OK", "Cancel"]).
|
buttons (List[str]): List of button labels (e.g., ["OK", "Cancel"]).
|
||||||
result (bool or None):
|
result (bool): True if the user clicked a positive button (like "Yes" or "OK"), else False.
|
||||||
- True for positive actions (Yes, OK)
|
icons: Dictionary mapping message types to tkinter.PhotoImage objects.
|
||||||
- False for negative actions (No, Cancel)
|
|
||||||
- None if "Cancel" was clicked with ≥3 buttons
|
|
||||||
icons: Dictionary mapping message types to tkinter.PhotoImage objects
|
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
message_type: Type of message dialog (default: "info")
|
message_type: Type of message dialog (default: "info").
|
||||||
text: Message content to display
|
text: Message content to display.
|
||||||
buttons: List of button labels (default: ["OK"])
|
buttons: List of button labels (default: ["OK"]).
|
||||||
master: Parent tkinter window (optional)
|
master: Parent tkinter window (optional).
|
||||||
commands: List of callables for each button (default: [None])
|
commands: List of callables for each button (default: [None]).
|
||||||
icon: Custom icon path (overrides default icons if provided)
|
icon: Custom icon path (overrides default icons if provided).
|
||||||
title: Window title (default: derived from message_type)
|
title: Window title (default: derived from message_type).
|
||||||
font: Font tuple for text styling
|
|
||||||
wraplength: Text wrapping width in pixels
|
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
_get_title(): Returns the default window title based on message type.
|
_get_title(): Returns the default window title based on message type.
|
||||||
_load_icons(): Loads icons from system paths or fallback locations.
|
_load_icons(): Loads icons from system paths or fallback locations.
|
||||||
_on_button_click(button_text): Sets result and closes the dialog.
|
_on_button_click(button_text): Sets result and closes the dialog.
|
||||||
show(): Displays the dialog and waits for user response.
|
show(): Displays the dialog and waits for user response (returns self.result).
|
||||||
|
|
||||||
Example Usage:
|
|
||||||
|
|
||||||
1. Basic Info Dialog:
|
|
||||||
>>> MessageDialog(
|
|
||||||
... text="This is an information message.")
|
|
||||||
>>> result = dialog.show()
|
|
||||||
>>> print("User clicked OK:", result)
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
My Favorite Example,
|
|
||||||
for simply information message:
|
|
||||||
|
|
||||||
>>> MessageDialog(text="This is an information message.")
|
|
||||||
>>> result = MessageDialog(text="This is an information message.").show()
|
|
||||||
|
|
||||||
Example Usage:
|
|
||||||
|
|
||||||
2. Error Dialog with Custom Command:
|
|
||||||
>>> def on_retry():
|
|
||||||
... print("User selected Retry")
|
|
||||||
|
|
||||||
>>> dialog = MessageDialog(
|
|
||||||
... message_type="error",
|
|
||||||
... text="An error occurred during processing.",
|
|
||||||
... buttons=["Retry", "Cancel"],
|
|
||||||
... commands=[on_retry, None],
|
|
||||||
... title="Critical Error"
|
|
||||||
... )
|
|
||||||
>>> result = dialog.show()
|
|
||||||
>>> print("User selected Retry:", result)
|
|
||||||
|
|
||||||
Example Usage:
|
|
||||||
|
|
||||||
3. And a special example for a "open link" button:
|
|
||||||
Be careful not to forget to import it into the script in which
|
|
||||||
this dialog is used!!! import webbrowser from functools import partial
|
|
||||||
|
|
||||||
>>> MessageDialog(
|
|
||||||
... "info"
|
|
||||||
... text="This is an information message.",
|
|
||||||
... buttons=["Yes", "Go to Exapmle"],
|
|
||||||
... commands=[
|
|
||||||
... None, # Default on "OK"
|
|
||||||
... partial(webbrowser.open, "https://exapmle.com"),
|
|
||||||
... ],
|
|
||||||
... icon="/pathh/to/custom/icon.png",
|
|
||||||
... title="Example",
|
|
||||||
... )
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
- Returns None if "Cancel" was clicked with ≥3 buttons
|
|
||||||
- Supports keyboard navigation (Left/Right arrows and Enter)
|
|
||||||
- Dialog automatically centers on screen
|
|
||||||
- Result is False for window close (X) with 2 buttons
|
|
||||||
- Font and wraplength parameters enable text styling
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DEFAULT_ICON_PATH = "/usr/share/icons/lx-icons"
|
DEFAULT_ICON_PATH = "/usr/share/icons/lx-icons"
|
||||||
@ -140,7 +191,7 @@ class MessageDialog:
|
|||||||
|
|
||||||
# Layout
|
# Layout
|
||||||
frame = ttk.Frame(self.window)
|
frame = ttk.Frame(self.window)
|
||||||
frame.pack(expand=True, fill="both", padx=15, pady=8)
|
frame.pack(expand=True, fill="both")
|
||||||
|
|
||||||
# Grid-Configuration
|
# Grid-Configuration
|
||||||
frame.grid_rowconfigure(0, weight=1)
|
frame.grid_rowconfigure(0, weight=1)
|
||||||
@ -167,12 +218,13 @@ class MessageDialog:
|
|||||||
row=0,
|
row=0,
|
||||||
column=1,
|
column=1,
|
||||||
padx=(10, 20),
|
padx=(10, 20),
|
||||||
|
pady=(8, 20),
|
||||||
sticky="nsew",
|
sticky="nsew",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create button frame
|
# Create button frame
|
||||||
self.button_frame = ttk.Frame(frame)
|
self.button_frame = ttk.Frame(frame)
|
||||||
self.button_frame.grid(row=1, columnspan=2, pady=(8, 10))
|
self.button_frame.grid(row=1, columnspan=2, pady=(15, 10))
|
||||||
|
|
||||||
for i, btn_text in enumerate(buttons):
|
for i, btn_text in enumerate(buttons):
|
||||||
if commands and len(commands) > i and commands[i] is not None:
|
if commands and len(commands) > i and commands[i] is not None:
|
||||||
@ -191,7 +243,7 @@ class MessageDialog:
|
|||||||
)
|
)
|
||||||
|
|
||||||
padx_value = 50 if self.icon is not None and len(buttons) == 2 else 10
|
padx_value = 50 if self.icon is not None and len(buttons) == 2 else 10
|
||||||
btn.pack(side="left" if i == 0 else "right", padx=padx_value, pady=5)
|
btn.pack(side="left" if i == 0 else "right", padx=padx_value, pady=15)
|
||||||
btn.focus_set() if i == 0 else None # Set focus on first button
|
btn.focus_set() if i == 0 else None # Set focus on first button
|
||||||
self.buttons_widgets.append(btn)
|
self.buttons_widgets.append(btn)
|
||||||
|
|
||||||
@ -202,7 +254,7 @@ class MessageDialog:
|
|||||||
self.window.attributes("-alpha", 0.0) # 100% Transparencence
|
self.window.attributes("-alpha", 0.0) # 100% Transparencence
|
||||||
self.window.after(200, lambda: self.window.attributes("-alpha", 100.0))
|
self.window.after(200, lambda: self.window.attributes("-alpha", 100.0))
|
||||||
self.window.update() # Window update before centering!
|
self.window.update() # Window update before centering!
|
||||||
LxTools.center_window_cross_platform(
|
Center.center_window_cross_platform(
|
||||||
self.window, self.window.winfo_width(), self.window.winfo_height()
|
self.window, self.window.winfo_width(), self.window.winfo_height()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -257,12 +309,12 @@ class MessageDialog:
|
|||||||
if os.path.exists(icon_paths[key]):
|
if os.path.exists(icon_paths[key]):
|
||||||
self.icons[key] = tk.PhotoImage(file=icon_paths[key])
|
self.icons[key] = tk.PhotoImage(file=icon_paths[key])
|
||||||
else:
|
else:
|
||||||
if os.path.exists(fallback_paths[key]):
|
self.icons[key] = tk.PhotoImage(file=fallback_paths[key])
|
||||||
self.icons[key] = tk.PhotoImage(file=fallback_paths[key])
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error on load Icon '{[key]}': {e}")
|
print(f"Error on load Icon '{[key]}': {e}")
|
||||||
self.icons[key] = tk.PhotoImage()
|
self.icons[key] = tk.PhotoImage()
|
||||||
print(f"⚠️ No Icon found for '{key}'. Use standard Tkinter icon.")
|
print(f"⚠️ No Icon found for '{key}'. Use standard Tkinter icon.")
|
||||||
|
|
||||||
return self.icons
|
return self.icons
|
||||||
|
|
||||||
def _get_icon_path(self) -> str:
|
def _get_icon_path(self) -> str:
|
||||||
|
Reference in New Issue
Block a user