myokit 1.34.0__py3-none-any.whl → 1.35.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- myokit/__init__.py +5 -23
- myokit/__main__.py +70 -117
- myokit/_aux.py +5 -8
- myokit/_config.py +22 -31
- myokit/_datablock.py +26 -70
- myokit/_datalog.py +23 -53
- myokit/_err.py +13 -15
- myokit/_expressions.py +35 -55
- myokit/_io.py +5 -22
- myokit/_model_api.py +34 -47
- myokit/_myokit_version.py +1 -5
- myokit/_parsing.py +17 -25
- myokit/_progress.py +4 -7
- myokit/_protocol.py +6 -9
- myokit/_sim/__init__.py +7 -24
- myokit/_sim/cable.c +1 -3
- myokit/_sim/cable.py +3 -5
- myokit/_sim/cmodel.h +1 -3
- myokit/_sim/cmodel.py +1 -4
- myokit/_sim/compiler.py +1 -4
- myokit/_sim/cvodessim.c +1 -4
- myokit/_sim/cvodessim.py +1 -4
- myokit/_sim/fiber_tissue.c +2 -6
- myokit/_sim/fiber_tissue.py +3 -5
- myokit/_sim/jacobian.py +6 -7
- myokit/_sim/mcl.h +51 -53
- myokit/_sim/opencl.py +9 -22
- myokit/_sim/openclsim.c +2 -6
- myokit/_sim/openclsim.py +6 -6
- myokit/_sim/pacing.h +2 -6
- myokit/_sim/rhs.c +3 -10
- myokit/_sim/rhs.py +4 -13
- myokit/_sim/sundials.py +1 -4
- myokit/_system.py +10 -16
- myokit/_unit.py +3 -12
- myokit/float.py +0 -3
- myokit/formats/__init__.py +8 -10
- myokit/formats/ansic/__init__.py +0 -3
- myokit/formats/ansic/_ewriter.py +2 -4
- myokit/formats/ansic/_exporter.py +0 -3
- myokit/formats/axon/__init__.py +1 -3
- myokit/formats/axon/_abf.py +12 -15
- myokit/formats/axon/_atf.py +5 -6
- myokit/formats/axon/_importer.py +0 -3
- myokit/formats/cellml/__init__.py +0 -3
- myokit/formats/cellml/_ewriter.py +3 -6
- myokit/formats/cellml/_exporter.py +3 -6
- myokit/formats/cellml/_importer.py +1 -4
- myokit/formats/cellml/v1/__init__.py +0 -4
- myokit/formats/cellml/v1/_api.py +7 -10
- myokit/formats/cellml/v1/_parser.py +2 -5
- myokit/formats/cellml/v1/_writer.py +2 -11
- myokit/formats/cellml/v2/__init__.py +0 -3
- myokit/formats/cellml/v2/_api.py +7 -16
- myokit/formats/cellml/v2/_parser.py +2 -5
- myokit/formats/cellml/v2/_writer.py +1 -4
- myokit/formats/channelml/__init__.py +0 -3
- myokit/formats/channelml/_importer.py +4 -14
- myokit/formats/cpp/__init__.py +1 -3
- myokit/formats/cpp/_ewriter.py +0 -3
- myokit/formats/cuda/__init__.py +0 -3
- myokit/formats/cuda/_ewriter.py +2 -4
- myokit/formats/cuda/_exporter.py +0 -3
- myokit/formats/easyml/__init__.py +0 -3
- myokit/formats/easyml/_ewriter.py +9 -11
- myokit/formats/easyml/_exporter.py +0 -3
- myokit/formats/html/__init__.py +0 -3
- myokit/formats/html/_exporter.py +0 -3
- myokit/formats/html/_flatten.py +5 -21
- myokit/formats/latex/__init__.py +0 -3
- myokit/formats/latex/_ewriter.py +1 -4
- myokit/formats/latex/_exporter.py +3 -5
- myokit/formats/mathml/__init__.py +0 -3
- myokit/formats/mathml/_ewriter.py +2 -11
- myokit/formats/mathml/_parser.py +3 -5
- myokit/formats/matlab/__init__.py +0 -3
- myokit/formats/matlab/_ewriter.py +1 -4
- myokit/formats/matlab/_exporter.py +0 -3
- myokit/formats/opencl/__init__.py +0 -3
- myokit/formats/opencl/_ewriter.py +2 -4
- myokit/formats/opencl/_exporter.py +0 -3
- myokit/formats/python/__init__.py +0 -3
- myokit/formats/python/_ewriter.py +2 -5
- myokit/formats/python/_exporter.py +0 -3
- myokit/formats/python/template/sim.py +10 -10
- myokit/formats/sbml/__init__.py +0 -3
- myokit/formats/sbml/_api.py +17 -11
- myokit/formats/sbml/_importer.py +1 -4
- myokit/formats/sbml/_parser.py +2 -5
- myokit/formats/stan/__init__.py +0 -3
- myokit/formats/stan/_ewriter.py +2 -4
- myokit/formats/stan/_exporter.py +1 -4
- myokit/formats/sympy/__init__.py +0 -3
- myokit/formats/sympy/_ereader.py +1 -4
- myokit/formats/sympy/_ewriter.py +2 -5
- myokit/formats/wcp/__init__.py +0 -3
- myokit/formats/wcp/_wcp.py +1 -7
- myokit/formats/xml/__init__.py +0 -3
- myokit/formats/xml/_exporter.py +0 -3
- myokit/formats/xml/_split.py +0 -3
- myokit/gui/__init__.py +75 -247
- myokit/gui/datablock_viewer.py +100 -83
- myokit/gui/datalog_viewer.py +32 -44
- myokit/gui/explorer.py +15 -21
- myokit/gui/ide.py +105 -125
- myokit/gui/progress.py +9 -9
- myokit/gui/source.py +405 -374
- myokit/gui/vargrapher.py +2 -12
- myokit/lib/deps.py +7 -8
- myokit/lib/guess.py +1 -2
- myokit/lib/hh.py +5 -7
- myokit/lib/markov.py +9 -11
- myokit/lib/multi.py +1 -3
- myokit/lib/plots.py +1 -3
- myokit/pacing.py +0 -3
- myokit/pype.py +7 -18
- myokit/tests/__init__.py +3 -6
- myokit/tests/ansic_event_based_pacing.py +1 -4
- myokit/tests/ansic_fixed_form_pacing.py +1 -4
- myokit/tests/test_aux.py +9 -23
- myokit/tests/test_cellml_v1_api.py +1 -16
- myokit/tests/test_cellml_v1_parser.py +0 -15
- myokit/tests/test_cellml_v1_writer.py +0 -9
- myokit/tests/test_cellml_v2_api.py +1 -16
- myokit/tests/test_cellml_v2_parser.py +0 -15
- myokit/tests/test_cellml_v2_writer.py +0 -9
- myokit/tests/test_cmodel.py +0 -9
- myokit/tests/test_compiler_detection.py +1 -11
- myokit/tests/test_component.py +0 -10
- myokit/tests/test_config.py +33 -66
- myokit/tests/test_datablock.py +1 -9
- myokit/tests/test_datalog.py +4 -21
- myokit/tests/test_dependency_checking.py +8 -23
- myokit/tests/test_expressions.py +0 -9
- myokit/tests/test_float.py +1 -5
- myokit/tests/test_formats.py +0 -9
- myokit/tests/test_formats_axon.py +1 -9
- myokit/tests/test_formats_cellml.py +0 -15
- myokit/tests/test_formats_channelml.py +0 -15
- myokit/tests/test_formats_easyml.py +0 -14
- myokit/tests/test_formats_exporters.py +1 -16
- myokit/tests/test_formats_expression_writers.py +1 -17
- myokit/tests/test_formats_html.py +0 -3
- myokit/tests/test_formats_importers.py +1 -16
- myokit/tests/test_formats_mathml_content.py +0 -9
- myokit/tests/test_formats_mathml_presentation.py +0 -9
- myokit/tests/test_formats_opencl.py +0 -10
- myokit/tests/test_formats_sbml.py +0 -15
- myokit/tests/test_formats_sympy.py +0 -9
- myokit/tests/test_formats_wcp.py +1 -3
- myokit/tests/test_io.py +6 -14
- myokit/tests/test_jacobian_calculator.py +1 -9
- myokit/tests/test_jacobian_tracer.py +0 -9
- myokit/tests/test_lib_deps.py +0 -9
- myokit/tests/test_lib_guess.py +0 -9
- myokit/tests/test_lib_hh.py +1 -9
- myokit/tests/test_lib_markov.py +1 -9
- myokit/tests/test_lib_multi.py +0 -9
- myokit/tests/test_lib_plots.py +0 -3
- myokit/tests/test_meta.py +0 -3
- myokit/tests/test_model.py +0 -10
- myokit/tests/test_model_building.py +2 -17
- myokit/tests/test_opencl_info.py +5 -14
- myokit/tests/test_pacing_factory.py +0 -3
- myokit/tests/test_pacing_system_c.py +0 -9
- myokit/tests/test_pacing_system_py.py +0 -9
- myokit/tests/test_parsing.py +5 -20
- myokit/tests/test_progress_reporters.py +0 -3
- myokit/tests/test_protocol.py +0 -9
- myokit/tests/test_protocol_floating_point.py +0 -9
- myokit/tests/test_protocol_time_series.py +0 -10
- myokit/tests/test_pype.py +0 -9
- myokit/tests/test_quantity.py +0 -9
- myokit/tests/test_rhs_benchmarker.py +1 -9
- myokit/tests/test_sbml_api.py +0 -15
- myokit/tests/test_sbml_parser.py +0 -15
- myokit/tests/test_simulation_1d.py +1 -10
- myokit/tests/test_simulation_cvodes.py +8 -16
- myokit/tests/test_simulation_cvodes_from_disk.py +0 -3
- myokit/tests/test_simulation_fiber_tissue.py +1 -10
- myokit/tests/test_simulation_log_interval.py +0 -9
- myokit/tests/test_simulation_opencl.py +1 -10
- myokit/tests/test_simulation_opencl_log_interval.py +1 -3
- myokit/tests/test_simulation_opencl_vs_cvode.py +1 -10
- myokit/tests/test_simulation_opencl_vs_sim1d.py +1 -10
- myokit/tests/test_system_info.py +1 -11
- myokit/tests/test_tools.py +0 -9
- myokit/tests/test_unit.py +0 -9
- myokit/tests/test_user_functions.py +0 -10
- myokit/tests/test_variable.py +0 -10
- myokit/tools.py +5 -21
- myokit/units.py +0 -3
- {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/METADATA +7 -7
- {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/RECORD +198 -200
- myokit/_exec_new.py +0 -15
- myokit/_exec_old.py +0 -15
- {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/LICENSE.txt +0 -0
- {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/WHEEL +0 -0
- {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/entry_points.txt +0 -0
- {myokit-1.34.0.dist-info → myokit-1.35.0.dist-info}/top_level.txt +0 -0
myokit/gui/datablock_viewer.py
CHANGED
|
@@ -4,24 +4,18 @@
|
|
|
4
4
|
# This file is part of Myokit.
|
|
5
5
|
# See http://myokit.org for copyright, sharing, and licensing details.
|
|
6
6
|
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
import collections
|
|
8
|
+
import configparser
|
|
10
9
|
import os
|
|
11
10
|
import sys
|
|
12
|
-
import numpy as np
|
|
13
11
|
import traceback
|
|
14
|
-
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
15
14
|
|
|
16
15
|
import myokit
|
|
17
16
|
import myokit.gui
|
|
18
|
-
from myokit.gui import QtWidgets, QtGui, QtCore, Qt
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
try:
|
|
22
|
-
import ConfigParser as configparser
|
|
23
|
-
except ImportError:
|
|
24
|
-
import configparser
|
|
18
|
+
from myokit.gui import QtWidgets, QtGui, QtCore, Qt
|
|
25
19
|
|
|
26
20
|
|
|
27
21
|
# Application title
|
|
@@ -92,22 +86,26 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
92
86
|
"""
|
|
93
87
|
|
|
94
88
|
def __init__(self, filename=None):
|
|
95
|
-
super(
|
|
89
|
+
super().__init__()
|
|
96
90
|
# Set application icon
|
|
97
91
|
self.setWindowIcon(icon())
|
|
92
|
+
|
|
98
93
|
# Set size, center
|
|
99
94
|
self.resize(800, 600)
|
|
100
95
|
self.setMinimumSize(600, 400)
|
|
101
96
|
qr = self.frameGeometry()
|
|
102
|
-
cp =
|
|
97
|
+
cp = QtGui.QGuiApplication.primaryScreen().availableGeometry().center()
|
|
103
98
|
qr.moveCenter(cp)
|
|
104
99
|
self.move(qr.topLeft())
|
|
100
|
+
|
|
105
101
|
# Status bar
|
|
106
102
|
self._label_cursor = QtWidgets.QLabel()
|
|
107
103
|
self.statusBar().addPermanentWidget(self._label_cursor)
|
|
108
104
|
self.statusBar().showMessage('Ready')
|
|
105
|
+
|
|
109
106
|
# Menu bar
|
|
110
107
|
self.create_menu()
|
|
108
|
+
|
|
111
109
|
# Timer
|
|
112
110
|
self._timer_interval = 50
|
|
113
111
|
self._timer = QtCore.QTimer(self)
|
|
@@ -115,10 +113,8 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
115
113
|
self._timer.setSingleShot(False)
|
|
116
114
|
self._timer.timeout.connect(self.action_next_frame)
|
|
117
115
|
self._timer_paused = False
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
except AttributeError:
|
|
121
|
-
pass # Qt4 uses precise timer by default
|
|
116
|
+
self._timer.setTimerType(Qt.TimerType.PreciseTimer)
|
|
117
|
+
|
|
122
118
|
# Video widget
|
|
123
119
|
self._video_scene = VideoScene()
|
|
124
120
|
self._video_scene.mouse_moved.connect(self.event_video_mouse_move)
|
|
@@ -126,12 +122,13 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
126
122
|
self._video_scene.double_click.connect(self.event_video_double_click)
|
|
127
123
|
self._video_view = VideoView(self._video_scene)
|
|
128
124
|
self._video_view.setMouseTracking(True)
|
|
129
|
-
self._video_view.setCursor(Qt.CrossCursor)
|
|
125
|
+
self._video_view.setCursor(Qt.CursorShape.CrossCursor)
|
|
130
126
|
#self._video_view.setViewport(QtOpenGL.QGLWidget())
|
|
131
127
|
self._video_pixmap = None
|
|
132
128
|
self._video_item = None
|
|
133
129
|
self._video_frames = None
|
|
134
130
|
self._video_iframe = None
|
|
131
|
+
|
|
135
132
|
# Colorbar widget
|
|
136
133
|
self._colorbar_width = 20
|
|
137
134
|
self._colorbar_height = 256
|
|
@@ -140,52 +137,65 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
140
137
|
self._colorbar_view.setMaximumWidth(self._colorbar_width)
|
|
141
138
|
self._colorbar_pixmap = None
|
|
142
139
|
self._colorbar_item = None
|
|
140
|
+
|
|
143
141
|
# Video slider
|
|
144
|
-
self._slider = QtWidgets.QSlider(Qt.Horizontal)
|
|
145
|
-
self._slider.setTickPosition(QtWidgets.QSlider.NoTicks)
|
|
146
|
-
#self._slider.setTickPosition(QtWidgets.QSlider.TicksBothSides)
|
|
142
|
+
self._slider = QtWidgets.QSlider(Qt.Orientation.Horizontal)
|
|
143
|
+
self._slider.setTickPosition(QtWidgets.QSlider.TickPosition.NoTicks)
|
|
147
144
|
self._slider.setSingleStep(1)
|
|
148
145
|
self._slider.setMinimum(0)
|
|
149
146
|
self._slider.setMaximum(0)
|
|
150
147
|
self._slider.sliderPressed.connect(self.action_pause_timer)
|
|
151
148
|
self._slider.sliderReleased.connect(self.action_depause_timer)
|
|
152
149
|
self._slider.valueChanged.connect(self.action_set_frame)
|
|
150
|
+
|
|
153
151
|
# Controls
|
|
154
152
|
style = QtWidgets.QApplication.style()
|
|
153
|
+
|
|
155
154
|
# Play button
|
|
156
|
-
self._play_icon_play = style.standardIcon(
|
|
157
|
-
|
|
155
|
+
self._play_icon_play = style.standardIcon(
|
|
156
|
+
style.StandardPixmap.SP_MediaPlay)
|
|
157
|
+
self._play_icon_pause = style.standardIcon(
|
|
158
|
+
style.StandardPixmap.SP_MediaPause)
|
|
158
159
|
self._play_button = QtWidgets.QPushButton()
|
|
159
160
|
self._play_button.setIcon(self._play_icon_play)
|
|
160
161
|
self._play_button.pressed.connect(self.action_start_stop)
|
|
162
|
+
|
|
161
163
|
# Frame indicator
|
|
162
164
|
self._frame_label = QtWidgets.QLabel('Frame')
|
|
163
165
|
self._frame_field = QtWidgets.QLineEdit('0')
|
|
164
166
|
self._frame_field.setReadOnly(True)
|
|
165
167
|
self._frame_field.setMaxLength(6)
|
|
166
168
|
self._frame_field.setMaximumWidth(100)
|
|
167
|
-
self._frame_label.setAlignment(
|
|
169
|
+
self._frame_label.setAlignment(
|
|
170
|
+
Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
|
|
171
|
+
|
|
168
172
|
# Time indicator
|
|
169
173
|
self._time_label = QtWidgets.QLabel('Time')
|
|
170
174
|
self._time_field = QtWidgets.QLineEdit('0')
|
|
171
175
|
self._time_field.setReadOnly(True)
|
|
172
176
|
self._time_field.setMaxLength(6)
|
|
173
177
|
self._time_field.setMaximumWidth(100)
|
|
174
|
-
self._time_label.setAlignment(
|
|
178
|
+
self._time_label.setAlignment(
|
|
179
|
+
Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
|
|
180
|
+
|
|
175
181
|
# Speed indicator
|
|
176
182
|
self._rate_label = QtWidgets.QLabel('Delay')
|
|
177
183
|
self._rate_field = QtWidgets.QLineEdit(str(self._timer_interval))
|
|
178
184
|
self._rate_field.setValidator(QtGui.QIntValidator(1, 2**20, self))
|
|
179
185
|
self._rate_field.editingFinished.connect(self.event_rate_changed)
|
|
180
186
|
self._rate_field.setMaximumWidth(100)
|
|
181
|
-
self._rate_label.setAlignment(
|
|
187
|
+
self._rate_label.setAlignment(
|
|
188
|
+
Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignVCenter)
|
|
189
|
+
|
|
182
190
|
# Graph controls
|
|
183
191
|
self._graph_clear_button = QtWidgets.QPushButton('Clear graphs')
|
|
184
192
|
self._graph_clear_button.pressed.connect(self.action_clear_graphs)
|
|
193
|
+
|
|
185
194
|
# Variable selection
|
|
186
195
|
self._variable_select = QtWidgets.QComboBox()
|
|
187
196
|
self._variable_select.activated.connect(self.event_variable_selected)
|
|
188
197
|
self._variable_select.setMinimumWidth(120)
|
|
198
|
+
|
|
189
199
|
# Colormap selection
|
|
190
200
|
self._colormap = next(iter(myokit.ColorMap.names()))
|
|
191
201
|
self._colormap_select = QtWidgets.QComboBox()
|
|
@@ -193,6 +203,7 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
193
203
|
self._colormap_select.addItem(cmap)
|
|
194
204
|
self._colormap_select.activated.connect(self.event_colormap_selected)
|
|
195
205
|
self._colormap_select.setMinimumWidth(120)
|
|
206
|
+
|
|
196
207
|
# Control layout
|
|
197
208
|
self._control_layout = QtWidgets.QHBoxLayout()
|
|
198
209
|
self._control_layout.addWidget(self._play_button)
|
|
@@ -205,15 +216,18 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
205
216
|
self._control_layout.addWidget(self._graph_clear_button)
|
|
206
217
|
self._control_layout.addWidget(self._variable_select)
|
|
207
218
|
self._control_layout.addWidget(self._colormap_select)
|
|
219
|
+
|
|
208
220
|
# Graph area
|
|
209
221
|
self._graph_area = GraphArea()
|
|
210
222
|
self._graph_area.mouse_moved.connect(self.event_graph_mouse_move)
|
|
211
223
|
self._graph_area.setMouseTracking(True)
|
|
212
|
-
self._graph_area.setCursor(Qt.CrossCursor)
|
|
224
|
+
self._graph_area.setCursor(Qt.CursorShape.CrossCursor)
|
|
225
|
+
|
|
213
226
|
# Video and colorbar layout
|
|
214
227
|
self._video_plus_layout = QtWidgets.QHBoxLayout()
|
|
215
228
|
self._video_plus_layout.addWidget(self._video_view)
|
|
216
229
|
self._video_plus_layout.addWidget(self._colorbar_view)
|
|
230
|
+
|
|
217
231
|
# Video Layout
|
|
218
232
|
self._video_layout = QtWidgets.QVBoxLayout()
|
|
219
233
|
self._video_layout.addLayout(self._video_plus_layout)
|
|
@@ -221,34 +235,42 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
221
235
|
self._video_layout.addLayout(self._control_layout)
|
|
222
236
|
self._video_widget = QtWidgets.QWidget()
|
|
223
237
|
self._video_widget.setLayout(self._video_layout)
|
|
238
|
+
|
|
224
239
|
# Central layout
|
|
225
|
-
self._central_widget = QtWidgets.QSplitter(Qt.Vertical)
|
|
240
|
+
self._central_widget = QtWidgets.QSplitter(Qt.Orientation.Vertical)
|
|
226
241
|
self._central_widget.addWidget(self._video_widget)
|
|
227
242
|
self._central_widget.addWidget(self._graph_area)
|
|
228
243
|
self.setCentralWidget(self._central_widget)
|
|
244
|
+
|
|
229
245
|
# Current path, current file, recent files
|
|
230
246
|
self._path = QtCore.QDir.currentPath()
|
|
231
247
|
self._file = None
|
|
232
248
|
self._recent_files = []
|
|
249
|
+
|
|
233
250
|
# Current data block, display variable
|
|
234
251
|
self._data = None
|
|
235
252
|
self._variable = None
|
|
253
|
+
|
|
236
254
|
# Load settings from ini file
|
|
237
255
|
self.load_config()
|
|
238
256
|
self.update_window_title()
|
|
257
|
+
|
|
239
258
|
# Set controls to correct values
|
|
240
259
|
self._colormap_select.setCurrentIndex(self._colormap_select.findText(
|
|
241
260
|
self._colormap))
|
|
242
261
|
self._rate_field.setText(str(self._timer_interval))
|
|
243
262
|
self._timer.setInterval(self._timer_interval)
|
|
263
|
+
|
|
244
264
|
# Pause video playback during resize
|
|
245
265
|
self._resize_timer = QtCore.QTimer()
|
|
246
266
|
self._resize_timer.timeout.connect(self._resize_timeout)
|
|
247
267
|
self._video_view.resize_event.connect(self._resize_started)
|
|
248
268
|
self._colorbar_view.resize_event.connect(self._resize_started)
|
|
269
|
+
|
|
249
270
|
# Attempt to load selected file
|
|
250
271
|
if filename and os.path.isfile(filename):
|
|
251
272
|
self.load_data_file(filename)
|
|
273
|
+
|
|
252
274
|
# Focus on play button
|
|
253
275
|
self._play_button.setFocus()
|
|
254
276
|
|
|
@@ -306,7 +328,8 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
306
328
|
nx = 200
|
|
307
329
|
ny = 800
|
|
308
330
|
image = myokit.ColorMap.image(self._colormap, nx, ny)
|
|
309
|
-
image = QtGui.QImage(
|
|
331
|
+
image = QtGui.QImage(
|
|
332
|
+
image, nx, ny, QtGui.QImage.Format.Format_ARGB32)
|
|
310
333
|
painter = QtGui.QPainter(image)
|
|
311
334
|
painter.drawText(10, 15, str(upper))
|
|
312
335
|
painter.drawText(10, ny - 5, str(lower))
|
|
@@ -360,7 +383,8 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
360
383
|
return
|
|
361
384
|
nt, ny, nx = self._data.shape()
|
|
362
385
|
image = self._video_frames[self._video_iframe]
|
|
363
|
-
image = QtGui.QImage(
|
|
386
|
+
image = QtGui.QImage(
|
|
387
|
+
image, nx, ny, QtGui.QImage.Format.Format_ARGB32)
|
|
364
388
|
image.save(fname, ext)
|
|
365
389
|
|
|
366
390
|
def action_extract_graphs(self):
|
|
@@ -464,7 +488,8 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
464
488
|
nx = self._colorbar_width
|
|
465
489
|
ny = self._colorbar_height
|
|
466
490
|
image = myokit.ColorMap.image(self._colormap, nx, ny)
|
|
467
|
-
image = QtGui.QImage(
|
|
491
|
+
image = QtGui.QImage(
|
|
492
|
+
image, nx, ny, QtGui.QImage.Format.Format_ARGB32)
|
|
468
493
|
self._colorbar_pixmap.convertFromImage(image)
|
|
469
494
|
self._colorbar_item.setPixmap(self._colorbar_pixmap) # qt5
|
|
470
495
|
self.action_set_variable(self._variable)
|
|
@@ -504,7 +529,8 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
504
529
|
self._time_field.setText(str(self._data.time()[frame]))
|
|
505
530
|
# Update scene
|
|
506
531
|
image = self._video_frames[self._video_iframe]
|
|
507
|
-
image = QtGui.QImage(
|
|
532
|
+
image = QtGui.QImage(
|
|
533
|
+
image, nx, ny, QtGui.QImage.Format.Format_ARGB32)
|
|
508
534
|
self._video_pixmap.convertFromImage(image)
|
|
509
535
|
self._video_item.setPixmap(self._video_pixmap) # qt5
|
|
510
536
|
# Update graph area
|
|
@@ -540,7 +566,7 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
540
566
|
# File menu
|
|
541
567
|
self._menu_file = self._menu.addMenu('&File')
|
|
542
568
|
# File > Open
|
|
543
|
-
self._tool_open =
|
|
569
|
+
self._tool_open = QtGui.QAction('&Open', self)
|
|
544
570
|
self._tool_open.setShortcut('Ctrl+O')
|
|
545
571
|
self._tool_open.setStatusTip('Open a DataLog for inspection.')
|
|
546
572
|
self._tool_open.setIcon(QtGui.QIcon.fromTheme('document-open'))
|
|
@@ -551,14 +577,14 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
551
577
|
# File > Recent files
|
|
552
578
|
self._recent_file_tools = []
|
|
553
579
|
for i in range(N_RECENT_FILES):
|
|
554
|
-
tool =
|
|
580
|
+
tool = QtGui.QAction(self, visible=False)
|
|
555
581
|
tool.triggered.connect(self.action_recent_file)
|
|
556
582
|
self._recent_file_tools.append(tool)
|
|
557
583
|
self._menu_file.addAction(tool)
|
|
558
584
|
# File > ----
|
|
559
585
|
self._menu_file.addSeparator()
|
|
560
586
|
# File > Quit
|
|
561
|
-
self._tool_exit =
|
|
587
|
+
self._tool_exit = QtGui.QAction('&Quit', self)
|
|
562
588
|
self._tool_exit.setShortcut('Ctrl+Q')
|
|
563
589
|
self._tool_exit.setStatusTip('Exit application.')
|
|
564
590
|
self._tool_exit.setIcon(QtGui.QIcon.fromTheme('application-exit'))
|
|
@@ -567,27 +593,26 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
567
593
|
# Data menu
|
|
568
594
|
self._menu_data = self._menu.addMenu('&Data')
|
|
569
595
|
# Data > Extract frame
|
|
570
|
-
self._tool_exframe =
|
|
596
|
+
self._tool_exframe = QtGui.QAction('Extract &frame', self)
|
|
571
597
|
self._tool_exframe.setStatusTip(
|
|
572
598
|
'Extract the current frame as csv file.')
|
|
573
599
|
self._tool_exframe.triggered.connect(self.action_extract_frame)
|
|
574
600
|
self._menu_data.addAction(self._tool_exframe)
|
|
575
601
|
# Data > Extract graphs
|
|
576
|
-
self._tool_exgraph =
|
|
602
|
+
self._tool_exgraph = QtGui.QAction('Extract &graphs', self)
|
|
577
603
|
self._tool_exgraph.setStatusTip('Extract the current graphs.')
|
|
578
604
|
self._tool_exgraph.triggered.connect(self.action_extract_graphs)
|
|
579
605
|
self._menu_data.addAction(self._tool_exgraph)
|
|
580
606
|
# Data > ----
|
|
581
607
|
self._menu_data.addSeparator()
|
|
582
608
|
# Data > Extract frame as image
|
|
583
|
-
self._tool_imgframe =
|
|
609
|
+
self._tool_imgframe = QtGui.QAction('Save frame as &image', self)
|
|
584
610
|
self._tool_imgframe.setStatusTip(
|
|
585
611
|
'Save the current frame as an image file.')
|
|
586
612
|
self._tool_imgframe.triggered.connect(self.action_extract_frame_image)
|
|
587
613
|
self._menu_data.addAction(self._tool_imgframe)
|
|
588
614
|
# Data > Extract colormap as image
|
|
589
|
-
self._tool_imgcolor =
|
|
590
|
-
'Save &colormap as image', self)
|
|
615
|
+
self._tool_imgcolor = QtGui.QAction('Save &colormap as image', self)
|
|
591
616
|
self._tool_imgcolor.setStatusTip('Save the colormap as an image file.')
|
|
592
617
|
self._tool_imgcolor.triggered.connect(
|
|
593
618
|
self.action_extract_colormap_image)
|
|
@@ -595,11 +620,11 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
595
620
|
# Help menu
|
|
596
621
|
self._menu_help = self._menu.addMenu('&Help')
|
|
597
622
|
# Help > About
|
|
598
|
-
self._tool_about =
|
|
623
|
+
self._tool_about = QtGui.QAction('&About', self)
|
|
599
624
|
self._tool_about.setStatusTip('View information about this program.')
|
|
600
625
|
self._tool_about.triggered.connect(self.action_about)
|
|
601
626
|
self._menu_help.addAction(self._tool_about)
|
|
602
|
-
self._tool_license =
|
|
627
|
+
self._tool_license = QtGui.QAction('&License', self)
|
|
603
628
|
self._tool_license.setStatusTip('View this program\'s license info.')
|
|
604
629
|
self._tool_license.triggered.connect(self.action_license)
|
|
605
630
|
self._menu_help.addAction(self._tool_license)
|
|
@@ -677,7 +702,7 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
677
702
|
"""
|
|
678
703
|
Catch key presses?
|
|
679
704
|
"""
|
|
680
|
-
if e.key() == Qt.Key_Space:
|
|
705
|
+
if e.key() == Qt.Key.Key_Space:
|
|
681
706
|
self.action_start_stop()
|
|
682
707
|
|
|
683
708
|
def load_config(self):
|
|
@@ -751,7 +776,7 @@ class DataBlockViewer(myokit.gui.MyokitApplication):
|
|
|
751
776
|
self.statusBar().showMessage('Loading ' + str(fname))
|
|
752
777
|
n = 1000000
|
|
753
778
|
pd = QtWidgets.QProgressDialog('Loading data file...', 'Cancel', 0, n)
|
|
754
|
-
pd.setWindowModality(Qt.WindowModal)
|
|
779
|
+
pd.setWindowModality(Qt.WindowModality.WindowModal)
|
|
755
780
|
pd.setValue(0)
|
|
756
781
|
|
|
757
782
|
class Reporter(myokit.ProgressReporter):
|
|
@@ -951,7 +976,7 @@ class VideoScene(QtWidgets.QGraphicsScene):
|
|
|
951
976
|
double_click = QtCore.Signal(float, float)
|
|
952
977
|
|
|
953
978
|
def __init__(self, *args):
|
|
954
|
-
super(
|
|
979
|
+
super().__init__(*args)
|
|
955
980
|
self.setBackgroundBrush(QtGui.QColor(192, 192, 192))
|
|
956
981
|
self._w = None
|
|
957
982
|
self._h = None
|
|
@@ -962,8 +987,8 @@ class VideoScene(QtWidgets.QGraphicsScene):
|
|
|
962
987
|
"""
|
|
963
988
|
Single-click
|
|
964
989
|
"""
|
|
965
|
-
if event.button() ==
|
|
966
|
-
if event.modifiers() == Qt.NoModifier:
|
|
990
|
+
if event.button() == Qt.MouseButton.LeftButton:
|
|
991
|
+
if event.modifiers() == Qt.KeyBoardModifier.NoModifier:
|
|
967
992
|
p = event.scenePos()
|
|
968
993
|
x, y = int(p.x()), int(p.y())
|
|
969
994
|
if x >= 0 and x < self._w and y >= 0 and y < self._h:
|
|
@@ -974,8 +999,8 @@ class VideoScene(QtWidgets.QGraphicsScene):
|
|
|
974
999
|
"""
|
|
975
1000
|
Double-click
|
|
976
1001
|
"""
|
|
977
|
-
if event.button() ==
|
|
978
|
-
if event.modifiers() == Qt.NoModifier:
|
|
1002
|
+
if event.button() == Qt.MouseButton.LeftButton:
|
|
1003
|
+
if event.modifiers() == Qt.KeyBoardModifier.NoModifier:
|
|
979
1004
|
p = event.scenePos()
|
|
980
1005
|
x, y = int(p.x()), int(p.y())
|
|
981
1006
|
if x >= 0 and x < self._w and y >= 0 and y < self._h:
|
|
@@ -1008,19 +1033,20 @@ class VideoView(QtWidgets.QGraphicsView):
|
|
|
1008
1033
|
resize_event = QtCore.Signal()
|
|
1009
1034
|
|
|
1010
1035
|
def __init__(self, scene):
|
|
1011
|
-
super(
|
|
1036
|
+
super().__init__(scene)
|
|
1012
1037
|
# Disable scrollbars
|
|
1013
|
-
self.setHorizontalScrollBarPolicy(
|
|
1014
|
-
|
|
1038
|
+
self.setHorizontalScrollBarPolicy(
|
|
1039
|
+
Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
|
1040
|
+
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
|
|
1015
1041
|
|
|
1016
1042
|
# Set rendering hints
|
|
1017
|
-
self.setRenderHint(QtGui.QPainter.Antialiasing)
|
|
1043
|
+
self.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing)
|
|
1018
1044
|
self.setViewportUpdateMode(
|
|
1019
|
-
QtWidgets.QGraphicsView.BoundingRectViewportUpdate)
|
|
1045
|
+
QtWidgets.QGraphicsView.ViewportUpdateMode.BoundingRectViewportUpdate) # noqa
|
|
1020
1046
|
|
|
1021
1047
|
# Fit scene rect in view
|
|
1022
1048
|
self.fitInView(self.sceneRect(), keepAspect=True)
|
|
1023
|
-
self.setAlignment(Qt.AlignCenter)
|
|
1049
|
+
self.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
1024
1050
|
|
|
1025
1051
|
# Delayed resizing
|
|
1026
1052
|
self._resize_timer = QtCore.QTimer()
|
|
@@ -1038,22 +1064,13 @@ class VideoView(QtWidgets.QGraphicsView):
|
|
|
1038
1064
|
https://bugreports.qt-project.org/browse/QTBUG-11945
|
|
1039
1065
|
"""
|
|
1040
1066
|
# Reset the view scale
|
|
1041
|
-
|
|
1042
|
-
# PyQt5 / PySide
|
|
1043
|
-
unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
|
|
1044
|
-
except AttributeError:
|
|
1045
|
-
# PyQt4
|
|
1046
|
-
unity = self.matrix().mapRect(QtCore.QRectF(0, 0, 1, 1))
|
|
1067
|
+
unity = self.transform().mapRect(QtCore.QRectF(0, 0, 1, 1))
|
|
1047
1068
|
w, h = max(1, unity.width()), max(1, unity.height())
|
|
1048
1069
|
self.scale(1. / w, 1 / h)
|
|
1049
1070
|
|
|
1050
1071
|
# Find the ideal scaling ratio
|
|
1051
1072
|
viewRect = self.viewport().rect()
|
|
1052
|
-
|
|
1053
|
-
sceneRect = self.transform().mapRect(rect)
|
|
1054
|
-
except AttributeError:
|
|
1055
|
-
# PyQt4
|
|
1056
|
-
sceneRect = self.matrix().mapRect(rect)
|
|
1073
|
+
sceneRect = self.transform().mapRect(rect)
|
|
1057
1074
|
xr = viewRect.width() / sceneRect.width()
|
|
1058
1075
|
yr = viewRect.height() / sceneRect.height()
|
|
1059
1076
|
if keepAspect:
|
|
@@ -1091,7 +1108,7 @@ class GraphArea(QtWidgets.QWidget):
|
|
|
1091
1108
|
mouse_moved = QtCore.Signal(float, float)
|
|
1092
1109
|
|
|
1093
1110
|
def __init__(self):
|
|
1094
|
-
super(
|
|
1111
|
+
super().__init__()
|
|
1095
1112
|
# DataBlock 2d, and its time vector
|
|
1096
1113
|
self._data = None
|
|
1097
1114
|
self._time = None
|
|
@@ -1120,20 +1137,20 @@ class GraphArea(QtWidgets.QWidget):
|
|
|
1120
1137
|
self._position = self._tmin
|
|
1121
1138
|
|
|
1122
1139
|
# Colors for drawing
|
|
1123
|
-
self._color_temp = Qt.black
|
|
1140
|
+
self._color_temp = Qt.GlobalColor.black
|
|
1124
1141
|
self._color_cycle = [
|
|
1125
|
-
Qt.red,
|
|
1126
|
-
#Qt.green,
|
|
1127
|
-
Qt.blue,
|
|
1128
|
-
#Qt.cyan,
|
|
1129
|
-
Qt.magenta,
|
|
1130
|
-
#Qt.yellow,
|
|
1131
|
-
Qt.darkRed,
|
|
1132
|
-
Qt.darkGreen,
|
|
1133
|
-
Qt.darkBlue,
|
|
1134
|
-
Qt.darkCyan,
|
|
1135
|
-
Qt.darkMagenta,
|
|
1136
|
-
Qt.darkYellow,
|
|
1142
|
+
Qt.GlobalColor.red,
|
|
1143
|
+
#Qt.GlobalColor.green,
|
|
1144
|
+
Qt.GlobalColor.blue,
|
|
1145
|
+
#Qt.GlobalColor.cyan,
|
|
1146
|
+
Qt.GlobalColor.magenta,
|
|
1147
|
+
#Qt.GlobalColor.yellow,
|
|
1148
|
+
Qt.GlobalColor.darkRed,
|
|
1149
|
+
Qt.GlobalColor.darkGreen,
|
|
1150
|
+
Qt.GlobalColor.darkBlue,
|
|
1151
|
+
Qt.GlobalColor.darkCyan,
|
|
1152
|
+
Qt.GlobalColor.darkMagenta,
|
|
1153
|
+
Qt.GlobalColor.darkYellow,
|
|
1137
1154
|
]
|
|
1138
1155
|
|
|
1139
1156
|
# Scaling factors from pixels to normalized (0, 1) coordinates. Updated
|
|
@@ -1265,11 +1282,11 @@ class GraphArea(QtWidgets.QWidget):
|
|
|
1265
1282
|
painter.begin(self)
|
|
1266
1283
|
|
|
1267
1284
|
# Fill background
|
|
1268
|
-
painter.fillRect(self.rect(), QtGui.QBrush(Qt.white))
|
|
1285
|
+
painter.fillRect(self.rect(), QtGui.QBrush(Qt.GlobalColor.white))
|
|
1269
1286
|
|
|
1270
1287
|
# Create coordinate system for graphs
|
|
1271
1288
|
painter.scale(self.width(), self.height())
|
|
1272
|
-
painter.setRenderHint(QtGui.QPainter.Antialiasing)
|
|
1289
|
+
painter.setRenderHint(QtGui.QPainter.RenderHint.Antialiasing)
|
|
1273
1290
|
|
|
1274
1291
|
# Create pen
|
|
1275
1292
|
pen = QtGui.QPen()
|
|
@@ -1293,7 +1310,7 @@ class GraphArea(QtWidgets.QWidget):
|
|
|
1293
1310
|
painter.drawPath(self._temp_path)
|
|
1294
1311
|
|
|
1295
1312
|
# Show time indicator
|
|
1296
|
-
pen.setColor(Qt.red)
|
|
1313
|
+
pen.setColor(Qt.GlobalColor.red)
|
|
1297
1314
|
painter.setPen(pen)
|
|
1298
1315
|
t = (self._position - self._tmin) / self._trange
|
|
1299
1316
|
painter.drawLine(QtCore.QLineF(t, 0, t, 1))
|