1 Commits

Author SHA1 Message Date
kaibot
fc5b330ec9 Fix BalBuildWillDialog: rimuovi widget vecchi per evitare sfarfallio su Windows
- Aggiungi metodo clear_layout per rimuovere e eliminare widget dal layout
- Modifica msg_update per creare un solo QLabel per messaggio
- Imposta setWordWrap(True) per gestire correttamente il testo

Fix #
2026-04-08 23:21:58 +00:00
3 changed files with 20 additions and 515 deletions

View File

@@ -1 +1 @@
0.2.10 0.2.8

View File

@@ -1,7 +1,7 @@
{ {
"name": "BAL", "name": "BAL",
"fullname": "Bitcoin After Life", "fullname": "Bitcoin After Life",
"description": "Provides free and decentralized inheritance support<br> Version: 0.2.10", "description": "Provides free and decentralized inheritance support<br> Version: 0.2.7",
"author":"Svatantrya", "author":"Svatantrya",
"available_for": ["qt"], "available_for": ["qt"],
"icon":"icons/bal32x32.png" "icon":"icons/bal32x32.png"

531
qt.py
View File

@@ -390,26 +390,6 @@ class shown_cv:
class BalWindow(Logger): class BalWindow(Logger):
"""Main application window for Bitcoin After Life inheritance management.
This class provides the primary UI for:
- Managing inheritance plans
- Building Wills
- Handling heir configurations
- Network operations
- Transaction signing and broadcasting
Attributes:
bal_plugin (BalPlugin): Reference to the plugin instance
config (dict): Application configuration
network (Network): Network interface
wallet (Abstract_Wallet): Wallet interface
heirs (list): List of heir configurations
will (Will): Current Will being managed
building_will (bool): Flag indicating Will construction in progress
stop_build (bool): Flag to stop Will construction
"""
def __init__(self, bal_plugin: "BalPlugin", window: "ElectrumWindow"): def __init__(self, bal_plugin: "BalPlugin", window: "ElectrumWindow"):
Logger.__init__(self) Logger.__init__(self)
self.bal_plugin = bal_plugin self.bal_plugin = bal_plugin
@@ -1292,17 +1272,6 @@ class _LockTimeEditor:
class HeirsLockTimeEdit(QWidget, _LockTimeEditor): class HeirsLockTimeEdit(QWidget, _LockTimeEditor):
"""HeirsLockTimeEdit class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = HeirsLockTimeEdit(required parameters)
"""
valueEdited = pyqtSignal() valueEdited = pyqtSignal()
locktime_threshold = 50000000 locktime_threshold = 50000000
@@ -1365,17 +1334,6 @@ class HeirsLockTimeEdit(QWidget, _LockTimeEditor):
self.editor.set_locktime(x, force) self.editor.set_locktime(x, force)
"""LockTimeRawEdit class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = LockTimeRawEdit(required parameters)
"""
class LockTimeRawEdit(QLineEdit, _LockTimeEditor): class LockTimeRawEdit(QLineEdit, _LockTimeEditor):
def __init__(self, parent=None, time_edit=None): def __init__(self, parent=None, time_edit=None):
QLineEdit.__init__(self, parent) QLineEdit.__init__(self, parent)
@@ -1460,17 +1418,6 @@ class LockTimeRawEdit(QLineEdit, _LockTimeEditor):
out = min(out, self.max_allowed_value) out = min(out, self.max_allowed_value)
self.setText(str(out)) self.setText(str(out))
"""LockTimeHeightEdit class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = LockTimeHeightEdit(required parameters)
"""
class LockTimeHeightEdit(LockTimeRawEdit): class LockTimeHeightEdit(LockTimeRawEdit):
max_allowed_value = NLOCKTIME_BLOCKHEIGHT_MAX max_allowed_value = NLOCKTIME_BLOCKHEIGHT_MAX
@@ -1501,17 +1448,6 @@ def get_max_allowed_timestamp() -> int:
ts = 2**31 - 1 # INT32_MAX ts = 2**31 - 1 # INT32_MAX
datetime.fromtimestamp(ts) # test if raises datetime.fromtimestamp(ts) # test if raises
return ts return ts
"""LockTimeDateEdit class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = LockTimeDateEdit(required parameters)
"""
class LockTimeDateEdit(QDateTimeEdit, _LockTimeEditor): class LockTimeDateEdit(QDateTimeEdit, _LockTimeEditor):
@@ -1543,25 +1479,6 @@ class LockTimeDateEdit(QDateTimeEdit, _LockTimeEditor):
self.setDateTime(dt) self.setDateTime(dt)
"""Widget for editing percentage amounts.
Extends BTCAmountEdit to provide:
- Percentage-based input (0-100%)
- Validation of percentage values
- Conversion between percentage and satoshis
- Formatting for display
Attributes:
min_value (float): Minimum percentage (default 0.0)
max_value (float): Maximum percentage (default 100.0)
step (float): Increment step for percentage values
Methods:
value(): Return current percentage as float
setValue(): Set percentage value
validate(): Validate percentage range
"""
_NOT_GIVEN = object() # sentinel value _NOT_GIVEN = object() # sentinel value
@@ -1628,35 +1545,6 @@ class PercAmountEdit(BTCAmountEdit):
painter.drawText( painter.drawText(
textRect, textRect,
int(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter), int(Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter),
"""Base class for dialog windows in Bitcoin After Life.
Provides common functionality for all dialog windows including:
- Window modal behavior
- Standard button layouts (OK, Cancel)
- Size policy management
- Parent window handling
Subclasses should implement:
- __init__: Initialize dialog components
- setup_ui: Create and configure UI elements
- connect_signals: Connect signal-slot connections
Attributes:
parent (QWidget): Parent window
plugin (BalPlugin): Plugin reference
title (str): Dialog window title
Methods:
exec_(): Show dialog modally
accept(): Handle dialog acceptance
reject(): Handle dialog rejection
Example:
dialog = BalDialog(parent, plugin, "My Dialog")
if dialog.exec_() == QDialog.Accepted:
# Handle acceptance
"""
self.base_unit() + " or perc value", self.base_unit() + " or perc value",
) )
@@ -1664,33 +1552,6 @@ class PercAmountEdit(BTCAmountEdit):
class BalDialog(WindowModalDialog): class BalDialog(WindowModalDialog):
def __init__(self, parent, bal_plugin, title=None, icon="icons/bal32x32.png"): def __init__(self, parent, bal_plugin, title=None, icon="icons/bal32x32.png"):
self.parent = parent self.parent = parent
"""Base class for multi-step wizard dialogs.
Provides infrastructure for:
- Multi-page workflows
- Navigation between steps
- Progress tracking
- Validation at each step
- Final submission
Subclasses implement specific wizards:
- BalWizardHeirsWidget: Heir configuration
- BalWizardWEDownloadWidget: Wallet export download
- BalWizardWEWidget: Wallet export configuration
- BalWizardLocktimeAndFeeWidget: Locktime and fee setup
Attributes:
current_page (int): Current step index
total_pages (int): Total number of steps
data (dict): Collected data across steps
Methods:
next_page(): Move to next step
prev_page(): Move to previous step
validate_current(): Validate current step
finish(): Complete the wizard
"""
WindowModalDialog.__init__(self, parent, title) WindowModalDialog.__init__(self, parent, title)
# WindowModalDialog.__init__(self,parent) # WindowModalDialog.__init__(self,parent)
self.setWindowIcon(read_QIcon_from_bytes(bal_plugin.read_file(icon))) self.setWindowIcon(read_QIcon_from_bytes(bal_plugin.read_file(icon)))
@@ -1779,17 +1640,6 @@ class BalWizardDialog(BalDialog):
self.bal_window.update_all() self.bal_window.update_all()
pass pass
"""BalWizardWidget class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = BalWizardWidget(required parameters)
"""
def closeEvent(self, event): def closeEvent(self, event):
self.bal_window.heir_list_widget.update_will_settings() self.bal_window.heir_list_widget.update_will_settings()
@@ -1855,17 +1705,6 @@ class BalWizardWidget(QWidget):
def _on_previous(self): def _on_previous(self):
self.on_previous() self.on_previous()
"""BalWizardHeirsWidget class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = BalWizardHeirsWidget(required parameters)
"""
def get_content(self): def get_content(self):
pass pass
@@ -1900,17 +1739,6 @@ class BalWizardHeirsWidget(BalWizardWidget):
def export_to_file(self): def export_to_file(self):
self.bal_window.export_heirs() self.bal_window.export_heirs()
"""BalWizardWEDownloadWidget class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = BalWizardWEDownloadWidget(required parameters)
"""
def add_heir(self): def add_heir(self):
self.bal_window.new_heir_dialog() self.bal_window.new_heir_dialog()
self.heir_list_widget.update() self.heir_list_widget.update()
@@ -1998,17 +1826,6 @@ class BalWizardWEDownloadWidget(BalWizardWidget):
if self.validate(): if self.validate():
return self.on_next() return self.on_next()
"""BalWizardWEWidget class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = BalWizardWEWidget(required parameters)
"""
def import_json_file(self, path): def import_json_file(self, path):
data = read_json_file(path) data = read_json_file(path)
data = self._validate(data) data = self._validate(data)
@@ -2025,17 +1842,6 @@ class BalWizardWEWidget(BalWizardWidget):
def get_content(self): def get_content(self):
widget = QWidget() widget = QWidget()
vbox = QVBoxLayout(widget) vbox = QVBoxLayout(widget)
"""BalWizardLocktimeAndFeeWidget class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = BalWizardLocktimeAndFeeWidget(required parameters)
"""
vbox.addWidget( vbox.addWidget(
WillExecutorWidget( WillExecutorWidget(
self, self,
@@ -2145,30 +1951,6 @@ class BalWizardLocktimeAndFeeWidget(BalWizardWidget):
_("Fees(sats/vbyte):"), _("Fees(sats/vbyte):"),
self.heir_tx_fees, self.heir_tx_fees,
("Fee to be used in the transaction"), ("Fee to be used in the transaction"),
"""Non-blocking progress dialog for long operations.
Provides:
- Indeterminate progress bar
- Status messages
- Cancel button for interruption
- Automatic cleanup
- Thread-safe operation
Used for operations like:
- Blockchain synchronization
- Transaction broadcasting
- Will construction
- Data loading
Attributes:
message (str): Current status message
can_cancel (bool): Whether operation can be cancelled
Methods:
update_message(): Update status message
cancel(): Interrupt the operation
"""
) )
) )
@@ -2233,17 +2015,6 @@ class BalWaitingDialog(BalDialog):
self.thread.stop() self.thread.stop()
def update_message(self, msg): def update_message(self, msg):
"""BalBlockingWaitingDialog class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = BalBlockingWaitingDialog(required parameters)
"""
self.message_label.setText(msg) self.message_label.setText(msg)
def update(self, msg): def update(self, msg):
@@ -2263,17 +2034,6 @@ class BalBlockingWaitingDialog(BalDialog):
vbox = QVBoxLayout(self) vbox = QVBoxLayout(self)
vbox.addWidget(self.message_label) vbox.addWidget(self.message_label)
self.finished.connect(self.deleteLater) # see #3956 self.finished.connect(self.deleteLater) # see #3956
"""bal_checkbox class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = bal_checkbox(required parameters)
"""
# show popup # show popup
self.show() self.show()
# refresh GUI; needed for popup to appear and for message_label to get drawn # refresh GUI; needed for popup to appear and for message_label to get drawn
@@ -2309,18 +2069,6 @@ class BalBuildWillDialog(BalDialog):
COLOR_OK = "#05ad05" COLOR_OK = "#05ad05"
def __init__(self, bal_window, parent=None): def __init__(self, bal_window, parent=None):
"""Initialize the Build Will dialog.
Args:
bal_window (BalWindow): The main application window
parent (QWidget, optional): Parent widget. Defaults to None.
Initializes:
- Main UI components (message label, container widget)
- Message queue system with debounce timer
- Layout management
- Network connection
"""
if not parent: if not parent:
parent = bal_window.window parent = bal_window.window
BalDialog.__init__(self, parent, bal_window.bal_plugin, _("Building Will")) BalDialog.__init__(self, parent, bal_window.bal_plugin, _("Building Will"))
@@ -2328,43 +2076,16 @@ class BalBuildWillDialog(BalDialog):
self.updatemessage.connect(self.msg_update) self.updatemessage.connect(self.msg_update)
self.bal_window = bal_window self.bal_window = bal_window
self.bal_plugin = bal_window.bal_plugin self.bal_plugin = bal_window.bal_plugin
# Main message label
self.message_label = QLabel(_("Building Will:")) self.message_label = QLabel(_("Building Will:"))
self.vbox = QVBoxLayout(self) self.vbox = QVBoxLayout(self)
self.vbox.addWidget(self.message_label, 0) self.vbox.addWidget(self.message_label,0)
# Container for dynamic messages
self.qwidget = QWidget(self) self.qwidget = QWidget(self)
self.vbox.addWidget(self.qwidget, 1) self.vbox.addWidget(self.qwidget,1)
self.labelsbox=QVBoxLayout(self.qwidget)
# Layout for messages with reduced spacing
self.labelsbox = QVBoxLayout(self.qwidget)
self.labelsbox.setContentsMargins(0, 0, 0, 0)
self.labelsbox.setSpacing(4) # Reduced spacing between messages
# Set minimum dimensions
self.setMinimumWidth(600) self.setMinimumWidth(600)
self.setMinimumHeight(100) self.setMinimumHeight(100)
self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred) self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
self.labels = []
# Message queue implementation for efficient updates
self._message_queue = [] # Thread-safe message queue
self._message_timer = QTimer(self)
self._message_timer.setSingleShot(True)
self._message_timer.setInterval(50) # Debounce interval: 50ms
self._message_timer.timeout.connect(self._process_message_queue)
# Other initialization
self.labels = [] # Immediate message storage
self.check_row = None
self.inval_row = None
self.build_row = None
self.sign_row = None
self.push_row = None
self.network = Network.get_instance()
self._stopping = False
self.check_row = None self.check_row = None
self.inval_row = None self.inval_row = None
self.build_row = None self.build_row = None
@@ -2814,103 +2535,22 @@ class BalBuildWillDialog(BalDialog):
w.deleteLater() w.deleteLater()
def msg_update(self): def msg_update(self):
"""Updates the UI with new messages using a debounced queue system.
This method implements the following logic:
1. Adds all pending messages to the queue
2. Clears the immediate message storage
3. Starts the debounce timer if not already active
The actual UI update happens in _process_message_queue after the
debounce interval to prevent excessive UI updates.
Note:
Thread-safe operation - can be called from any thread
"""
self._message_queue.extend(self.labels)
self.labels = [] # Clear immediate labels after queuing
if not self._message_timer.isActive():
self._message_timer.start()
def _process_message_queue(self):
"""Processes queued messages with debounce for efficient UI updates.
This method:
1. Clears the existing layout
2. Processes all queued messages
3. Updates the UI once with all new messages
4. Resets the queue
5. Adjusts dialog height based on content
The debounce interval (50ms) ensures rapid message bursts are
processed in a single batch, reducing UI flicker.
Note:
Called automatically by QTimer after debounce interval
"""
if not self._message_queue:
return
# Clear existing layout
self.clear_layout(self.labelsbox) self.clear_layout(self.labelsbox)
for text in self.labels:
text = text.replace("\n","<br>")
qlabel = QLabel(text)
qlabel.setWordWrap(True)
self.labelsbox.addWidget(qlabel)
self.setMinimumHeight(30*(len(self.labels)+2))
# Process all queued messages def clear_layout(self, layout):
for text in self._message_queue: while layout.count():
try: item = layout.takeAt(0)
# Format text for rich display widget = item.widget()
formatted_text = text.replace("\n", "<br>") if widget is not None:
widget.deleteLater()
# Create label with proper settings else:
label = QLabel(formatted_text) self.clear_layout(item.layout())
label.setWordWrap(True)
label.setTextFormat(Qt.TextFormat.RichText)
label.setOpenExternalLinks(False) # Security
# Set size policy
label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Fixed)
# Add to layout
self.labelsbox.addWidget(label)
except Exception as e:
# Log errors without interrupting processing
"""Table widget for managing heir configurations.
Provides a tabular interface for:
- Adding, editing, and removing heirs
- Configuring inheritance percentages
- Setting heir addresses and conditions
- Validating heir configurations
- Sorting and filtering heir list
Inherits from MyTreeView for:
- Column-based data display
- Sorting functionality
- Filtering capabilities
- Model-view architecture
Attributes:
bal_window (BalWindow): Reference to main window
main_window (QMainWindow): Parent window
model (QStandardItemModel): Data model for heirs
Columns:
NAME: Heir name
ADDRESS: Bitcoin address
AMOUNT: Inheritance percentage
Example:
widget = HeirListWidget(window, parent)
widget.update() # Refresh heir list
"""
import logging
logging.error(f"Error creating label in BalBuildWillDialog: {e}")
# Reset queue and update dimensions
self._message_queue = []
self.setMinimumHeight(min(30 * (len(self.labels) + 2), 400)) # Max height limit
def get_text(self): def get_text(self):
return self.message_label.text() return self.message_label.text()
@@ -3183,34 +2823,6 @@ class HeirListWidget(MyTreeView, MessageBoxMixin):
return toolbar return toolbar
"""Widget for previewing Will documents before signing.
Provides functionality to:
- Render Will in human-readable format
- Highlight important clauses and conditions
- Show inheritance distribution
- Validate Will structure
- Generate PDF preview
Uses MyTreeView for:
- Column-based preview display
- Sorting and filtering
- Efficient rendering of large documents
Attributes:
bal_window (BalWindow): Reference to main window
main_window (QMainWindow): Parent window
Methods:
update(): Refresh preview display
validate(): Check Will structure
export_pdf(): Generate PDF document
Example:
preview = PreviewList(window, parent)
preview.update()
"""
def update_will_settings(self): def update_will_settings(self):
try: try:
self.heir_locktime.set_locktime(self.bal_window.will_settings["locktime"]) self.heir_locktime.set_locktime(self.bal_window.will_settings["locktime"])
@@ -3488,17 +3100,6 @@ class PreviewList(MyTreeView):
close_window.build_will_task() close_window.build_will_task()
will = {} will = {}
"""PreviewDialog class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = PreviewDialog(required parameters)
"""
for wid, w in self.bal_window.willitems.items(): for wid, w in self.bal_window.willitems.items():
if ( if (
w.get_status("VALID") w.get_status("VALID")
@@ -3580,17 +3181,6 @@ class PreviewDialog(BalDialog, MessageBoxMixin):
def update(self): def update(self):
self.transactions_list.update() self.transactions_list.update()
"""WillDetailDialog class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = WillDetailDialog(required parameters)
"""
def is_hidden(self): def is_hidden(self):
return self.isMinimized() or self.isHidden() return self.isMinimized() or self.isHidden()
@@ -3691,17 +3281,6 @@ class WillDetailDialog(BalDialog):
toggle = _("Unhide") toggle = _("Unhide")
self.toggle_replace_button.setText(f"{toggle} {_('replaced')}") self.toggle_replace_button.setText(f"{toggle} {_('replaced')}")
self.update() self.update()
"""WillWidget class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = WillWidget(required parameters)
"""
def toggle_invalidated(self): def toggle_invalidated(self):
self.bal_window.bal_plugin.hide_invalidated() self.bal_window.bal_plugin.hide_invalidated()
@@ -3793,17 +3372,6 @@ class WillWidget(QWidget):
decoded_amount = Util.decode_amount( decoded_amount = Util.decode_amount(
self.will[w].we["base_fee"], self.parent.decimal_point self.will[w].we["base_fee"], self.parent.decimal_point
) )
"""WillExecutorListWidget class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = WillExecutorListWidget(required parameters)
"""
detaillayout.addWidget( detaillayout.addWidget(
qlabel( qlabel(
@@ -4035,31 +3603,6 @@ class WillExecutorListWidget(MyTreeView):
items[self.Columns.BASE_FEE].setData( items[self.Columns.BASE_FEE].setData(
url, self.ROLE_HEIR_KEY + self.Columns.BASE_FEE url, self.ROLE_HEIR_KEY + self.Columns.BASE_FEE
) )
"""Widget for executing Will transactions.
Handles:
- Transaction construction
- Fee calculation
- Signature collection
- Transaction broadcasting
- Status monitoring
Coordinates with:
- WillExecutorListWidget: List of executors
- WillExecutorDialog: Detailed executor configuration
- BalWindow: Main application window
Attributes:
will (Will): Will being executed
executors (list): List of executor configurations
network (Network): Network interface
Methods:
execute(): Start transaction execution
stop(): Interrupt execution
validate(): Check transaction validity
"""
items[self.Columns.INFO].setData( items[self.Columns.INFO].setData(
url, self.ROLE_HEIR_KEY + self.Columns.INFO url, self.ROLE_HEIR_KEY + self.Columns.INFO
) )
@@ -4164,17 +3707,6 @@ class WillExecutorWidget(QWidget, MessageBoxMixin):
self.willexecutors_list.update, self.willexecutors_list.update,
) )
"""WillExecutorDialog class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = WillExecutorDialog(required parameters)
"""
def update_willexecutors(self, wes=None): def update_willexecutors(self, wes=None):
if not wes: if not wes:
wes = self.willexecutors_list wes = self.willexecutors_list
@@ -4210,17 +3742,6 @@ class WillExecutorDialog(BalDialog, MessageBoxMixin):
self.setMinimumSize(1000, 200) self.setMinimumSize(1000, 200)
vbox = QVBoxLayout(self) vbox = QVBoxLayout(self)
"""CheckAliveException class for Bitcoin After Life.
This class provides functionality for managing various Bitcoin After Life features.
Attributes:
See class implementation for attributes
Example:
instance = CheckAliveException(required parameters)
"""
self.will_executor_list_widget = WillExecutorWidget( self.will_executor_list_widget = WillExecutorWidget(
self, self.bal_window, self.willexecutors_list self, self.bal_window, self.willexecutors_list
) )
@@ -4247,20 +3768,4 @@ class CheckAliveException(Exception):
def __init__(self,timestamp_to_check): def __init__(self,timestamp_to_check):
self.timestamp_to_check = timestamp_to_check self.timestamp_to_check = timestamp_to_check
def __str__(self): def __str__(self):
def __del__(self):
"""Explicit cleanup to prevent memory leaks.
This destructor ensures proper cleanup of:
- Message queue timer
- All widgets in the layout
- Network connections
Called automatically when the dialog is destroyed.
"""
if hasattr(self, '_message_timer') and self._message_timer:
self._message_timer.stop()
self._message_timer.deleteLater()
self.clear_layout(self.labelsbox)
return "Check alive expired please update it: {}".format(datetime.fromtimestamp(self.timestamp_to_check).isoformat()) return "Check alive expired please update it: {}".format(datetime.fromtimestamp(self.timestamp_to_check).isoformat())