nanovna-saver/src/NanoVNASaver/Windows/DisplaySettings.py

659 wiersze
26 KiB
Python

# NanoVNASaver
#
# A python program to view and export Touchstone data from a NanoVNA
# Copyright (C) 2019, 2020 Rune B. Broberg
# Copyright (C) 2020ff NanoVNA-Saver Authors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging
from typing import List
from PyQt6 import QtWidgets, QtCore
from PyQt6.QtGui import QColor, QColorConstants, QPalette, QShortcut
from NanoVNASaver import Defaults
from NanoVNASaver.Charts.Chart import Chart, ChartColors
from NanoVNASaver.Windows.Bands import BandsWindow
from NanoVNASaver.Windows.Defaults import make_scrollable
from NanoVNASaver.Windows.MarkerSettings import MarkerSettingsWindow
from NanoVNASaver.Marker.Widget import Marker
logger = logging.getLogger(__name__)
class DisplaySettingsWindow(QtWidgets.QWidget):
def __init__(self, app: QtWidgets.QWidget):
super().__init__()
self.app = app
self.setWindowTitle("Display settings")
self.setWindowIcon(self.app.icon)
self.marker_window = MarkerSettingsWindow(self.app)
self.callback_params = {}
QShortcut(QtCore.Qt.Key.Key_Escape, self, self.hide)
layout = QtWidgets.QHBoxLayout()
make_scrollable(self, layout)
left_layout = QtWidgets.QVBoxLayout()
layout.addLayout(left_layout)
display_options_box = QtWidgets.QGroupBox("Options")
display_options_layout = QtWidgets.QFormLayout(display_options_box)
self.returnloss_group = QtWidgets.QButtonGroup()
self.returnloss_is_negative = QtWidgets.QRadioButton("Negative")
self.returnloss_is_positive = QtWidgets.QRadioButton("Positive")
self.returnloss_group.addButton(self.returnloss_is_positive)
self.returnloss_group.addButton(self.returnloss_is_negative)
display_options_layout.addRow(
"Return loss is:", self.returnloss_is_negative
)
display_options_layout.addRow("", self.returnloss_is_positive)
self.returnloss_is_positive.setChecked(
Defaults.cfg.chart.returnloss_is_positive
)
self.returnloss_is_negative.setChecked(
not Defaults.cfg.chart.returnloss_is_positive
)
self.returnloss_is_positive.toggled.connect(self.changeReturnLoss)
self.changeReturnLoss()
self.show_lines_option = QtWidgets.QCheckBox("Show lines")
show_lines_label = QtWidgets.QLabel(
"Displays a thin line between data points"
)
self.show_lines_option.stateChanged.connect(self.changeShowLines)
display_options_layout.addRow(self.show_lines_option, show_lines_label)
self.dark_mode_option = QtWidgets.QCheckBox("Dark mode")
dark_mode_label = QtWidgets.QLabel("Black background with white text")
self.dark_mode_option.stateChanged.connect(self.changeDarkMode)
display_options_layout.addRow(self.dark_mode_option, dark_mode_label)
self.trace_colors(display_options_layout)
self.pointSizeInput = QtWidgets.QSpinBox()
self.pointSizeInput.setMinimumHeight(20)
pointsize = Defaults.cfg.chart.point_size
self.pointSizeInput.setValue(pointsize)
self.changePointSize(pointsize)
self.pointSizeInput.setMinimum(1)
self.pointSizeInput.setMaximum(10)
self.pointSizeInput.setSuffix(" px")
self.pointSizeInput.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
self.pointSizeInput.valueChanged.connect(self.changePointSize)
display_options_layout.addRow("Point size", self.pointSizeInput)
self.lineThicknessInput = QtWidgets.QSpinBox()
self.lineThicknessInput.setMinimumHeight(20)
linethickness = Defaults.cfg.chart.line_thickness
self.lineThicknessInput.setValue(linethickness)
self.changeLineThickness(linethickness)
self.lineThicknessInput.setMinimum(1)
self.lineThicknessInput.setMaximum(10)
self.lineThicknessInput.setSuffix(" px")
self.lineThicknessInput.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
self.lineThicknessInput.valueChanged.connect(self.changeLineThickness)
display_options_layout.addRow("Line thickness", self.lineThicknessInput)
self.markerSizeInput = QtWidgets.QSpinBox()
self.markerSizeInput.setMinimumHeight(20)
markersize = Defaults.cfg.chart.marker_size
self.markerSizeInput.setValue(markersize)
self.markerSizeInput.setMinimum(4)
self.markerSizeInput.setMaximum(20)
self.markerSizeInput.setSingleStep(2)
self.markerSizeInput.setSuffix(" px")
self.markerSizeInput.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight)
self.markerSizeInput.valueChanged.connect(self.changeMarkerSize)
display_options_layout.addRow("Marker size", self.markerSizeInput)
self.show_marker_number_option = QtWidgets.QCheckBox(
"Show marker numbers"
)
show_marker_number_label = QtWidgets.QLabel(
"Displays the marker number next to the marker"
)
self.show_marker_number_option.stateChanged.connect(
self.changeShowMarkerNumber
)
display_options_layout.addRow(
self.show_marker_number_option, show_marker_number_label
)
self.filled_marker_option = QtWidgets.QCheckBox("Filled markers")
filled_marker_label = QtWidgets.QLabel(
"Shows the marker as a filled triangle"
)
self.filled_marker_option.stateChanged.connect(self.changeFilledMarkers)
display_options_layout.addRow(
self.filled_marker_option, filled_marker_label
)
self.marker_tip_group = QtWidgets.QButtonGroup()
self.marker_at_center = QtWidgets.QRadioButton(
"At the center of the marker"
)
self.marker_at_tip = QtWidgets.QRadioButton("At the tip of the marker")
self.marker_tip_group.addButton(self.marker_at_center)
self.marker_tip_group.addButton(self.marker_at_tip)
display_options_layout.addRow("Data point is:", self.marker_at_center)
display_options_layout.addRow("", self.marker_at_tip)
self.marker_at_tip.setChecked(Defaults.cfg.chart.marker_at_tip)
self.marker_at_center.setChecked(not Defaults.cfg.chart.marker_at_tip)
self.marker_at_tip.toggled.connect(self.changeMarkerAtTip)
self.changeMarkerAtTip()
color_options_box = QtWidgets.QGroupBox("Chart colors")
color_options_layout = QtWidgets.QFormLayout(color_options_box)
self.use_custom_colors = QtWidgets.QCheckBox("Use custom chart colors")
self.use_custom_colors.stateChanged.connect(self.updateCharts)
color_options_layout.addRow(self.use_custom_colors)
self.custom_colors(color_options_layout)
right_layout = QtWidgets.QVBoxLayout()
layout.addLayout(right_layout)
font_options_box = QtWidgets.QGroupBox("Font")
font_options_layout = QtWidgets.QFormLayout(font_options_box)
self.font_dropdown = QtWidgets.QComboBox()
self.font_dropdown.setMinimumHeight(20)
self.font_dropdown.addItems(["7", "8", "9", "10", "11", "12"])
self.font_dropdown.setCurrentText(str(Defaults.cfg.gui.font_size))
self.changeFont()
self.font_dropdown.currentTextChanged.connect(self.changeFont)
font_options_layout.addRow("Font size", self.font_dropdown)
bands_box = QtWidgets.QGroupBox("Bands")
bands_layout = QtWidgets.QFormLayout(bands_box)
self.show_bands = QtWidgets.QCheckBox("Show bands")
self.show_bands.setChecked(self.app.bands.enabled)
self.show_bands.stateChanged.connect(
lambda: self.setShowBands(self.show_bands.isChecked())
)
bands_layout.addRow(self.show_bands)
bands_layout.addRow(
"Chart bands", self.color_picker("BandsColor", "bands")
)
self.btn_manage_bands = QtWidgets.QPushButton("Manage bands")
self.btn_manage_bands.setMinimumHeight(20)
self.bandsWindow = BandsWindow(self.app)
self.btn_manage_bands.clicked.connect(self.displayBandsWindow)
bands_layout.addRow(self.btn_manage_bands)
vswr_marker_box = QtWidgets.QGroupBox("VSWR Markers")
vswr_marker_layout = QtWidgets.QFormLayout(vswr_marker_box)
self.vswrMarkers: List[float] = self.app.settings.value(
"VSWRMarkers", [], float
)
if isinstance(self.vswrMarkers, float):
# Single values from the .ini become floats rather than lists.
# Convert them.
self.vswrMarkers = (
[] if self.vswrMarkers == 0.0 else [self.vswrMarkers]
)
vswr_marker_layout.addRow(
"VSWR Markers", self.color_picker("VSWRColor", "swr")
)
self.vswr_marker_dropdown = QtWidgets.QComboBox()
self.vswr_marker_dropdown.setMinimumHeight(20)
vswr_marker_layout.addRow(self.vswr_marker_dropdown)
if not self.vswrMarkers:
self.vswr_marker_dropdown.addItem("None")
else:
for m in self.vswrMarkers:
self.vswr_marker_dropdown.addItem(str(m))
for c in self.app.s11charts:
c.addSWRMarker(m)
self.vswr_marker_dropdown.setCurrentIndex(0)
btn_add_vswr_marker = QtWidgets.QPushButton("Add ...")
btn_add_vswr_marker.setMinimumHeight(20)
btn_remove_vswr_marker = QtWidgets.QPushButton("Remove")
btn_remove_vswr_marker.setMinimumHeight(20)
vswr_marker_btn_layout = QtWidgets.QHBoxLayout()
vswr_marker_btn_layout.addWidget(btn_add_vswr_marker)
vswr_marker_btn_layout.addWidget(btn_remove_vswr_marker)
vswr_marker_layout.addRow(vswr_marker_btn_layout)
btn_add_vswr_marker.clicked.connect(self.addVSWRMarker)
btn_remove_vswr_marker.clicked.connect(self.removeVSWRMarker)
markers_box = QtWidgets.QGroupBox("Markers")
markers_layout = QtWidgets.QFormLayout(markers_box)
btn_add_marker = QtWidgets.QPushButton("Add")
btn_add_marker.setMinimumHeight(30)
btn_add_marker.clicked.connect(self.addMarker)
self.btn_remove_marker = QtWidgets.QPushButton("Remove")
self.btn_remove_marker.setMinimumHeight(30)
self.btn_remove_marker.clicked.connect(self.removeMarker)
btn_marker_settings = QtWidgets.QPushButton("Settings ...")
btn_marker_settings.setMinimumHeight(30)
btn_marker_settings.clicked.connect(self.displayMarkerWindow)
marker_btn_layout = QtWidgets.QHBoxLayout()
marker_btn_layout.addWidget(btn_add_marker)
marker_btn_layout.addWidget(self.btn_remove_marker)
marker_btn_layout.addWidget(btn_marker_settings)
markers_layout.addRow(marker_btn_layout)
charts_box = QtWidgets.QGroupBox("Displayed charts")
charts_layout = QtWidgets.QGridLayout(charts_box)
selections = [c.name for c in self.app.selectable_charts]
selections.append("None")
self._chart_selection(charts_layout, selections)
chart_colors = ChartColors()
Chart.color.background = self.app.settings.value(
"BackgroundColor",
defaultValue=chart_colors.background,
type=QColor,
)
Chart.color.foreground = self.app.settings.value(
"ForegroundColor",
defaultValue=chart_colors.foreground,
type=QColor,
)
Chart.color.text = self.app.settings.value(
"TextColor", defaultValue=chart_colors.text, type=QColor
)
self.bandsColor = self.app.settings.value(
"BandsColor", defaultValue=chart_colors.bands, type=QColor
)
self.app.bands.color = Chart.color.bands
Chart.color.swr = self.app.settings.value(
"VSWRColor", defaultValue=chart_colors.swr, type=QColor
)
self.dark_mode_option.setChecked(Defaults.cfg.gui.dark_mode)
self.show_lines_option.setChecked(Defaults.cfg.chart.show_lines)
self.show_marker_number_option.setChecked(
Defaults.cfg.chart.marker_label
)
self.filled_marker_option.setChecked(Defaults.cfg.chart.marker_filled)
if self.app.settings.value(
"UseCustomColors", defaultValue=False, type=bool
):
self.dark_mode_option.setDisabled(True)
self.dark_mode_option.setChecked(False)
self.use_custom_colors.setChecked(True)
left_layout.addWidget(display_options_box)
left_layout.addWidget(charts_box)
left_layout.addWidget(markers_box)
left_layout.addStretch(1)
right_layout.addWidget(color_options_box)
right_layout.addWidget(font_options_box)
right_layout.addWidget(bands_box)
right_layout.addWidget(vswr_marker_box)
right_layout.addStretch(1)
self.update()
def _chart_selection(self, charts_layout, selections):
chart00_selection = QtWidgets.QComboBox()
chart00_selection.setMinimumHeight(30)
chart00_selection.addItems(selections)
chart00 = self.app.settings.value("Chart00", "S11 Smith Chart")
if chart00_selection.findText(chart00) > -1:
chart00_selection.setCurrentText(chart00)
else:
chart00_selection.setCurrentText("S11 Smith Chart")
chart00_selection.currentTextChanged.connect(
lambda: self.changeChart(0, 0, chart00_selection.currentText())
)
charts_layout.addWidget(chart00_selection, 0, 0)
chart01_selection = QtWidgets.QComboBox()
chart01_selection.setMinimumHeight(30)
chart01_selection.addItems(selections)
chart01 = self.app.settings.value("Chart01", "S11 Return Loss")
if chart01_selection.findText(chart01) > -1:
chart01_selection.setCurrentText(chart01)
else:
chart01_selection.setCurrentText("S11 Return Loss")
chart01_selection.currentTextChanged.connect(
lambda: self.changeChart(0, 1, chart01_selection.currentText())
)
charts_layout.addWidget(chart01_selection, 0, 1)
chart02_selection = QtWidgets.QComboBox()
chart02_selection.setMinimumHeight(30)
chart02_selection.addItems(selections)
chart02 = self.app.settings.value("Chart02", "None")
if chart02_selection.findText(chart02) > -1:
chart02_selection.setCurrentText(chart02)
else:
chart02_selection.setCurrentText("None")
chart02_selection.currentTextChanged.connect(
lambda: self.changeChart(0, 2, chart02_selection.currentText())
)
charts_layout.addWidget(chart02_selection, 0, 2)
chart10_selection = QtWidgets.QComboBox()
chart10_selection.setMinimumHeight(30)
chart10_selection.addItems(selections)
chart10 = self.app.settings.value("Chart10", "S21 Polar Plot")
if chart10_selection.findText(chart10) > -1:
chart10_selection.setCurrentText(chart10)
else:
chart10_selection.setCurrentText("S21 Polar Plot")
chart10_selection.currentTextChanged.connect(
lambda: self.changeChart(1, 0, chart10_selection.currentText())
)
charts_layout.addWidget(chart10_selection, 1, 0)
chart11_selection = QtWidgets.QComboBox()
chart11_selection.setMinimumHeight(30)
chart11_selection.addItems(selections)
chart11 = self.app.settings.value("Chart11", "S21 Gain")
if chart11_selection.findText(chart11) > -1:
chart11_selection.setCurrentText(chart11)
else:
chart11_selection.setCurrentText("S21 Gain")
chart11_selection.currentTextChanged.connect(
lambda: self.changeChart(1, 1, chart11_selection.currentText())
)
charts_layout.addWidget(chart11_selection, 1, 1)
chart12_selection = QtWidgets.QComboBox()
chart12_selection.setMinimumHeight(30)
chart12_selection.addItems(selections)
chart12 = self.app.settings.value("Chart12", "None")
if chart12_selection.findText(chart12) > -1:
chart12_selection.setCurrentText(chart12)
else:
chart12_selection.setCurrentText("None")
chart12_selection.currentTextChanged.connect(
lambda: self.changeChart(1, 2, chart12_selection.currentText())
)
charts_layout.addWidget(chart12_selection, 1, 2)
self.changeChart(0, 0, chart00_selection.currentText())
self.changeChart(0, 1, chart01_selection.currentText())
self.changeChart(0, 2, chart02_selection.currentText())
self.changeChart(1, 0, chart10_selection.currentText())
self.changeChart(1, 1, chart11_selection.currentText())
self.changeChart(1, 2, chart12_selection.currentText())
def trace_colors(self, layout: QtWidgets.QLayout):
for setting, name, attr in (
("SweepColor", "Sweep color", "sweep"),
("SecondarySweepColor", "Second sweep color", "sweep_secondary"),
("ReferenceColor", "Reference color", "reference"),
(
"SecondaryReferenceColor",
"Second reference color",
"reference_secondary",
),
):
cp = self.color_picker(setting, attr)
layout.addRow(name, cp)
def custom_colors(self, layout: QtWidgets.QLayout):
for setting, name, attr in (
("BackgroundColor", "Chart background", "background"),
("ForegroundColor", "Chart foreground", "foreground"),
("TextColor", "Chart text", "text"),
):
cp = self.color_picker(setting, attr)
layout.addRow(name, cp)
def color_picker(self, setting: str, attr: str) -> QtWidgets.QPushButton:
cp = QtWidgets.QPushButton("")
cp.setFixedWidth(20)
cp.setMinimumHeight(20)
default = getattr(Chart.color, attr)
color = self.app.settings.value(
setting, defaultValue=default, type=QColor
)
setattr(Chart.color, attr, color)
self.callback_params[cp] = (setting, attr)
cp.clicked.connect(self.setColor)
p = cp.palette()
p.setColor(QPalette.ColorRole.ButtonText, getattr(Chart.color, attr))
cp.setPalette(p)
return cp
def changeChart(self, x, y, chart):
found = None
for c in self.app.selectable_charts:
if c.name == chart:
found = c
self.app.settings.setValue(f"Chart{x}{y}", chart)
old_widget = self.app.charts_layout.itemAtPosition(x, y)
if old_widget is not None:
w = old_widget.widget()
self.app.charts_layout.removeWidget(w)
w.hide()
if found is not None:
if self.app.charts_layout.indexOf(found) > -1:
logger.debug("%s is already shown, duplicating.", found.name)
found = self.app.copyChart(found)
self.app.charts_layout.addWidget(found, x, y)
if found.isHidden():
found.show()
def changeReturnLoss(self):
state = self.returnloss_is_positive.isChecked()
Defaults.cfg.chart.returnloss_is_positive = bool(state)
for m in self.app.markers:
m.returnloss_is_positive = state
m.updateLabels(self.app.data.s11, self.app.data.s21)
self.marker_window.exampleMarker.returnloss_is_positive = state
self.marker_window.updateMarker()
self.app.charts["s11"]["log_mag"].isInverted = state
self.app.charts["s11"]["log_mag"].update()
def changeShowLines(self):
state = self.show_lines_option.isChecked()
Defaults.cfg.chart.show_lines = bool(state)
for c in self.app.subscribing_charts:
c.setDrawLines(state)
def changeShowMarkerNumber(self):
Defaults.cfg.chart.marker_label = bool(
self.show_marker_number_option.isChecked()
)
self.updateCharts()
def changeFilledMarkers(self):
Defaults.cfg.chart.marker_filled = bool(
self.filled_marker_option.isChecked()
)
self.updateCharts()
def changeMarkerAtTip(self):
Defaults.cfg.chart.marker_at_tip = bool(self.marker_at_tip.isChecked())
self.updateCharts()
def changePointSize(self, size: int):
Defaults.cfg.chart.point_size = size
for c in self.app.subscribing_charts:
c.setPointSize(size)
def changeLineThickness(self, size: int):
Defaults.cfg.chart.line_thickness = size
for c in self.app.subscribing_charts:
c.setLineThickness(size)
def changeMarkerSize(self, size: int):
Defaults.cfg.chart.marker_size = size
self.markerSizeInput.setValue(size)
self.updateCharts()
def changeDarkMode(self):
state = self.dark_mode_option.isChecked()
Defaults.cfg.gui.dark_mode = bool(state)
Chart.color.foreground = QColor(QColorConstants.LightGray)
if state:
Chart.color.background = QColor(QColorConstants.Black)
Chart.color.text = QColor(QColorConstants.White)
else:
Chart.color.background = QColor(QColorConstants.White)
Chart.color.text = QColor(QColorConstants.Black)
Chart.color.swr = Chart.color.swr
self.updateCharts()
def changeSetting(self, setting: str, value: str):
logger.debug("Setting %s: %s", setting, value)
self.app.settings.setValue(setting, value)
self.app.settings.sync()
self.updateCharts()
def setColor(self):
sender = self.sender()
logger.debug("Sender %s", sender)
setting, attr = self.callback_params[sender]
logger.debug("Setting: %s Attribute: %s", setting, attr)
color = getattr(Chart.color, attr)
color = QtWidgets.QColorDialog.getColor(
color, options=QtWidgets.QColorDialog.ShowAlphaChannel
)
if not color.isValid():
logger.info("Invalid color")
return
palette = sender.palette()
palette.setColor(QPalette.ButtonText, color)
sender.setPalette(palette)
self.changeSetting(setting, color)
def setShowBands(self, show_bands):
self.app.bands.enabled = show_bands
self.app.bands.settings.setValue("ShowBands", show_bands)
self.app.bands.settings.sync()
for c in self.app.subscribing_charts:
c.update()
def changeFont(self):
font_size = int(self.font_dropdown.currentText())
Defaults.cfg.gui.font_size = font_size
app: QtWidgets.QApplication = QtWidgets.QApplication.instance()
font = app.font()
font.setPointSize(font_size)
app.setFont(font)
self.app.changeFont(font)
def displayBandsWindow(self):
self.bandsWindow.show()
QtWidgets.QApplication.setActiveWindow(self.bandsWindow)
def displayMarkerWindow(self):
self.marker_window.show()
QtWidgets.QApplication.setActiveWindow(self.marker_window)
def addMarker(self):
new_marker = Marker("", self.app.settings)
new_marker.setScale(self.app.scaleFactor)
self.app.markers.append(new_marker)
self.app.marker_data_layout.addWidget(new_marker.get_data_layout())
self.app.marker_frame.adjustSize()
new_marker.updated.connect(self.app.markerUpdated)
label, layout = new_marker.getRow()
self.app.marker_control.layout.insertRow(
Marker.count() - 1, label, layout
)
self.btn_remove_marker.setDisabled(False)
if Marker.count() >= 2:
self.app.marker_control.check_delta.setDisabled(False)
def removeMarker(self):
# keep at least one marker
if Marker.count() <= 1:
return
if Marker.count() == 2:
self.btn_remove_marker.setDisabled(True)
self.app.delta_marker_layout.setVisible(False)
self.app.marker_control.check_delta.setDisabled(True)
last_marker = self.app.markers.pop()
last_marker.updated.disconnect(self.app.markerUpdated)
self.app.marker_data_layout.removeWidget(last_marker.get_data_layout())
self.app.marker_control.layout.removeRow(Marker.count() - 1)
self.app.marker_frame.adjustSize()
last_marker.get_data_layout().hide()
last_marker.get_data_layout().destroy()
label, _ = last_marker.getRow()
label.hide()
def addVSWRMarker(self):
value, selected = QtWidgets.QInputDialog.getDouble(
self,
"Add VSWR Marker",
"VSWR value to show:",
min=1.001,
decimals=3,
)
if selected:
self.vswrMarkers.append(value)
if self.vswr_marker_dropdown.itemText(0) == "None":
self.vswr_marker_dropdown.removeItem(0)
self.vswr_marker_dropdown.addItem(str(value))
self.vswr_marker_dropdown.setCurrentText(str(value))
for c in self.app.s11charts:
c.addSWRMarker(value)
self.app.settings.setValue("VSWRMarkers", self.vswrMarkers)
def removeVSWRMarker(self):
value_str = self.vswr_marker_dropdown.currentText()
if value_str != "None":
value = float(value_str)
self.vswrMarkers.remove(value)
self.vswr_marker_dropdown.removeItem(
self.vswr_marker_dropdown.currentIndex()
)
if self.vswr_marker_dropdown.count() == 0:
self.vswr_marker_dropdown.addItem("None")
self.app.settings.remove("VSWRMarkers")
else:
self.app.settings.setValue("VSWRMarkers", self.vswrMarkers)
for c in self.app.s11charts:
c.removeSWRMarker(value)
def updateCharts(self):
for c in self.app.subscribing_charts:
c.update()
Defaults.store(self.app.settings, Defaults.cfg)