-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathbasic_plot_window.py
133 lines (113 loc) · 5.26 KB
/
basic_plot_window.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""
This file is part of VisualPIC.
The module contains the class for the basic Qt window for the matplotlib
visualizer.
Copyright 2016-2020, Angel Ferran Pousa.
License: GNU GPL-3.0.
"""
from pkg_resources import resource_filename
import platform
import ctypes
import numpy as np
from PyQt5.Qt import Qt, QStyleFactory
from PyQt5 import QtWidgets, QtGui
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from visualpic.helper_functions import (
get_closest_timestep, get_next_timestep, get_previous_timestep)
# code for proper scaling in high-DPI screens. Move this somewhere else once \
# final UI is implemented.
if platform.system() == 'Windows':
myappid = 'visualpic' # arbitrary string
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
ctypes.windll.user32.SetProcessDPIAware()
# Enable scaling for high DPI displays
QtWidgets.QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
QtWidgets.QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)
QtWidgets.QApplication.setStyle(QStyleFactory.create('Fusion'))
class BasicPlotWindow(QtWidgets.QMainWindow):
"""Basic Qt window for interactive visualization matplotlib plots."""
def __init__(self, vp_figure, mpl_visualizer, parent=None):
super().__init__(parent=parent)
self.vp_figure = vp_figure
self.mpl_vis = mpl_visualizer
self.available_timesteps = self.vp_figure.get_available_timesteps()
self.timestep_change_callbacks = []
self.setup_interface()
self.register_ui_events()
self.show()
def setup_interface(self):
self.resize(600, 400)
self.setWindowTitle('VisualPIC - 2D Viewer')
icon_path = resource_filename('visualpic.ui.icons',
'vp_logo_sq_blue.png')
self.setWindowIcon(QtGui.QIcon(icon_path))
self.frame = QtWidgets.QFrame()
self.vl = QtWidgets.QVBoxLayout()
self.dialog_dict = {}
self.settings_dialog = None
self.figure_canvas = FigureCanvasQTAgg(self.vp_figure._mpl_figure)
self.vl.addWidget(self.figure_canvas)
self.hl = QtWidgets.QHBoxLayout()
self.timestep_line_edit = QtWidgets.QLineEdit()
self.timestep_line_edit.setReadOnly(True)
self.timestep_line_edit.setAlignment(Qt.AlignCenter)
self.timestep_line_edit.setText(str(self.vp_figure._current_timestep))
self.timestep_line_edit.setMaximumWidth(50)
self.hl.addWidget(self.timestep_line_edit)
self.prev_button = QtWidgets.QPushButton()
prev_icon_path = resource_filename('visualpic.ui.icons',
'left_arrow.png')
self.prev_button.setIcon(QtGui.QIcon(prev_icon_path))
if len(self.available_timesteps) == 0:
self.prev_button.setEnabled(False)
self.hl.addWidget(self.prev_button)
self.next_button = QtWidgets.QPushButton()
next_icon_path = resource_filename('visualpic.ui.icons',
'right_arrow.png')
self.next_button.setIcon(QtGui.QIcon(next_icon_path))
if len(self.available_timesteps) == 0:
self.next_button.setEnabled(False)
self.hl.addWidget(self.next_button)
self.timestep_slider = QtWidgets.QSlider(Qt.Horizontal)
if len(self.available_timesteps) > 0:
self.timestep_slider.setRange(np.min(self.available_timesteps),
np.max(self.available_timesteps))
self.timestep_slider.setValue(self.vp_figure._current_timestep)
else:
self.timestep_slider.setEnabled(False)
self.hl.addWidget(self.timestep_slider)
self.vl.addLayout(self.hl)
self.frame.setLayout(self.vl)
self.setCentralWidget(self.frame)
def register_ui_events(self):
self.timestep_slider.sliderReleased.connect(
self.timestep_slider_released)
self.timestep_slider.valueChanged.connect(
self.timestep_slider_value_changed)
self.prev_button.clicked.connect(self.prev_button_clicked)
self.next_button.clicked.connect(self.next_button_clicked)
def prev_button_clicked(self):
current_ts = self.timestep_slider.value()
prev_ts = get_previous_timestep(current_ts, self.available_timesteps)
if prev_ts != current_ts:
self.timestep_slider.setValue(prev_ts)
self.vp_figure.generate(prev_ts, False)
self.figure_canvas.draw()
# self.render_timestep(prev_ts)
def next_button_clicked(self):
current_ts = self.timestep_slider.value()
next_ts = get_next_timestep(current_ts, self.available_timesteps)
if next_ts != current_ts:
self.timestep_slider.setValue(next_ts)
self.vp_figure.generate(next_ts, False)
self.figure_canvas.draw()
# self.render_timestep(next_ts)
def timestep_slider_released(self):
value = self.timestep_slider.value()
value = get_closest_timestep(value, self.available_timesteps)
self.timestep_slider.setValue(value)
self.vp_figure.generate(value, False)
self.figure_canvas.draw()
# self.render_timestep(value)
def timestep_slider_value_changed(self, value):
self.timestep_line_edit.setText(str(value))