New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple plotting GUI #24338
Multiple plotting GUI #24338
Changes from all commits
703e9d1
ee2da0a
bdfb788
ca4d639
8d152fb
9060d5f
d433ee7
30bd6f4
0199375
614149f
40b8080
e48d3da
3813c14
a9f1755
9142174
57b63e3
240bff7
8c387de
f9d93f2
1c32fcb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Mantid Repository : https://github.com/mantidproject/mantid | ||
# | ||
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, | ||
# NScD Oak Ridge National Laboratory, European Spallation Source | ||
# & Institut Laue - Langevin | ||
# SPDX - License - Identifier: GPL - 3.0 + |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Mantid Repository : https://github.com/mantidproject/mantid | ||
# | ||
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, | ||
# NScD Oak Ridge National Laboratory, European Spallation Source | ||
# & Institut Laue - Langevin | ||
# SPDX - License - Identifier: GPL - 3.0 + | ||
|
||
|
||
class AxisChangerPresenter(object): | ||
|
||
def __init__(self, view): | ||
self.view = view | ||
|
||
def set_enabled(self, state): | ||
self.view.set_enabled(state) | ||
|
||
def hide(self): | ||
self.view.hide() | ||
|
||
def show(self): | ||
self.view.show() | ||
|
||
def get_bounds(self): | ||
return self.view.get_bounds() | ||
|
||
def set_bounds(self, bounds): | ||
self.view.set_bounds(bounds) | ||
|
||
def clear_bounds(self): | ||
self.view.clear_bounds() | ||
|
||
def on_bound_changed(self, slot): | ||
self.view.on_bound_changed(slot) | ||
|
||
def unreg_on_bound_changed(self, slot): | ||
try: | ||
self.view.unreg_bound_changed(slot) | ||
except TypeError: | ||
return |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Mantid Repository : https://github.com/mantidproject/mantid | ||
# | ||
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, | ||
# NScD Oak Ridge National Laboratory, European Spallation Source | ||
# & Institut Laue - Langevin | ||
# SPDX - License - Identifier: GPL - 3.0 + | ||
from qtpy import QtGui, QtCore, QtWidgets | ||
|
||
|
||
class AxisChangerView(QtWidgets.QWidget): | ||
sig_bound_changed = QtCore.Signal(object) | ||
|
||
def __init__(self, label): | ||
super(AxisChangerView, self).__init__() | ||
layout = QtWidgets.QHBoxLayout() | ||
self._label = QtWidgets.QLabel(label) | ||
layout.addWidget(self._label) | ||
|
||
self.lower_bound = QtWidgets.QLineEdit() | ||
self.lower_bound.setValidator(QtGui.QDoubleValidator()) | ||
self.lower_bound.returnPressed.connect(self._bound_changed) | ||
|
||
self.upper_bound = QtWidgets.QLineEdit() | ||
self.upper_bound.setValidator(QtGui.QDoubleValidator()) | ||
self.upper_bound.returnPressed.connect(self._bound_changed) | ||
|
||
layout.addWidget(self.lower_bound) | ||
self._to = QtWidgets.QLabel("to") | ||
layout.addWidget(self._to) | ||
layout.addWidget(self.upper_bound) | ||
self.setLayout(layout) | ||
|
||
def set_enabled(self, state): | ||
self.lower_bound.setDisabled(state) | ||
self.upper_bound.setDisabled(state) | ||
|
||
def show(self): | ||
self.lower_bound.show() | ||
self.upper_bound.show() | ||
self._label.show() | ||
self._to.show() | ||
|
||
def hide(self): | ||
self.lower_bound.hide() | ||
self.upper_bound.hide() | ||
self._label.hide() | ||
self._to.hide() | ||
|
||
def get_bounds(self): | ||
bounds = [self.lower_bound, self.upper_bound] | ||
return [float(str(bound.text())) if bound.text() | ||
else 0 for bound in bounds] | ||
|
||
def set_bounds(self, bounds): | ||
lower, upper = [str(bound) for bound in bounds] | ||
self.lower_bound.setText(lower) | ||
self.upper_bound.setText(upper) | ||
|
||
def clear_bounds(self): | ||
self.lower_bound.clear() | ||
self.upper_bound.clear() | ||
|
||
def _bound_changed(self): | ||
self.sig_bound_changed.emit(self.get_bounds()) | ||
|
||
def on_bound_changed(self, slot): | ||
self.sig_bound_changed.connect(slot) | ||
|
||
def unreg_bound_changed(self, slot): | ||
self.sig_bound_changed.disconnect(slot) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Mantid Repository : https://github.com/mantidproject/mantid | ||
# | ||
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, | ||
# NScD Oak Ridge National Laboratory, European Spallation Source | ||
# & Institut Laue - Langevin | ||
# SPDX - License - Identifier: GPL - 3.0 + |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Mantid Repository : https://github.com/mantidproject/mantid | ||
# | ||
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, | ||
# NScD Oak Ridge National Laboratory, European Spallation Source | ||
# & Institut Laue - Langevin | ||
# SPDX - License - Identifier: GPL - 3.0 + | ||
from __future__ import absolute_import, print_function | ||
|
||
|
||
class QuickEditPresenter(object): | ||
|
||
def __init__(self, view ): | ||
self._view = view | ||
|
||
@property | ||
def widget(self): | ||
return self._view | ||
|
||
def connect_autoscale_changed(self, slot): | ||
self._view.connect_autoscale_changed(slot) | ||
|
||
def connect_errors_changed(self, slot): | ||
self._view.connect_errors_changed(slot) | ||
|
||
def connect_x_range_changed(self, slot): | ||
self._view.connect_x_range_changed(slot) | ||
|
||
def connect_y_range_changed(self, slot): | ||
self._view.connect_y_range_changed(slot) | ||
|
||
def connect_plot_selection(self, slot): | ||
self._view.connect_plot_selection(slot) | ||
|
||
def add_subplot(self, name): | ||
current = self._view.current_selection() | ||
self._view.add_subplot(name) | ||
index = self._view.find_index(current) | ||
self._view.set_index(index) | ||
|
||
def all(self): | ||
return [self._view.plot_at_index(index) for index in range(1, self._view.number_of_plots())] | ||
|
||
def set_plot_x_range(self, range): | ||
self._view.set_plot_x_range(range) | ||
|
||
def set_plot_y_range(self, range): | ||
self._view.set_plot_y_range(range) | ||
|
||
def set_errors(self, state): | ||
previous = self._view.get_errors() | ||
if previous == state: | ||
return | ||
self._view.set_errors(state) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# Mantid Repository : https://github.com/mantidproject/mantid | ||
# | ||
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, | ||
# NScD Oak Ridge National Laboratory, European Spallation Source | ||
# & Institut Laue - Langevin | ||
# SPDX - License - Identifier: GPL - 3.0 + | ||
from __future__ import absolute_import, print_function | ||
from qtpy import QtWidgets, QtCore | ||
import qtpy | ||
from MultiPlotting.AxisChanger.axis_changer_presenter import AxisChangerPresenter | ||
from MultiPlotting.AxisChanger.axis_changer_view import AxisChangerView | ||
|
||
|
||
class QuickEditView(QtWidgets.QWidget): | ||
error_signal = QtCore.Signal(object) | ||
|
||
def __init__(self, subcontext, parent=None): | ||
super(QuickEditView, self).__init__(parent) | ||
|
||
button_layout = QtWidgets.QHBoxLayout() | ||
self.plot_selector = QtWidgets.QComboBox() | ||
self.plot_selector.setEditable(True) | ||
self.plot_selector.completer().setCompletionMode( | ||
QtWidgets.QCompleter.PopupCompletion) | ||
if qtpy.PYQT5: | ||
self.plot_selector.completer().setFilterMode( | ||
QtCore.Qt.MatchContains) | ||
|
||
self.plot_selector.addItem("All") | ||
self.x_axis_changer = AxisChangerPresenter(AxisChangerView("X")) | ||
|
||
self.autoscale = QtWidgets.QPushButton("Autoscale y") | ||
self.autoscale.setStyleSheet("background-color:lightgrey") | ||
|
||
self.y_axis_changer = AxisChangerPresenter(AxisChangerView("Y")) | ||
|
||
self.errors = QtWidgets.QCheckBox("Errors") | ||
self.errors.stateChanged.connect(self._emit_errors) | ||
|
||
button_layout.addWidget(self.plot_selector) | ||
button_layout.addWidget(self.x_axis_changer.view) | ||
button_layout.addWidget(self.autoscale) | ||
button_layout.addWidget(self.y_axis_changer.view) | ||
button_layout.addWidget(self.errors) | ||
self.setLayout(button_layout) | ||
|
||
""" plot selection """ | ||
|
||
def current_selection(self): | ||
return self.plot_selector.currentText() | ||
|
||
def find_index(self, name): | ||
return self.plot_selector.findText(name) | ||
|
||
def set_index(self, index): | ||
self.plot_selector.setCurrentIndex(index) | ||
|
||
def plot_at_index(self, index): | ||
return self.plot_selector.itemText(index) | ||
|
||
def number_of_plots(self): | ||
return self.plot_selector.count() | ||
|
||
def add_subplot(self, name): | ||
self.plot_selector.addItem(name) | ||
|
||
def connect_plot_selection(self, slot): | ||
self.plot_selector.currentIndexChanged.connect(slot) | ||
|
||
""" x axis selection """ | ||
|
||
def connect_x_range_changed(self, slot): | ||
self.x_axis_changer.on_bound_changed(slot) | ||
|
||
def set_plot_x_range(self, range): | ||
self.x_axis_changer.set_bounds(range) | ||
|
||
""" y axis selection """ | ||
|
||
def connect_y_range_changed(self, slot): | ||
self.y_axis_changer.on_bound_changed(slot) | ||
|
||
def set_plot_y_range(self, range): | ||
self.y_axis_changer.set_bounds(range) | ||
|
||
def get_y_bounds(self): | ||
return self.y_axis_changer.get_bounds() | ||
|
||
""" auto scale selection """ | ||
|
||
def connect_autoscale_changed(self, slot): | ||
self.autoscale.clicked.connect(slot) | ||
|
||
""" errors selection """ | ||
|
||
# need our own signal that sends a bool | ||
|
||
def _emit_errors(self): | ||
state = self.get_errors() | ||
self.error_signal.emit(state) | ||
|
||
def connect_errors_changed(self, slot): | ||
self.error_signal.connect(slot) | ||
|
||
def set_errors(self, state): | ||
self.errors.setChecked(state) | ||
|
||
def get_errors(self): | ||
return self.errors.isChecked() | ||
|
||
""" load/save from/to context """ | ||
|
||
def loadFromContext(self, context): | ||
self.x_axis_changer.set_bounds(context["x bounds"]) | ||
self.y_axis_changer.set_bounds(context["y bounds"]) | ||
|
||
def getSubContext(self): | ||
subcontext = {} | ||
subcontext["x bounds"] = self.x_axis_changer.get_bounds() | ||
subcontext["y bounds"] = self.y_axis_changer.get_bounds() | ||
return subcontext |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Mantid Repository : https://github.com/mantidproject/mantid | ||
# | ||
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, | ||
# NScD Oak Ridge National Laboratory, European Spallation Source | ||
# & Institut Laue - Langevin | ||
# SPDX - License - Identifier: GPL - 3.0 + | ||
from __future__ import absolute_import, print_function | ||
|
||
|
||
from MultiPlotting.QuickEdit.quickEdit_view import QuickEditView | ||
from MultiPlotting.QuickEdit.quickEdit_presenter import QuickEditPresenter | ||
|
||
|
||
class QuickEditWidget(object): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this class needed ? as it seems to mainly forward all of it's methods straight to methods on the presenter with the same names. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is something I have to clean up the code at import. It is a wrapper so we only have to import this if we want to use the widget. As opposed to importing the view, presenter and model. |
||
|
||
def __init__(self, parent=None): | ||
view = QuickEditView(None, parent) | ||
self._presenter = QuickEditPresenter(view) | ||
|
||
@property | ||
def widget(self): | ||
return self._presenter.widget | ||
""" connect statements""" | ||
|
||
def connect_autoscale_changed(self, slot): | ||
self._presenter.connect_autoscale_changed(slot) | ||
|
||
def connect_errors_changed(self, slot): | ||
self._presenter.connect_errors_changed(slot) | ||
|
||
def connect_x_range_changed(self, slot): | ||
self._presenter.connect_x_range_changed(slot) | ||
|
||
def connect_y_range_changed(self, slot): | ||
self._presenter.connect_y_range_changed(slot) | ||
|
||
def connect_plot_selection(self, slot): | ||
self._presenter.connect_plot_selection(slot) | ||
# add subplot | ||
|
||
def add_subplot(self, name): | ||
self._presenter.add_subplot(name) | ||
|
||
def get_selection(self): | ||
name = self._presenter.widget.current_selection() | ||
if name == "All": | ||
return self._presenter.all() | ||
return [name] | ||
|
||
def set_plot_x_range(self, range): | ||
self._presenter.set_plot_x_range(range) | ||
|
||
def set_plot_y_range(self, range): | ||
self._presenter.set_plot_y_range(range) | ||
|
||
def set_errors(self, state): | ||
self._presenter.set_errors(state) | ||
|
||
def set_mock(self,mock_presenter): | ||
self._presenter = mock_presenter |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Mantid Repository : https://github.com/mantidproject/mantid | ||
# | ||
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, | ||
# NScD Oak Ridge National Laboratory, European Spallation Source | ||
# & Institut Laue - Langevin | ||
# SPDX - License - Identifier: GPL - 3.0 + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this class strictly needed it seems to just simply forward everything to the view?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be useful if we ever decide to restrain acceptable inputs. We could then do the logic in here. However, yes it is unneeded for this case.