Skip to content

Commit

Permalink
Merge pull request #18 from nqrduck/measurement-edit
Browse files Browse the repository at this point in the history
Measurement edit
  • Loading branch information
jupfi authored May 20, 2024
2 parents 044b223 + 88af151 commit 6124ee8
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 21 deletions.
24 changes: 17 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# Changelog

### Version 0.0.4 (05-05-2024)
- Added display of multiple measurements that can be displayed in th plot window.
## Version 0.0.5 (20-05-2024)

- Fixed measurement dialog not showing in wayland (`f5705e4efcbaf1aa0efd558b1ec1dacf42a53944`)
- Measurement names are now editable (`be2e895c5768c3a82c329da62f9afef4bd953895`).
- Improved darkmode compatibility (`be2e895c5768c3a82c329da62f9afef4bd953895`).

## Version 0.0.4 (05-05-2024)

- Added display of multiple measurements that can be displayed in th plot window.
- Now using the FileManager class instead of QFileManager

### Version 0.0.3 (26-04-2024)
- Switched to new formbuilder. This should make implementation of signal processing methods more robust and easier.
## Version 0.0.3 (26-04-2024)

- Switched to new formbuilder. This should make implementation of signal processing methods more robust and easier.

## Version 0.0.2 (17-04-2024)

### Version 0.0.2 (17-04-2024)
- Deployment to PyPi via github actions

### Version 0.0.1 (15-04-2024)
- Initial release
## Version 0.0.1 (15-04-2024)

- Initial release
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ allow-direct-references = true

[project]
name = "nqrduck-measurement"
version = "0.0.4"
version = "0.0.5"
authors = [
{ name="jupfi", email="[email protected]" },
]
Expand Down
25 changes: 24 additions & 1 deletion src/nqrduck_measurement/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def start_measurement(self) -> None:
"""Emit the start measurement signal."""
logger.debug("Start measurement clicked")
self.module.view.measurement_dialog.show()
QApplication.processEvents()

# Set the measurement parameters again in case the user switches spectrometer
self.module.nqrduck_signal.emit(
Expand Down Expand Up @@ -233,8 +234,13 @@ def show_apodization_dialog(self) -> None:

@pyqtSlot()
def change_displayed_measurement(self, measurement=None) -> None:
"""Change the displayed measurement."""
"""Change the displayed measurement.
If no measurement is provided, the displayed measurement is changed to the selected measurement in the selection box.
Args:
measurement (Measurement, optional): The measurement to display. Defaults to None.
"""
if not self.module.model.measurements:
logger.debug("No measurements to display.")
return
Expand Down Expand Up @@ -270,3 +276,20 @@ def delete_measurement(self, measurement: Measurement) -> None:
)
else:
self.module.model.displayed_measurement = None

def edit_measurement(
self, old_measurement: Measurement, new_measurement: Measurement
) -> None:
"""Edit a measurement.
Args:
old_measurement (Measurement): The measurement to edit.
new_measurement (Measurement): The new measurement.
"""
logger.debug("Editing measurement.")
# Delete the old measurement
self.delete_measurement(old_measurement)

# Add the new measurement
self.module.model.add_measurement(new_measurement)
self.module.model.displayed_measurement = new_measurement
122 changes: 110 additions & 12 deletions src/nqrduck_measurement/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
QListWidgetItem,
QSizePolicy,
QApplication,
QLineEdit,
)
from PyQt6.QtGui import QFontMetrics
from PyQt6.QtCore import pyqtSlot, Qt
Expand Down Expand Up @@ -54,7 +55,7 @@ def __init__(self, module):
)

# Measurement dialog
self.measurement_dialog = self.MeasurementDialog()
self.measurement_dialog = self.MeasurementDialog(self)

# Connect signals
self.module.model.displayed_measurement_changed.connect(
Expand Down Expand Up @@ -135,6 +136,11 @@ def init_plotter(self) -> None:
plotter.canvas.ax.set_title("Measurement data - Time domain")
plotter.canvas.ax.grid()

@pyqtSlot()
def on_settings_changed(self) -> None:
"""Redraw the plots in case the according settings have changed."""
self.update_displayed_measurement()

def change_to_time_view(self) -> None:
"""Change plotter to time domain view."""
plotter = self._ui_form.plotter
Expand Down Expand Up @@ -164,7 +170,7 @@ def update_displayed_measurement(self) -> None:
try:
if self.module.model.displayed_measurement is None:
logger.debug("No measurement data to display. Clearing plotter.")

if self.module.model.view_mode == self.module.model.FFT_VIEW:
self.change_to_fft_view()
else:
Expand All @@ -173,7 +179,7 @@ def update_displayed_measurement(self) -> None:
self._ui_form.plotter.canvas.draw()

return

if self.module.model.view_mode == self.module.model.FFT_VIEW:
self.change_to_fft_view()
y = self.module.model.displayed_measurement.fdy
Expand Down Expand Up @@ -298,9 +304,16 @@ def on_measurements_changed(self) -> None:
lambda: self.module.controller.delete_measurement(measurement)
)

edit_button = QPushButton()
edit_button.setIcon(Logos.Pen12x12())
edit_button.setFixedWidth(edit_button.iconSize().width())
edit_button.clicked.connect(lambda: self.show_measurement_edit(measurement))

name_button = QPushButton()
name_button.clicked.connect(
partial(self.module.controller.change_displayed_measurement, measurement)
partial(
self.module.controller.change_displayed_measurement, measurement
)
)

# Not sure if this is pretty
Expand All @@ -309,6 +322,7 @@ def on_measurements_changed(self) -> None:
QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred
) # Set size policy

layout.addWidget(edit_button)
layout.addWidget(name_button)
layout.addWidget(delete_button)
layout.addStretch() # Add stretch after delete button to ensure name button takes up space
Expand Down Expand Up @@ -341,6 +355,21 @@ def on_measurements_changed(self) -> None:
name_button.setText(elidedText)
name_button.setToolTip(measurement.name)

def show_measurement_edit(self, measurement) -> None:
"""Show the measurement dialog.
Args:
measurement (Measurement): The measurement to edit.
"""
dialog = self.MeasurementEdit(measurement, parent=self)
result = dialog.exec()

if result == QDialog.DialogCode.Accepted:
logger.debug("Measurement edited.")
self.module.controller.edit_measurement(measurement, dialog.measurement)
else:
logger.debug("Measurement edit canceled.")

class MeasurementDialog(QDialog):
"""This Dialog is shown when the measurement is started and therefore blocks the main window.
Expand All @@ -350,34 +379,103 @@ class MeasurementDialog(QDialog):
finished (bool): True if the spinner movie is finished.
"""

def __init__(self):
def __init__(self, parent=None):
"""Initialize the dialog."""
super().__init__()
self.finished = True
super().__init__(parent)
self.setParent(parent)
self.finished = False
self.setModal(True)
self.setWindowFlag(Qt.WindowType.FramelessWindowHint)
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
self.setWindowFlag(Qt.WindowType.WindowStaysOnTopHint) # Ensure the window stays on top

self.message_label = QLabel("Measuring...")
# Make label bold and text larger
font = self.message_label.font()
font.setPointSize(20)
font.setBold(True)
self.message_label.setFont(font)

self.message_label = "Measuring..."
self.spinner_movie = DuckAnimations.DuckKick128x128()
self.spinner_label = QLabel(self)
# Make spinner label
self.spinner_label.setMovie(self.spinner_movie)

self.layout = QVBoxLayout(self)
self.layout.addWidget(QLabel(self.message_label))
self.layout.addWidget(self.message_label)
self.layout.addWidget(self.spinner_label)

self.spinner_movie.finished.connect(self.on_movie_finished)

self.spinner_movie.start()
def show(self) -> None:
"""Show the dialog and ensure it is raised and activated."""
super().show()
self.raise_() # Bring the dialog to the front
self.activateWindow() # Give the dialog focus
self.spinner_movie.start() # Ensure the movie starts playing

def on_movie_finished(self) -> None:
"""Called when the spinner movie is finished."""
self.finished = True

def hide(self) -> None:
"""Hide the dialog and stop the spinner movie."""
while not self.finished:
continue
self.spinner_movie.stop()
super().hide()

class MeasurementEdit(QDialog):
"""This dialog is displayed when the measurement edit button is clicked.
It allows the user to edit the measurement parameters (e.g. name, ...)
"""

def __init__(self, measurement, parent=None) -> None:
"""Initialize the dialog."""
super().__init__(parent)
self.setParent(parent)

self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)

logger.debug("Edit measurement dialog started.")

self.measurement = measurement

self.setWindowTitle("Edit Measurement")
self.layout = QVBoxLayout(self)
self.setLayout(self.layout)

self.name_layout = QHBoxLayout()
self.name_label = QLabel("Name:")
self.name_edit = QLineEdit(measurement.name)
font_metrics = self.name_edit.fontMetrics()
self.name_edit.setFixedWidth(
font_metrics.horizontalAdvance(self.name_edit.text()) + 10
)
self.name_edit.adjustSize()

self.name_layout.addWidget(self.name_label)
self.name_layout.addWidget(self.name_edit)

self.ok_button = QPushButton("OK")
self.ok_button.clicked.connect(self.on_ok_button_clicked)

self.cancel_button = QPushButton("Cancel")
self.cancel_button.clicked.connect(self.close)

self.layout.addLayout(self.name_layout)

button_layout = QHBoxLayout()
button_layout.addWidget(self.cancel_button)
button_layout.addWidget(self.ok_button)

self.layout.addLayout(button_layout)

# Resize the dialog
self.adjustSize()

def on_ok_button_clicked(self) -> None:
"""Slot for when the OK button is clicked."""
logger.debug("OK button clicked.")
self.measurement.name = self.name_edit.text()
self.accept()
self.close()

0 comments on commit 6124ee8

Please sign in to comment.