Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • software_public/passoft/sohstationviewer
1 result
Show changes
...@@ -63,9 +63,17 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow): ...@@ -63,9 +63,17 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow):
""" """
self.dir_names: List[Path] = [] self.dir_names: List[Path] = []
""" """
current_dir: str - the current main data directory current_dir: the current main data directory
""" """
self.current_dir = '' self.current_dir: str = ''
"""
save_plot_dir: directory to save plot
"""
self.save_plot_dir: str = ''
"""
save_plot_format: format to save plot
"""
self.save_plot_format: str = 'SVG'
""" """
rt130_das_dict: dict by rt130 for data paths, so user can choose rt130_das_dict: dict by rt130 for data paths, so user can choose
dasses to assign list of data paths to selected_rt130_paths dasses to assign list of data paths to selected_rt130_paths
...@@ -185,6 +193,10 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow): ...@@ -185,6 +193,10 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow):
self.validate_config() self.validate_config()
self.apply_config() self.apply_config()
@QtCore.Slot()
def save_plot(self):
self.plotting_widget.save_plot('SOH-Plot')
@QtCore.Slot() @QtCore.Slot()
def open_data_type(self) -> None: def open_data_type(self) -> None:
""" """
...@@ -720,6 +732,10 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow): ...@@ -720,6 +732,10 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow):
return return
self.clear_plots() self.clear_plots()
self.is_plotting_soh = True self.is_plotting_soh = True
self.plotting_widget.set_colors(self.color_mode)
self.waveform_dlg.plotting_widget.set_colors(self.color_mode)
self.tps_dlg.plotting_widget.set_colors(self.color_mode)
self.gps_dialog.set_colors(self.color_mode)
d_obj = self.data_object d_obj = self.data_object
...@@ -842,6 +858,7 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow): ...@@ -842,6 +858,7 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow):
# current directory # current directory
self.current_directory_changed.emit(path) self.current_directory_changed.emit(path)
self.current_dir = path self.current_dir = path
self.save_plot_dir = path
execute_db(f'UPDATE PersistentData SET FieldValue="{path}" WHERE ' execute_db(f'UPDATE PersistentData SET FieldValue="{path}" WHERE '
'FieldName="currentDirectory"') 'FieldName="currentDirectory"')
self.set_open_files_list_texts() self.set_open_files_list_texts()
...@@ -1060,10 +1077,6 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow): ...@@ -1060,10 +1077,6 @@ class MainWindow(QtWidgets.QMainWindow, UIMainWindow):
if not checked: if not checked:
return return
self.color_mode = color_mode self.color_mode = color_mode
self.plotting_widget.set_colors(color_mode)
self.waveform_dlg.plotting_widget.set_colors(color_mode)
self.tps_dlg.plotting_widget.set_colors(color_mode)
self.gps_dialog.set_colors(color_mode)
@QtCore.Slot() @QtCore.Slot()
def clear_file_search(self): def clear_file_search(self):
......
...@@ -78,6 +78,7 @@ class PlottingAxes: ...@@ -78,6 +78,7 @@ class PlottingAxes:
labelbottom = False labelbottom = False
else: else:
labelbottom = True labelbottom = True
self.parent.plotting_bot -= 0.007 # space for ticks
timestamp_bar.tick_params(which='major', length=7, width=2, timestamp_bar.tick_params(which='major', length=7, width=2,
direction='inout', direction='inout',
colors=self.parent.display_color['basic'], colors=self.parent.display_color['basic'],
...@@ -90,7 +91,8 @@ class PlottingAxes: ...@@ -90,7 +91,8 @@ class PlottingAxes:
fontweight='bold', fontweight='bold',
fontsize=self.parent.font_size, fontsize=self.parent.font_size,
rotation=0, rotation=0,
labelpad=constants.HOUR_TO_TMBAR_D, labelpad=constants.HOUR_TO_TMBAR_D *
self.parent.ratio_w,
ha='left', ha='left',
color=self.parent.display_color['basic']) color=self.parent.display_color['basic'])
# not show any y ticks # not show any y ticks
...@@ -112,7 +114,8 @@ class PlottingAxes: ...@@ -112,7 +114,8 @@ class PlottingAxes:
timestamp_bar.set_xticks(times, minor=True) timestamp_bar.set_xticks(times, minor=True)
timestamp_bar.set_xticks(major_times) timestamp_bar.set_xticks(major_times)
timestamp_bar.set_xticklabels(major_time_labels, timestamp_bar.set_xticklabels(major_time_labels,
fontsize=self.parent.font_size + 2) fontsize=self.parent.font_size +
2 * self.parent.ratio_w)
timestamp_bar.set_xlim(self.parent.min_x, self.parent.max_x) timestamp_bar.set_xlim(self.parent.min_x, self.parent.max_x)
def create_axes(self, plot_b, plot_h, has_min_max_lines=True): def create_axes(self, plot_b, plot_h, has_min_max_lines=True):
...@@ -221,7 +224,7 @@ class PlottingAxes: ...@@ -221,7 +224,7 @@ class PlottingAxes:
rotation='horizontal', rotation='horizontal',
transform=ax.transAxes, transform=ax.transAxes,
color=color, color=color,
size=self.parent.font_size + 2 size=self.parent.font_size + 2 * self.parent.ratio_w
) )
# set samples' total on right side # set samples' total on right side
...@@ -352,17 +355,23 @@ class PlottingAxes: ...@@ -352,17 +355,23 @@ class PlottingAxes:
) )
) )
def get_height(self, ratio, bw_plots_distance=0.0015): def get_height(self, ratio: float, bw_plots_distance: float = 0.0015,
pixel_height: float = 19) -> float:
""" """
Calculate new plot's bottom position and return plot's height. Calculate new plot's bottom position and return plot's height.
:param ratio: float - ratio of the plot height on the BASIC_HEIGHT :param ratio: ratio of the plot height on the BASIC_HEIGHT
:param bw_plots_distance: float - distance between plots :param bw_plots_distance: distance between plots
:return plot_h: float - height of the plot :param pixel_height: height of plot in pixel (
for TPS/TPS legend, height of each day row)
:return plot_h: height of the plot
""" """
plot_h = constants.BASIC_HEIGHT * ratio # ratio with figure height plot_h = constants.BASIC_HEIGHT * ratio # ratio with figure height
self.parent.plotting_bot -= plot_h + bw_plots_distance self.parent.plotting_bot -= plot_h + bw_plots_distance
self.parent.plotting_bot_pixel += 19 * ratio bw_plots_distance_pixel = 3000 * bw_plots_distance
self.parent.plotting_bot_pixel += (pixel_height * ratio +
bw_plots_distance_pixel)
return plot_h return plot_h
def add_ruler(self, color): def add_ruler(self, color):
...@@ -403,4 +412,4 @@ class PlottingAxes: ...@@ -403,4 +412,4 @@ class PlottingAxes:
horizontalalignment='left', horizontalalignment='left',
transform=self.parent.timestamp_bar_top.transAxes, transform=self.parent.timestamp_bar_top.transAxes,
color=self.parent.display_color['basic'], color=self.parent.display_color['basic'],
size=self.parent.font_size) size=self.parent.font_size + 2 * self.parent.ratio_w)
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
Class of which object is used to plot data Class of which object is used to plot data
""" """
from typing import List, Optional, Union from typing import List, Optional, Union
import matplotlib.text import matplotlib.text
from PySide2.QtCore import QTimer, Qt
from matplotlib import pyplot as pl from matplotlib import pyplot as pl
from matplotlib.transforms import Bbox
from PySide2.QtCore import QTimer, Qt
from PySide2 import QtCore, QtWidgets from PySide2 import QtCore, QtWidgets
from PySide2.QtWidgets import QWidget, QApplication, QTextBrowser from PySide2.QtWidgets import QWidget, QApplication, QTextBrowser
...@@ -18,6 +18,7 @@ from sohstationviewer.view.plotting.plotting_widget.plotting_axes import ( ...@@ -18,6 +18,7 @@ from sohstationviewer.view.plotting.plotting_widget.plotting_axes import (
PlottingAxes PlottingAxes
) )
from sohstationviewer.view.plotting.plotting_widget.plotting import Plotting from sohstationviewer.view.plotting.plotting_widget.plotting import Plotting
from sohstationviewer.view.save_plot_dialog import SavePlotDialog
from sohstationviewer.controller.plotting_data import format_time from sohstationviewer.controller.plotting_data import format_time
from sohstationviewer.controller.util import display_tracking_info from sohstationviewer.controller.util import display_tracking_info
...@@ -110,6 +111,7 @@ class PlottingWidget(QtWidgets.QScrollArea): ...@@ -110,6 +111,7 @@ class PlottingWidget(QtWidgets.QScrollArea):
font_size: float - font size on plot. With some require bigger font, font_size: float - font size on plot. With some require bigger font,
+2 to the font_size +2 to the font_size
""" """
self.base_font_size = 7
self.font_size = 7 self.font_size = 7
""" """
bottom: float - y position of the bottom edge of all plots in self.axes bottom: float - y position of the bottom edge of all plots in self.axes
...@@ -243,6 +245,7 @@ class PlottingWidget(QtWidgets.QScrollArea): ...@@ -243,6 +245,7 @@ class PlottingWidget(QtWidgets.QScrollArea):
# set view size fit with the scroll's view port size # set view size fit with the scroll's view port size
self.main_widget.setFixedWidth(geo.width()) self.main_widget.setFixedWidth(geo.width())
self.ratio_w = geo.width() / self.width_base_px self.ratio_w = geo.width() / self.width_base_px
self.font_size = self.ratio_w * self.base_font_size
self.plotting_w = self.ratio_w * self.width_base self.plotting_w = self.ratio_w * self.width_base
self.plotting_l = self.ratio_w * self.plotting_l_base self.plotting_l = self.ratio_w * self.plotting_l_base
if self.plot_total == 0: if self.plot_total == 0:
...@@ -652,6 +655,57 @@ class PlottingWidget(QtWidgets.QScrollArea): ...@@ -652,6 +655,57 @@ class PlottingWidget(QtWidgets.QScrollArea):
""" """
self.peer_plotting_widgets = widgets self.peer_plotting_widgets = widgets
def save_plot(self, default_name='plot'):
if self.c_mode != self.main_window.color_mode:
main_color = constants.ALL_COLOR_MODES[self.main_window.color_mode]
curr_color = constants.ALL_COLOR_MODES[self.c_mode]
msg = (f"Main window's color mode is {main_color}"
f" but the mode haven't been applied to plotting.\n\n"
f"Do you want to cancel to apply {main_color} mode "
f"by clicking RePlot?\n"
f"Or continue with {curr_color}?")
msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Color Mode Conflict")
msgbox.setText(msg)
msgbox.addButton(QtWidgets.QMessageBox.Cancel)
msgbox.addButton('Continue', QtWidgets.QMessageBox.YesRole)
result = msgbox.exec_()
if result == QtWidgets.QMessageBox.Cancel:
return
self.main_window.color_mode = self.c_mode
if self.c_mode == 'B':
self.main_window.background_black_radio_button.setChecked(True)
else:
self.main_window.background_white_radio_button.setChecked(True)
if self.c_mode == 'B':
msg = ("The current background mode is black.\n"
"Do you want to cancel to change the background mode "
"before saving the plots to file?")
msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Background Mode Confirmation")
msgbox.setText(msg)
msgbox.addButton(QtWidgets.QMessageBox.Cancel)
msgbox.addButton('Continue', QtWidgets.QMessageBox.YesRole)
result = msgbox.exec_()
if result == QtWidgets.QMessageBox.Cancel:
return
save_plot_dlg = SavePlotDialog(
self.parent, self.main_window, default_name)
save_plot_dlg.exec_()
save_file_path = save_plot_dlg.save_file_path
if save_file_path is None:
return
dpi = save_plot_dlg.dpi
self.plotting_axes.fig.savefig(
save_file_path,
bbox_inches=Bbox([[0, self.plotting_bot*100],
[self.ratio_w*15.5, 100]]),
dpi=dpi
)
msg = f"Graph is saved at {save_file_path}"
display_tracking_info(self.tracking_box, msg)
def clear(self): def clear(self):
self.plotting_axes.fig.clear() self.plotting_axes.fig.clear()
self.axes = [] self.axes = []
......
...@@ -89,8 +89,10 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget): ...@@ -89,8 +89,10 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
self.is_working = True self.is_working = True
self.set_key = key self.set_key = key
self.plotting_data1 = d_obj.waveform_data[key] self.plotting_data1 = d_obj.waveform_data[key]
self.plot_total = len(self.plotting_data1)
self.plotting_bot = const.BOTTOM self.plotting_bot = const.BOTTOM
self.plotting_bot_pixel = const.BOTTOM_PX
self.processed_channels = [] self.processed_channels = []
self.channels = [] self.channels = []
self.tps_processors = [] self.tps_processors = []
...@@ -111,7 +113,7 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget): ...@@ -111,7 +113,7 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
title = get_title(key, self.min_x, self.max_x, self.date_mode) title = get_title(key, self.min_x, self.max_x, self.date_mode)
self.timestamp_bar_top = self.plotting_axes.add_timestamp_bar(0.) self.timestamp_bar_top = self.plotting_axes.add_timestamp_bar(0.)
self.plotting_axes.set_title(title, y=0, v_align='bottom') self.plotting_axes.set_title(title, y=5, v_align='bottom')
if self.plotting_data1 == {}: if self.plotting_data1 == {}:
self.is_working = False self.is_working = False
...@@ -220,11 +222,12 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget): ...@@ -220,11 +222,12 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
total_days = c_data['tps_data'].shape[0] total_days = c_data['tps_data'].shape[0]
plot_h = self.plotting_axes.get_height( plot_h = self.plotting_axes.get_height(
1.5 * total_days, bw_plots_distance=0.003) total_days/1.5, bw_plots_distance=0.003, pixel_height=12.1)
ax = self.create_axes(self.plotting_bot, plot_h) ax = self.create_axes(self.plotting_bot, plot_h)
ax.spines[['right', 'left', 'top', 'bottom']].set_visible(False)
ax.text( ax.text(
-0.1, 1.2, -0.12, 1,
f"{get_chan_label(chan_id)} {c_data['samplerate']}", f"{get_chan_label(chan_id)} {c_data['samplerate']}sps",
horizontalalignment='left', horizontalalignment='left',
verticalalignment='top', verticalalignment='top',
rotation='horizontal', rotation='horizontal',
...@@ -234,17 +237,17 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget): ...@@ -234,17 +237,17 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
) )
zoom_marker1 = ax.plot( zoom_marker1 = ax.plot(
[], [], marker='|', markersize=10, [], [], marker='|', markersize=5,
markeredgecolor=self.display_color['zoom_marker'])[0] markeredgecolor=self.display_color['zoom_marker'])[0]
self.zoom_marker1s.append(zoom_marker1) self.zoom_marker1s.append(zoom_marker1)
zoom_marker2 = ax.plot( zoom_marker2 = ax.plot(
[], [], marker='|', markersize=10, [], [], marker='|', markersize=5,
markeredgecolor=self.display_color['zoom_marker'])[0] markeredgecolor=self.display_color['zoom_marker'])[0]
self.zoom_marker2s.append(zoom_marker2) self.zoom_marker2s.append(zoom_marker2)
ruler = ax.plot( ruler = ax.plot(
[], [], marker='s', markersize=5, [], [], marker='s', markersize=4,
markeredgecolor=self.display_color['time_ruler'], markeredgecolor=self.display_color['time_ruler'],
markerfacecolor='None')[0] markerfacecolor='None')[0]
self.rulers.append(ruler) self.rulers.append(ruler)
...@@ -258,8 +261,8 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget): ...@@ -258,8 +261,8 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
# not draw data out of day range # not draw data out of day range
color_set = self.get_color_set(y, square_counts, color_codes) color_set = self.get_color_set(y, square_counts, color_codes)
# (- dayIdx): each day is a line, increase from top to bottom # (- dayIdx): each day is a line, increase from top to bottom
ax.scatter(x, [- dayIdx] * len(x), marker='|', ax.scatter(x, [- dayIdx] * len(x), marker='s',
c=color_set, s=7, alpha=0.8) c=color_set, s=3)
# extra to show highlight square # extra to show highlight square
ax.set_ylim(-(c_data['tps_data'].shape[0] + 1), 1) ax.set_ylim(-(c_data['tps_data'].shape[0] + 1), 1)
...@@ -274,11 +277,13 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget): ...@@ -274,11 +277,13 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
ax.legend will create one label for each dot. ax.legend will create one label for each dot.
""" """
# set height of legend and distance bw legend and upper ax # set height of legend and distance bw legend and upper ax
plot_h = self.plotting_axes.get_height(7, bw_plots_distance=0.003) plot_h = self.plotting_axes.get_height(
21, bw_plots_distance=0.004, pixel_height=12)
ax = self.plotting_axes.canvas.figure.add_axes( ax = self.plotting_axes.canvas.figure.add_axes(
[self.plotting_l, self.plotting_bot, self.plotting_w, plot_h], [self.plotting_l, self.plotting_bot, self.plotting_w, plot_h],
picker=True picker=True
) )
ax.axis('off')
ax.patch.set_alpha(0) ax.patch.set_alpha(0)
c_labels = self.parent.sel_col_labels c_labels = self.parent.sel_col_labels
clrs = self.parent.color_def # colordef clrs = self.parent.color_def # colordef
...@@ -466,6 +471,7 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget): ...@@ -466,6 +471,7 @@ class TimePowerSquaredWidget(plotting_widget.PlottingWidget):
with new color range selected. with new color range selected.
""" """
self.clear() self.clear()
self.set_colors(self.main_window.color_mode)
self.plotting_bot = const.BOTTOM self.plotting_bot = const.BOTTOM
title = get_title(self.set_key, self.min_x, self.max_x, self.date_mode) title = get_title(self.set_key, self.min_x, self.max_x, self.date_mode)
self.timestamp_bar_top = self.plotting_axes.add_timestamp_bar(0.) self.timestamp_bar_top = self.plotting_axes.add_timestamp_bar(0.)
...@@ -554,6 +560,7 @@ class TimePowerSquaredDialog(QtWidgets.QWidget): ...@@ -554,6 +560,7 @@ class TimePowerSquaredDialog(QtWidgets.QWidget):
""" """
self.color_range_choice = QtWidgets.QComboBox(self) self.color_range_choice = QtWidgets.QComboBox(self)
self.color_range_choice.addItems(self.color_ranges) self.color_range_choice.addItems(self.color_ranges)
self.color_range_choice.setCurrentText('High') self.color_range_choice.setCurrentText('High')
color_layout.addWidget(self.color_range_choice) color_layout.addWidget(self.color_range_choice)
# ##################### Replot button ######################## # ##################### Replot button ########################
...@@ -561,8 +568,8 @@ class TimePowerSquaredDialog(QtWidgets.QWidget): ...@@ -561,8 +568,8 @@ class TimePowerSquaredDialog(QtWidgets.QWidget):
buttons_layout.addWidget(self.replot_button) buttons_layout.addWidget(self.replot_button)
# ##################### Save button ########################## # ##################### Save button ##########################
self.save_button = QtWidgets.QPushButton('Save', self) self.save_plot_button = QtWidgets.QPushButton('Save Plot', self)
buttons_layout.addWidget(self.save_button) buttons_layout.addWidget(self.save_plot_button)
self.info_text_browser.setFixedHeight(60) self.info_text_browser.setFixedHeight(60)
bottom_layout.addWidget(self.info_text_browser) bottom_layout.addWidget(self.info_text_browser)
...@@ -595,7 +602,7 @@ class TimePowerSquaredDialog(QtWidgets.QWidget): ...@@ -595,7 +602,7 @@ class TimePowerSquaredDialog(QtWidgets.QWidget):
""" """
Connect functions to widgets Connect functions to widgets
""" """
self.save_button.clicked.connect(self.save) self.save_plot_button.clicked.connect(self.save_plot)
self.replot_button.clicked.connect(self.plotting_widget.replot) self.replot_button.clicked.connect(self.plotting_widget.replot)
self.color_range_choice.currentTextChanged.connect( self.color_range_choice.currentTextChanged.connect(
self.color_range_changed) self.color_range_changed)
...@@ -612,8 +619,8 @@ class TimePowerSquaredDialog(QtWidgets.QWidget): ...@@ -612,8 +619,8 @@ class TimePowerSquaredDialog(QtWidgets.QWidget):
self.sel_col_labels = self.color_label[cr_index] self.sel_col_labels = self.color_label[cr_index]
@QtCore.Slot() @QtCore.Slot()
def save(self): def save_plot(self):
""" """
Save the plotting to a file Save the plotting to a file
""" """
print("save") self.plotting_widget.save_plot('TPS-Plot')
...@@ -118,11 +118,11 @@ class WaveformDialog(QtWidgets.QWidget): ...@@ -118,11 +118,11 @@ class WaveformDialog(QtWidgets.QWidget):
bottom_layout = QtWidgets.QHBoxLayout() bottom_layout = QtWidgets.QHBoxLayout()
main_layout.addLayout(bottom_layout) main_layout.addLayout(bottom_layout)
""" """
save_button: save plot in plotting_widget to file save_plot_button: save plot in plotting_widget to file
""" """
self.save_button = QtWidgets.QPushButton('Save', self) self.save_plot_button = QtWidgets.QPushButton('Save Plot', self)
self.save_button.clicked.connect(self.save) self.save_plot_button.clicked.connect(self.save_plot)
bottom_layout.addWidget(self.save_button) bottom_layout.addWidget(self.save_plot_button)
self.info_text_browser.setFixedHeight(60) self.info_text_browser.setFixedHeight(60)
bottom_layout.addWidget(self.info_text_browser) bottom_layout.addWidget(self.info_text_browser)
...@@ -148,11 +148,11 @@ class WaveformDialog(QtWidgets.QWidget): ...@@ -148,11 +148,11 @@ class WaveformDialog(QtWidgets.QWidget):
self.plotting_widget.init_size() self.plotting_widget.init_size()
@QtCore.Slot() @QtCore.Slot()
def save(self): def save_plot(self):
""" """
Save the plotting to a file Save the plotting to a file
""" """
print("save") self.plotting_widget.save_plot('Waveform-Plot')
def plot_finished(self): def plot_finished(self):
self.parent.is_plotting_waveform = False self.parent.is_plotting_waveform = False
import sys
import platform
import os
from pathlib import Path
from typing import Union, Optional
from PySide2 import QtWidgets, QtCore, QtGui
from PySide2.QtWidgets import QApplication, QWidget, QDialog
from sohstationviewer.conf import constants
class SavePlotDialog(QDialog):
def __init__(self, parent: Union[QWidget, QApplication],
main_window: QApplication,
default_name: str):
"""
Dialog allow choosing file format and open file dialog to
save file as
:param parent: the parent widget
:param main_window: to keep path to save file
:param default_name: default name for graph file to be saved as
"""
super(SavePlotDialog, self).__init__(parent)
self.main_window = main_window
"""
save_file_path: path to save file
"""
self.save_file_path: Optional[Path] = None
"""
save_dir_path: path to save dir
"""
self.save_dir_path: Path = main_window.save_plot_dir
"""
dpi: resolution for png format
"""
self.dpi: int = 100
self.save_dir_btn = QtWidgets.QPushButton("Save Directory", self)
self.save_dir_textbox = QtWidgets.QLineEdit(self.save_dir_path)
self.save_filename_textbox = QtWidgets.QLineEdit(default_name)
self.dpi_line_edit = QtWidgets.QSpinBox(self)
self.format_radio_btns = {}
for fmt in constants.IMG_FORMAT:
self.format_radio_btns[fmt] = QtWidgets.QRadioButton(fmt, self)
if fmt == self.main_window.save_plot_format:
self.format_radio_btns[fmt].setChecked(True)
self.cancel_btn = QtWidgets.QPushButton('CANCEL', self)
self.continue_btn = QtWidgets.QPushButton('SAVE PLOT', self)
self.setup_ui()
self.connect_signals()
def setup_ui(self) -> None:
self.setWindowTitle("Save Plot")
main_layout = QtWidgets.QGridLayout()
self.setLayout(main_layout)
main_layout.addWidget(self.save_dir_btn, 0, 0, 1, 1)
self.save_dir_textbox.setFixedWidth(500)
main_layout.addWidget(self.save_dir_textbox, 0, 1, 1, 5)
main_layout.addWidget(QtWidgets.QLabel('Save Filename'),
1, 0, 1, 1)
main_layout.addWidget(self.save_filename_textbox, 1, 1, 1, 5)
main_layout.addWidget(QtWidgets.QLabel('DPI'),
2, 2, 1, 1, QtGui.Qt.AlignRight)
self.dpi_line_edit.setRange(50, 300)
self.dpi_line_edit.setValue(100)
main_layout.addWidget(self.dpi_line_edit, 2, 3, 1, 1)
rowidx = 2
for fmt in self.format_radio_btns:
main_layout.addWidget(self.format_radio_btns[fmt], rowidx, 1, 1, 1)
rowidx += 1
main_layout.addWidget(self.cancel_btn, rowidx, 1, 1, 1)
main_layout.addWidget(self.continue_btn, rowidx, 3, 1, 1)
def connect_signals(self) -> None:
self.save_dir_btn.clicked.connect(self.change_save_directory)
self.cancel_btn.clicked.connect(self.close)
self.continue_btn.clicked.connect(self.on_continue)
@QtCore.Slot()
def change_save_directory(self) -> None:
"""
Show a file selection window and change the GPS data save directory
based on the folder selected by the user.
"""
fd = QtWidgets.QFileDialog(self)
fd.setFileMode(QtWidgets.QFileDialog.Directory)
fd.setDirectory(self.save_dir_textbox.text())
fd.exec_()
new_path = fd.selectedFiles()[0]
self.save_dir_textbox.setText(new_path)
self.save_dir_path = new_path
self.main_window.save_plot_dir = new_path
@QtCore.Slot()
def on_continue(self):
if self.save_dir_textbox.text().strip() == '':
QtWidgets.QMessageBox.warning(
self, "Add Directory",
"A directory need to be given before continue.")
return
if self.save_filename_textbox.text().strip() == '':
QtWidgets.QMessageBox.warning(
self, "Add Filename",
"A file name need to be given before continue.")
return
for img_format in self.format_radio_btns:
if self.format_radio_btns[img_format].isChecked():
save_format = img_format
self.main_window.save_plot_format = img_format
break
self.save_file_path = Path(self.save_dir_path).joinpath(
f"{self.save_filename_textbox.text()}.{save_format}")
self.dpi = self.dpi_line_edit.value()
self.close()
if __name__ == '__main__':
os_name, version, *_ = platform.platform().split('-')
if os_name == 'macOS':
os.environ['QT_MAC_WANTS_LAYER'] = '1'
app = QtWidgets.QApplication(sys.argv)
save_path = '/Users/ldam/Documents/GIT/sohstationviewer/tests/test_data/Q330-sample' # noqa: E501
test = SavePlotDialog(None, 'test_plot')
test.set_save_directory(save_path)
test.exec_()
print("dpi:", test.dpi)
print("save file path:", test.save_file_path)
sys.exit(app.exec_())
...@@ -793,6 +793,8 @@ class UIMainWindow(object): ...@@ -793,6 +793,8 @@ class UIMainWindow(object):
self.stop_button.clicked.connect(main_window.stop) self.stop_button.clicked.connect(main_window.stop)
self.save_plot_button.clicked.connect(main_window.save_plot)
def read_config(self): def read_config(self):
self.config = configparser.ConfigParser() self.config = configparser.ConfigParser()
config_path = Path('sohstationviewer/conf/read_settings.ini') config_path = Path('sohstationviewer/conf/read_settings.ini')
......
...@@ -96,6 +96,9 @@ def create_table_of_content_file(base_path: Path) -> None: ...@@ -96,6 +96,9 @@ def create_table_of_content_file(base_path: Path) -> None:
"this software.\n\n" "this software.\n\n"
"On the left-hand side you will find a list of currently available" "On the left-hand side you will find a list of currently available"
" help topics.\n\n" " help topics.\n\n"
"If the links of the Table of Contents are broken, click on Recreate "
"Table of Content <img src='recreate_table_contents.png' height=30 /> "
"to rebuild it.\n\n"
"The home button can be used to return to this page at any time.\n\n" "The home button can be used to return to this page at any time.\n\n"
"# Table of Contents\n\n") "# Table of Contents\n\n")
links = "" links = ""
......