mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-14 03:31:50 +02:00
feat!: add support for auto updates
This commit is contained in:
@ -1,169 +1,295 @@
|
|||||||
# TODO autoupdate disabled
|
from __future__ import annotations
|
||||||
# from __future__ import annotations
|
|
||||||
#
|
from typing import TYPE_CHECKING, Literal, overload
|
||||||
# import threading
|
|
||||||
# from queue import Queue
|
from bec_lib.endpoints import MessageEndpoints
|
||||||
# from typing import TYPE_CHECKING
|
from bec_lib.logger import bec_logger
|
||||||
#
|
from bec_lib.messages import ScanStatusMessage
|
||||||
# from pydantic import BaseModel
|
|
||||||
#
|
from bec_widgets.utils.error_popups import SafeSlot
|
||||||
# if TYPE_CHECKING:
|
|
||||||
# from .client import BECDockArea, BECFigure
|
if TYPE_CHECKING: # pragma: no cover
|
||||||
#
|
from bec_widgets.utils.bec_widget import BECWidget
|
||||||
#
|
from bec_widgets.widgets.containers.dock.dock import BECDock
|
||||||
# class ScanInfo(BaseModel):
|
from bec_widgets.widgets.containers.dock.dock_area import BECDockArea
|
||||||
# scan_id: str
|
from bec_widgets.widgets.plots.image.image import Image
|
||||||
# scan_number: int
|
from bec_widgets.widgets.plots.motor_map.motor_map import MotorMap
|
||||||
# scan_name: str
|
from bec_widgets.widgets.plots.multi_waveform.multi_waveform import MultiWaveform
|
||||||
# scan_report_devices: list
|
from bec_widgets.widgets.plots.scatter_waveform.scatter_waveform import ScatterWaveform
|
||||||
# monitored_devices: list
|
from bec_widgets.widgets.plots.waveform.waveform import Waveform
|
||||||
# status: str
|
|
||||||
# model_config: dict = {"validate_assignment": True}
|
|
||||||
#
|
logger = bec_logger.logger
|
||||||
#
|
|
||||||
# class AutoUpdates:
|
|
||||||
# create_default_dock: bool = False
|
class AutoUpdates:
|
||||||
# enabled: bool = False
|
_default_dock: BECDock
|
||||||
# dock_name: str = None
|
|
||||||
#
|
def __init__(self, dock_area: BECDockArea):
|
||||||
# def __init__(self, gui: BECDockArea):
|
self.dock_area = dock_area
|
||||||
# self.gui = gui
|
self.bec_dispatcher = dock_area.bec_dispatcher
|
||||||
# self._default_dock = None
|
self._default_dock = None # type:ignore
|
||||||
# self._default_fig = None
|
self.current_widget: BECWidget | None = None
|
||||||
#
|
self.dock_name = None
|
||||||
# def start_default_dock(self):
|
self._enabled = False
|
||||||
# """
|
|
||||||
# Create a default dock for the auto updates.
|
def connect(self):
|
||||||
# """
|
"""
|
||||||
# self.dock_name = "default_figure"
|
Establish all connections for the auto updates.
|
||||||
# self._default_dock = self.gui.new(self.dock_name)
|
"""
|
||||||
# self._default_dock.new("BECFigure")
|
self.bec_dispatcher.connect_slot(self._on_scan_status, MessageEndpoints.scan_status())
|
||||||
# self._default_fig = self._default_dock.elements_list[0]
|
|
||||||
#
|
def disconnect(self):
|
||||||
# @staticmethod
|
"""
|
||||||
# def get_scan_info(msg) -> ScanInfo:
|
Disconnect all connections for the auto updates.
|
||||||
# """
|
"""
|
||||||
# Update the script with the given data.
|
self.bec_dispatcher.disconnect_slot(
|
||||||
# """
|
self._on_scan_status, MessageEndpoints.scan_status() # type:ignore
|
||||||
# info = msg.info
|
)
|
||||||
# status = msg.status
|
|
||||||
# scan_id = msg.scan_id
|
@SafeSlot()
|
||||||
# scan_number = info.get("scan_number", 0)
|
def _on_scan_status(self, content: dict, metadata: dict) -> None:
|
||||||
# scan_name = info.get("scan_name", "Unknown")
|
"""
|
||||||
# scan_report_devices = info.get("scan_report_devices", [])
|
Callback for scan status messages.
|
||||||
# monitored_devices = info.get("readout_priority", {}).get("monitored", [])
|
"""
|
||||||
# monitored_devices = [dev for dev in monitored_devices if dev not in scan_report_devices]
|
msg = ScanStatusMessage(**content, metadata=metadata)
|
||||||
# return ScanInfo(
|
|
||||||
# scan_id=scan_id,
|
match msg.status:
|
||||||
# scan_number=scan_number,
|
case "open":
|
||||||
# scan_name=scan_name,
|
self.on_scan_open(msg)
|
||||||
# scan_report_devices=scan_report_devices,
|
case "closed":
|
||||||
# monitored_devices=monitored_devices,
|
self.on_scan_closed(msg)
|
||||||
# status=status,
|
case ["aborted", "halted"]:
|
||||||
# )
|
self.on_scan_abort(msg)
|
||||||
#
|
case _:
|
||||||
# def get_default_figure(self) -> BECFigure | None:
|
pass
|
||||||
# """
|
|
||||||
# Get the default figure from the GUI.
|
def start_default_dock(self):
|
||||||
# """
|
"""
|
||||||
# return self._default_fig
|
Create a default dock for the auto updates.
|
||||||
#
|
"""
|
||||||
# def do_update(self, msg):
|
self.dock_name = "update_dock"
|
||||||
# """
|
self._default_dock = self.dock_area.new(self.dock_name)
|
||||||
# Run the update function if enabled.
|
self.current_widget = self._default_dock.new("Waveform")
|
||||||
# """
|
|
||||||
# if not self.enabled:
|
@overload
|
||||||
# return
|
def set_dock_to_widget(self, widget: Literal["Waveform"]) -> Waveform: ...
|
||||||
# if msg.status != "open":
|
|
||||||
# return
|
@overload
|
||||||
# info = self.get_scan_info(msg)
|
def set_dock_to_widget(self, widget: Literal["Image"]) -> Image: ...
|
||||||
# return self.handler(info)
|
|
||||||
#
|
@overload
|
||||||
# def get_selected_device(self, monitored_devices, selected_device):
|
def set_dock_to_widget(self, widget: Literal["ScatterWaveform"]) -> ScatterWaveform: ...
|
||||||
# """
|
|
||||||
# Get the selected device for the plot. If no device is selected, the first
|
@overload
|
||||||
# device in the monitored devices list is selected.
|
def set_dock_to_widget(self, widget: Literal["MotorMap"]) -> MotorMap: ...
|
||||||
# """
|
|
||||||
# if selected_device:
|
@overload
|
||||||
# return selected_device
|
def set_dock_to_widget(self, widget: Literal["MultiWaveform"]) -> MultiWaveform: ...
|
||||||
# if len(monitored_devices) > 0:
|
|
||||||
# sel_device = monitored_devices[0]
|
def set_dock_to_widget(
|
||||||
# return sel_device
|
self,
|
||||||
# return None
|
widget: Literal["Waveform", "Image", "ScatterWaveform", "MotorMap", "MultiWaveForm"] | str,
|
||||||
#
|
) -> BECWidget:
|
||||||
# def handler(self, info: ScanInfo) -> None:
|
"""
|
||||||
# """
|
Set the dock to the widget.
|
||||||
# Default update function.
|
|
||||||
# """
|
Args:
|
||||||
# if info.scan_name == "line_scan" and info.scan_report_devices:
|
widget (str): The widget to set the dock to. Must be the name of a valid widget class.
|
||||||
# return self.simple_line_scan(info)
|
|
||||||
# if info.scan_name == "grid_scan" and info.scan_report_devices:
|
Returns:
|
||||||
# return self.simple_grid_scan(info)
|
BECWidget: The widget that was set.
|
||||||
# if info.scan_report_devices:
|
"""
|
||||||
# return self.best_effort(info)
|
if self._default_dock is None or self.current_widget is None:
|
||||||
#
|
logger.warning(
|
||||||
# def simple_line_scan(self, info: ScanInfo) -> None:
|
f"Auto Updates: No default dock found. Creating a new one with name {self.dock_name}"
|
||||||
# """
|
)
|
||||||
# Simple line scan.
|
self.start_default_dock()
|
||||||
# """
|
assert self.current_widget is not None
|
||||||
# fig = self.get_default_figure()
|
|
||||||
# if not fig:
|
if not self.current_widget.__class__.__name__ == widget:
|
||||||
# return
|
self._default_dock.delete(self.current_widget.object_name)
|
||||||
# dev_x = info.scan_report_devices[0]
|
self.current_widget = self._default_dock.new(widget)
|
||||||
# selected_device = yield self.gui.selected_device
|
return self.current_widget
|
||||||
# dev_y = self.get_selected_device(info.monitored_devices, selected_device)
|
|
||||||
# if not dev_y:
|
def get_selected_device(
|
||||||
# return
|
self, monitored_devices, selected_device: str | None = None
|
||||||
# yield fig.clear_all()
|
) -> str | None:
|
||||||
# yield fig.plot(
|
"""
|
||||||
# x_name=dev_x,
|
Get the selected device for the plot. If no device is selected, the first
|
||||||
# y_name=dev_y,
|
device in the monitored devices list is selected.
|
||||||
# label=f"Scan {info.scan_number} - {dev_y}",
|
"""
|
||||||
# title=f"Scan {info.scan_number}",
|
|
||||||
# x_label=dev_x,
|
if selected_device is None:
|
||||||
# y_label=dev_y,
|
selected_device = self.dock_area.selected_device
|
||||||
# )
|
if selected_device:
|
||||||
#
|
return selected_device
|
||||||
# def simple_grid_scan(self, info: ScanInfo) -> None:
|
if len(monitored_devices) > 0:
|
||||||
# """
|
sel_device = monitored_devices[0]
|
||||||
# Simple grid scan.
|
return sel_device
|
||||||
# """
|
return None
|
||||||
# fig = self.get_default_figure()
|
|
||||||
# if not fig:
|
@property
|
||||||
# return
|
def enabled(self) -> bool:
|
||||||
# dev_x = info.scan_report_devices[0]
|
"""
|
||||||
# dev_y = info.scan_report_devices[1]
|
Get the enabled status of the auto updates.
|
||||||
# selected_device = yield self.gui.selected_device
|
"""
|
||||||
# dev_z = self.get_selected_device(info.monitored_devices, selected_device)
|
return self._enabled
|
||||||
# yield fig.clear_all()
|
|
||||||
# yield fig.plot(
|
@enabled.setter
|
||||||
# x_name=dev_x,
|
def enabled(self, value: bool) -> None:
|
||||||
# y_name=dev_y,
|
"""
|
||||||
# z_name=dev_z,
|
Set the enabled status of the auto updates.
|
||||||
# label=f"Scan {info.scan_number} - {dev_z}",
|
"""
|
||||||
# title=f"Scan {info.scan_number}",
|
if self._enabled == value:
|
||||||
# x_label=dev_x,
|
return
|
||||||
# y_label=dev_y,
|
self._enabled = value
|
||||||
# )
|
|
||||||
#
|
if value:
|
||||||
# def best_effort(self, info: ScanInfo) -> None:
|
self.connect()
|
||||||
# """
|
self.on_start()
|
||||||
# Best effort scan.
|
else:
|
||||||
# """
|
self.disconnect()
|
||||||
# fig = self.get_default_figure()
|
self.on_stop()
|
||||||
# if not fig:
|
|
||||||
# return
|
########################################################################
|
||||||
# dev_x = info.scan_report_devices[0]
|
################# Update Functions #####################################
|
||||||
# selected_device = yield self.gui.selected_device
|
########################################################################
|
||||||
# dev_y = self.get_selected_device(info.monitored_devices, selected_device)
|
|
||||||
# if not dev_y:
|
def simple_line_scan(self, info: ScanStatusMessage) -> None:
|
||||||
# return
|
"""
|
||||||
# yield fig.clear_all()
|
Simple line scan.
|
||||||
# yield fig.plot(
|
|
||||||
# x_name=dev_x,
|
Args:
|
||||||
# y_name=dev_y,
|
info (ScanStatusMessage): The scan status message.
|
||||||
# label=f"Scan {info.scan_number} - {dev_y}",
|
"""
|
||||||
# title=f"Scan {info.scan_number}",
|
|
||||||
# x_label=dev_x,
|
# Set the dock to the waveform widget
|
||||||
# y_label=dev_y,
|
wf = self.set_dock_to_widget("Waveform")
|
||||||
# )
|
|
||||||
|
# Get the scan report devices reported by the scan
|
||||||
|
dev_x = info.scan_report_devices[0] # type:ignore
|
||||||
|
|
||||||
|
# For the y axis, get the selected device
|
||||||
|
dev_y = self.get_selected_device(info.readout_priority["monitored"]) # type:ignore
|
||||||
|
if not dev_y:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Clear the waveform widget and plot the data
|
||||||
|
# with the scan number and device names
|
||||||
|
# as the label and title
|
||||||
|
wf.clear_all()
|
||||||
|
wf.plot(
|
||||||
|
x_name=dev_x,
|
||||||
|
y_name=dev_y,
|
||||||
|
label=f"Scan {info.scan_number} - {dev_y}",
|
||||||
|
title=f"Scan {info.scan_number}",
|
||||||
|
x_label=dev_x,
|
||||||
|
y_label=dev_y,
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"Auto Update [simple_line_scan]: Started plot with: x_name={dev_x}, y_name={dev_y}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def simple_grid_scan(self, info: ScanStatusMessage) -> None:
|
||||||
|
"""
|
||||||
|
Simple grid scan.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
info (ScanStatusMessage): The scan status message.
|
||||||
|
"""
|
||||||
|
# Set the dock to the scatter waveform widget
|
||||||
|
scatter = self.set_dock_to_widget("ScatterWaveform")
|
||||||
|
|
||||||
|
# Get the scan report devices reported by the scan
|
||||||
|
dev_x, dev_y = info.scan_report_devices[0], info.scan_report_devices[1] # type:ignore
|
||||||
|
dev_z = self.get_selected_device(info.readout_priority["monitored"]) # type:ignore
|
||||||
|
|
||||||
|
# Clear the scatter waveform widget and plot the data
|
||||||
|
scatter.clear_all()
|
||||||
|
scatter.plot(
|
||||||
|
x_name=dev_x, y_name=dev_y, z_name=dev_z, label=f"Scan {info.scan_number} - {dev_z}"
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
f"Auto Update [simple_grid_scan]: Started plot with: x_name={dev_x}, y_name={dev_y}, z_name={dev_z}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def best_effort(self, info: ScanStatusMessage) -> None:
|
||||||
|
"""
|
||||||
|
Best effort scan.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
info (ScanStatusMessage): The scan status message.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# If the scan report devices are empty, there is nothing we can do
|
||||||
|
if not info.scan_report_devices:
|
||||||
|
return
|
||||||
|
dev_x = info.scan_report_devices[0] # type:ignore
|
||||||
|
dev_y = self.get_selected_device(info.readout_priority["monitored"]) # type:ignore
|
||||||
|
if not dev_y:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Set the dock to the waveform widget
|
||||||
|
wf = self.set_dock_to_widget("Waveform")
|
||||||
|
|
||||||
|
# Clear the waveform widget and plot the data
|
||||||
|
wf.clear_all()
|
||||||
|
wf.plot(
|
||||||
|
x_name=dev_x,
|
||||||
|
y_name=dev_y,
|
||||||
|
label=f"Scan {info.scan_number} - {dev_y}",
|
||||||
|
title=f"Scan {info.scan_number}",
|
||||||
|
x_label=dev_x,
|
||||||
|
y_label=dev_y,
|
||||||
|
)
|
||||||
|
|
||||||
|
logger.info(f"Auto Update [best_effort]: Started plot with: x_name={dev_x}, y_name={dev_y}")
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
################# GUI Callbacks #######################################
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
def on_start(self) -> None:
|
||||||
|
"""
|
||||||
|
Procedure to run when the auto updates are enabled.
|
||||||
|
"""
|
||||||
|
self.start_default_dock()
|
||||||
|
|
||||||
|
def on_stop(self) -> None:
|
||||||
|
"""
|
||||||
|
Procedure to run when the auto updates are disabled.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def on_scan_open(self, msg: ScanStatusMessage) -> None:
|
||||||
|
"""
|
||||||
|
Procedure to run when a scan starts.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
msg (ScanStatusMessage): The scan status message.
|
||||||
|
"""
|
||||||
|
if msg.scan_name == "line_scan" and msg.scan_report_devices:
|
||||||
|
return self.simple_line_scan(msg)
|
||||||
|
if msg.scan_name == "grid_scan" and msg.scan_report_devices:
|
||||||
|
return self.simple_grid_scan(msg)
|
||||||
|
if msg.scan_report_devices:
|
||||||
|
return self.best_effort(msg)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def on_scan_closed(self, msg: ScanStatusMessage) -> None:
|
||||||
|
"""
|
||||||
|
Procedure to run when a scan ends.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
msg (ScanStatusMessage): The scan status message.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def on_scan_abort(self, msg: ScanStatusMessage) -> None:
|
||||||
|
"""
|
||||||
|
Procedure to run when a scan is aborted.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
msg (ScanStatusMessage): The scan status message.
|
||||||
|
"""
|
||||||
|
@ -363,13 +363,6 @@ class BECDockArea(RPCBase):
|
|||||||
Return all floating docks to the dock area.
|
Return all floating docks to the dock area.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@property
|
|
||||||
@rpc_call
|
|
||||||
def selected_device(self) -> "str":
|
|
||||||
"""
|
|
||||||
None
|
|
||||||
"""
|
|
||||||
|
|
||||||
@rpc_call
|
@rpc_call
|
||||||
def save_state(self) -> "dict":
|
def save_state(self) -> "dict":
|
||||||
"""
|
"""
|
||||||
@ -379,6 +372,26 @@ class BECDockArea(RPCBase):
|
|||||||
dict: The state of the dock area.
|
dict: The state of the dock area.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@property
|
||||||
|
@rpc_call
|
||||||
|
def selected_device(self) -> "str | None":
|
||||||
|
"""
|
||||||
|
Get the selected device from the auto update config.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The selected device. If no device is selected, None is returned.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@selected_device.setter
|
||||||
|
@rpc_call
|
||||||
|
def selected_device(self) -> "str | None":
|
||||||
|
"""
|
||||||
|
Get the selected device from the auto update config.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The selected device. If no device is selected, None is returned.
|
||||||
|
"""
|
||||||
|
|
||||||
@rpc_call
|
@rpc_call
|
||||||
def restore_state(
|
def restore_state(
|
||||||
self, state: "dict" = None, missing: "Literal['ignore', 'error']" = "ignore", extra="bottom"
|
self, state: "dict" = None, missing: "Literal['ignore', 'error']" = "ignore", extra="bottom"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Literal, Optional
|
from typing import TYPE_CHECKING, Literal, Optional
|
||||||
from weakref import WeakValueDictionary
|
from weakref import WeakValueDictionary
|
||||||
|
|
||||||
from bec_lib.endpoints import MessageEndpoints
|
from bec_lib.endpoints import MessageEndpoints
|
||||||
@ -37,6 +37,9 @@ from bec_widgets.widgets.services.bec_status_box.bec_status_box import BECStatus
|
|||||||
from bec_widgets.widgets.utility.logpanel.logpanel import LogPanel
|
from bec_widgets.widgets.utility.logpanel.logpanel import LogPanel
|
||||||
from bec_widgets.widgets.utility.visual.dark_mode_button.dark_mode_button import DarkModeButton
|
from bec_widgets.widgets.utility.visual.dark_mode_button.dark_mode_button import DarkModeButton
|
||||||
|
|
||||||
|
if TYPE_CHECKING: # pragma: no cover
|
||||||
|
from bec_widgets.cli.auto_updates import AutoUpdates
|
||||||
|
|
||||||
logger = bec_logger.logger
|
logger = bec_logger.logger
|
||||||
|
|
||||||
|
|
||||||
@ -63,8 +66,9 @@ class BECDockArea(BECWidget, QWidget):
|
|||||||
"remove",
|
"remove",
|
||||||
"detach_dock",
|
"detach_dock",
|
||||||
"attach_all",
|
"attach_all",
|
||||||
"selected_device",
|
|
||||||
"save_state",
|
"save_state",
|
||||||
|
"selected_device",
|
||||||
|
"selected_device.setter",
|
||||||
"restore_state",
|
"restore_state",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -96,6 +100,8 @@ class BECDockArea(BECWidget, QWidget):
|
|||||||
self.layout.setSpacing(5)
|
self.layout.setSpacing(5)
|
||||||
self.layout.setContentsMargins(0, 0, 0, 0)
|
self.layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
|
self.auto_update: AutoUpdates | None = None
|
||||||
|
self._auto_update_selected_device: str | None = None
|
||||||
self._instructions_visible = True
|
self._instructions_visible = True
|
||||||
|
|
||||||
self.dark_mode_button = DarkModeButton(parent=self, parent_id=self.gui_id, toolbar=True)
|
self.dark_mode_button = DarkModeButton(parent=self, parent_id=self.gui_id, toolbar=True)
|
||||||
@ -253,15 +259,33 @@ class BECDockArea(BECWidget, QWidget):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def selected_device(self) -> str:
|
def selected_device(self) -> str | None:
|
||||||
gui_id = QApplication.instance().gui_id
|
"""
|
||||||
auto_update_config = self.client.connector.get(
|
Get the selected device from the auto update config.
|
||||||
MessageEndpoints.gui_auto_update_config(gui_id)
|
|
||||||
)
|
Returns:
|
||||||
try:
|
str: The selected device. If no device is selected, None is returned.
|
||||||
return auto_update_config.selected_device
|
"""
|
||||||
except AttributeError:
|
return self._auto_update_selected_device
|
||||||
return None
|
|
||||||
|
@selected_device.setter
|
||||||
|
def selected_device(self, value: str | None) -> None:
|
||||||
|
"""
|
||||||
|
Set the selected device in the auto update config.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value(str): The selected device.
|
||||||
|
"""
|
||||||
|
self._auto_update_selected_device = value
|
||||||
|
|
||||||
|
def set_auto_update(self, auto_update_cls: type[AutoUpdates]) -> None:
|
||||||
|
"""
|
||||||
|
Set the auto update object for the dock area.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
auto_update(AutoUpdates): The auto update object.
|
||||||
|
"""
|
||||||
|
self.auto_update = auto_update_cls(self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def panels(self) -> dict[str, BECDock]:
|
def panels(self) -> dict[str, BECDock]:
|
||||||
@ -447,6 +471,8 @@ class BECDockArea(BECWidget, QWidget):
|
|||||||
"""
|
"""
|
||||||
Cleanup the dock area.
|
Cleanup the dock area.
|
||||||
"""
|
"""
|
||||||
|
if self.auto_update:
|
||||||
|
self.auto_update.enabled = False
|
||||||
self.delete_all()
|
self.delete_all()
|
||||||
self.toolbar.close()
|
self.toolbar.close()
|
||||||
self.toolbar.deleteLater()
|
self.toolbar.deleteLater()
|
||||||
|
Reference in New Issue
Block a user