[segyio] 80/376: New "View" class holding a standalone QWidget that can be embedded in other QT programs.
Jørgen Kvalsvik
jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:11 UTC 2017
This is an automated email from the git hooks/post-receive script.
jokva-guest pushed a commit to branch debian
in repository segyio.
commit 75525e055cb4e04af4709e279681af82037a60f2
Author: Thorvald Johannessen <thorvjo at statoil.com>
Date: Thu Oct 27 13:46:33 2016 +0200
New "View" class holding a standalone QWidget that can be embedded in other QT programs.
Plus the necessary refactoring, to enable reuse classes for the different use cases.
---
applications/segyviewer.py | 223 ++++++++------------------------------
python/segyview/CMakeLists.txt | 2 +
python/segyview/__init__.py | 3 +
python/segyview/progresswidget.py | 25 +++++
python/segyview/viewer.py | 177 ++++++++++++++++++++++++++++++
5 files changed, 254 insertions(+), 176 deletions(-)
diff --git a/applications/segyviewer.py b/applications/segyviewer.py
index 21b0807..379e985 100755
--- a/applications/segyviewer.py
+++ b/applications/segyviewer.py
@@ -6,102 +6,6 @@ from PyQt4 import QtGui, QtCore
from segyview import *
-class LineSelectionMonitor(QtCore.QObject):
- iline_changed = QtCore.pyqtSignal(int)
- xline_changed = QtCore.pyqtSignal(int)
- depth_changed = QtCore.pyqtSignal(int)
-
- def __init__(self, parent):
- QtCore.QObject.__init__(self, parent)
-
- def iline_updated(self, new_index):
- self.iline_changed.emit(new_index)
-
- def xline_updated(self, new_index):
- self.xline_changed.emit(new_index)
-
- def depth_updated(self, new_index):
- self.depth_changed.emit(new_index)
-
-
-class ColorMapMonitor(QtCore.QObject):
- cmap_changed = QtCore.pyqtSignal(str)
-
- def __init__(self, parent=None):
- QtCore.QObject.__init__(self, parent)
-
- def colormap_updated(self, value):
- self.cmap_changed.emit(str(value))
-
-
-class FileActivityMonitor(QtCore.QObject):
- started = QtCore.pyqtSignal()
- finished = QtCore.pyqtSignal()
- cancelled_operation = False
-
- def __init__(self, parent=None):
- QtCore.QObject.__init__(self)
- self.cancelled_operation = False
-
- def reset(self):
- self.cancelled_operation = False
-
- def set_file_read_started(self):
- self.started.emit()
-
- def set_file_read_finished(self):
- self.finished.emit()
-
- def set_cancel_operation(self):
- self.finished.emit()
- self.cancelled_operation = True
-
-
-class ProgressWidget(QtGui.QWidget):
-
- def __init__(self, call_on_cancel):
- super(ProgressWidget, self).__init__()
- self.call_on_cancel = call_on_cancel
-
- layout = QtGui.QHBoxLayout()
- # progress bar
- self.p_bar = QtGui.QProgressBar(self)
- cancel_file_load_btn = QtGui.QPushButton()
- cancel_file_load_btn.setText("cancel")
-
- cancel_file_load_btn.clicked.connect(self.call_on_cancel)
-
- layout.addWidget(self.p_bar, 2)
- layout.addWidget(cancel_file_load_btn)
-
- self.setLayout(layout)
-
- def set_value(self, int):
- self.p_bar.setValue(int)
-
-
-class FileLoaderWorker(QtCore.QObject):
- finished = QtCore.pyqtSignal(int)
- progress = QtCore.pyqtSignal(int)
-
- def __init__(self, segy_file_wrapper, filename, read_to_memory=False):
- QtCore.QObject.__init__(self)
- self.segy_file_wrapper = segy_file_wrapper
- self.filename = filename
- self.read_to_memory = read_to_memory
-
- def load_file(self):
- successful_file_open = self.segy_file_wrapper.open_file(self.filename,
- read_to_memory=self.read_to_memory,
- progress_callback=self.progress.emit)
- if successful_file_open:
- self.finished.emit(0)
- else:
- self.finished.emit(1)
-
- return None
-
-
class SegyViewer(QtGui.QMainWindow):
def __init__(self, filename):
QtGui.QMainWindow.__init__(self)
@@ -117,7 +21,7 @@ class SegyViewer(QtGui.QMainWindow):
self.file_activity_monitor = FileActivityMonitor(self)
# the wrapper around segyio
- self.swrap = SegyIOWrapper(self.file_activity_monitor)
+ self.swrap = None
# menus
available_colormaps = ['seismic', 'spectral', 'RdGy', 'hot', 'jet', 'gray']
@@ -136,7 +40,7 @@ class SegyViewer(QtGui.QMainWindow):
self.setup_dock_widgets()
# progress bar
- self.progress_bar = ProgressWidget(self.swrap.file_activity_monitor.set_cancel_operation)
+ self.progress_bar = ProgressWidget(self.file_activity_monitor.set_cancel_operation)
self.statusBar().addWidget(self.progress_bar, 1)
self.progress_bar.hide()
@@ -144,20 +48,15 @@ class SegyViewer(QtGui.QMainWindow):
self.resize(1200, 800)
# connect cursor overrides to file activity that might take long time
- self.swrap.file_activity_monitor.started.connect(
+ self.file_activity_monitor.started.connect(
lambda: QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.BusyCursor)))
- self.swrap.file_activity_monitor.finished.connect(
+ self.file_activity_monitor.finished.connect(
lambda: QtGui.QApplication.restoreOverrideCursor())
# initiate the first file load
if filename:
self.load_file_and_setup_slice_widgets(filename)
- # fix for making dock widgets fill entire window
- # self.main_widget = QtGui.QWidget(self)
- # self.main_widget.setFocus()
- # self.setCentralWidget(self.main_widget)
- # self.main_widget.hide()
def setup_dock_widgets(self):
self.setDockOptions(QtGui.QMainWindow.AllowNestedDocks)
@@ -206,55 +105,6 @@ class SegyViewer(QtGui.QMainWindow):
for widgt in dock_widget.findChildren(SliceWidget):
widgt.deleteLater()
- def setup_widgets_and_controls(self):
- self.addToolBar(LineNavigationBar(self.swrap.xlines,
- self.swrap.ilines,
- range(self.swrap.samples),
- self.line_monitor))
-
- # initialize slice widgets
- x_slice_widget = SliceWidget(self.swrap.xline, self.swrap.xlines,
- x_axis_indexes=('i-lines', self.swrap.ilines),
- y_axis_indexes=('depth', range(self.swrap.samples)),
- show_v_indicator=True,
- v_min_max=self.swrap.min_max)
-
- i_slice_widget = SliceWidget(self.swrap.iline, self.swrap.ilines,
- x_axis_indexes=('x-lines', self.swrap.xlines),
- y_axis_indexes=('depth', range(self.swrap.samples)),
- show_v_indicator=True,
- v_min_max=self.swrap.min_max)
-
- depth_slice_widget = SliceWidget(self.swrap.depth_slice, range(self.swrap.samples),
- x_axis_indexes=('i-lines', self.swrap.ilines),
- y_axis_indexes=('x-lines', self.swrap.xlines),
- show_v_indicator=True,
- show_h_indicator=True,
- v_min_max=self.swrap.min_max)
-
- # attach line-index change signals
- x_slice_widget.index_changed.connect(self.line_monitor.iline_updated)
- i_slice_widget.index_changed.connect(self.line_monitor.xline_updated)
-
- self.line_monitor.iline_changed.connect(x_slice_widget.set_vertical_line_indicator)
- self.line_monitor.iline_changed.connect(depth_slice_widget.set_vertical_line_indicator)
- self.line_monitor.iline_changed.connect(i_slice_widget.update_image)
-
- self.line_monitor.xline_changed.connect(i_slice_widget.set_vertical_line_indicator)
- self.line_monitor.xline_changed.connect(depth_slice_widget.set_horizontal_line_indicator)
- self.line_monitor.xline_changed.connect(x_slice_widget.update_image)
-
- self.line_monitor.depth_changed.connect(depth_slice_widget.update_image)
-
- # colormap signals
- self.colormap_monitor.cmap_changed.connect(x_slice_widget.set_cmap)
- self.colormap_monitor.cmap_changed.connect(i_slice_widget.set_cmap)
- self.colormap_monitor.cmap_changed.connect(depth_slice_widget.set_cmap)
-
- self.xdock.setWidget(x_slice_widget)
- self.idock.setWidget(i_slice_widget)
- self.ddock.setWidget(depth_slice_widget)
-
def open_file_dialogue(self):
f_dialog = QtGui.QFileDialog(self)
@@ -286,32 +136,53 @@ class SegyViewer(QtGui.QMainWindow):
self.progress_bar.show()
self.file_activity_monitor.reset()
- self.swrap = SegyIOWrapper(self.file_activity_monitor)
-
- # worker thread and worker obj are referenced from main thread to not get gc'ed by accident
- self.file_loader_thread = QtCore.QThread()
- self.file_loader_worker = FileLoaderWorker(self.swrap, filename, read_to_memory=read_to_memory)
- self.file_loader_worker.moveToThread(self.file_loader_thread)
-
- # what to do
- self.file_loader_thread.started.connect(self.file_loader_worker.load_file)
-
- # update progress
- self.file_loader_worker.progress.connect(self.progress_bar.set_value)
-
- # when finished
- self.file_loader_worker.finished.connect(self.complete_finished_file_load_operation)
-
- self.file_loader_thread.start()
- def complete_finished_file_load_operation(self, status):
+ # calling close on current filehandler
+ if self.swrap is not None:
+ self.swrap.close()
+
+ # instantiating a new wrapper
+ self.swrap = SegyIOWrapper.open_file_and_wrap(file_name=filename,
+ file_activity_monitor=self.file_activity_monitor)
+ # callback when finished
+ def complete_finished_file_load_operation(status):
+ if status == 0: # when completed successfully
+ self.initialize_slice_widgets()
+ self.progress_bar.hide()
+ self.file_loader_thread.quit()
+
+ # a memory read, might take some time. Set up a separate thread and update the progressbar
+ if read_to_memory:
+ # worker thread and worker obj are referenced from main thread to not get gc'ed by accident
+ self.file_loader_thread = QtCore.QThread()
+ self.file_loader_worker = FileLoaderWorker(self.swrap)
+ self.file_loader_worker.moveToThread(self.file_loader_thread)
+
+ # what to do
+ self.file_loader_thread.started.connect(self.file_loader_worker.load_file)
+
+ # update progress
+ self.file_loader_worker.progress.connect(self.progress_bar.set_value)
+
+ # set up finished callback
+ self.file_loader_worker.finished.connect(complete_finished_file_load_operation)
+
+ # and start
+ self.file_loader_thread.start()
+ else:
+ complete_finished_file_load_operation(0)
- if status == 0: # when completed successfully
- self.setup_widgets_and_controls()
+ def initialize_slice_widgets(self):
+ self.addToolBar(LineNavigationBar(self.swrap.xlines,
+ self.swrap.ilines,
+ range(self.swrap.samples),
+ self.line_monitor))
- self.progress_bar.hide()
- self.file_loader_thread.quit()
+ x_wdgt, i_wdgt, d_wdgt = viewer.initialize_slice_widgets(self.swrap, self.line_monitor, self.colormap_monitor)
+ self.xdock.setWidget(x_wdgt)
+ self.idock.setWidget(i_wdgt)
+ self.ddock.setWidget(d_wdgt)
def main():
diff --git a/python/segyview/CMakeLists.txt b/python/segyview/CMakeLists.txt
index 42de12b..89bd465 100644
--- a/python/segyview/CMakeLists.txt
+++ b/python/segyview/CMakeLists.txt
@@ -1,9 +1,11 @@
set(PYTHON_SOURCES
__init__.py
linenavigationbar.py
+ progresswidget.py
segyiowrapper.py
segyplot.py
slicewidget.py
+ viewer.py
)
add_python_package(segyview segyview "${PYTHON_SOURCES}")
diff --git a/python/segyview/__init__.py b/python/segyview/__init__.py
index a8c2648..273d2c7 100644
--- a/python/segyview/__init__.py
+++ b/python/segyview/__init__.py
@@ -3,7 +3,10 @@ from .segyiowrapper import SegyIOWrapper, SlicesWrapper
try:
from .linenavigationbar import LineNavigationBar
+ from .progresswidget import ProgressWidget
from .slicewidget import SliceWidget
+ from .segyiowrapper import SegyIOWrapper, SlicesWrapper
+ from .viewer import *
except ImportError as e:
import sys
import traceback
diff --git a/python/segyview/progresswidget.py b/python/segyview/progresswidget.py
new file mode 100644
index 0000000..a530f9d
--- /dev/null
+++ b/python/segyview/progresswidget.py
@@ -0,0 +1,25 @@
+from PyQt4 import QtGui
+
+
+class ProgressWidget(QtGui.QWidget):
+
+ def __init__(self, call_on_cancel):
+ super(ProgressWidget, self).__init__()
+ self.call_on_cancel = call_on_cancel
+
+ layout = QtGui.QHBoxLayout()
+ # progress bar
+ self.p_bar = QtGui.QProgressBar(self)
+ cancel_file_load_btn = QtGui.QPushButton()
+ cancel_file_load_btn.setText("cancel")
+
+ cancel_file_load_btn.clicked.connect(self.call_on_cancel)
+
+ layout.addWidget(self.p_bar, 2)
+ layout.addWidget(cancel_file_load_btn)
+
+ self.setLayout(layout)
+
+ def set_value(self, int):
+ self.p_bar.setValue(int)
+
diff --git a/python/segyview/viewer.py b/python/segyview/viewer.py
new file mode 100644
index 0000000..32fad8f
--- /dev/null
+++ b/python/segyview/viewer.py
@@ -0,0 +1,177 @@
+from segyview import SegyIOWrapper, SliceWidget
+from PyQt4 import QtGui, QtCore
+
+
+class LineSelectionMonitor(QtCore.QObject):
+ iline_changed = QtCore.pyqtSignal(int)
+ xline_changed = QtCore.pyqtSignal(int)
+ depth_changed = QtCore.pyqtSignal(int)
+
+ def __init__(self, parent):
+ QtCore.QObject.__init__(self, parent)
+
+ def iline_updated(self, new_index):
+ self.iline_changed.emit(new_index)
+
+ def xline_updated(self, new_index):
+ self.xline_changed.emit(new_index)
+
+ def depth_updated(self, new_index):
+ self.depth_changed.emit(new_index)
+
+
+class ColorMapMonitor(QtCore.QObject):
+ cmap_changed = QtCore.pyqtSignal(str)
+
+ def __init__(self, parent=None):
+ QtCore.QObject.__init__(self, parent)
+
+ def colormap_updated(self, value):
+ self.cmap_changed.emit(str(value))
+
+
+class FileActivityMonitor(QtCore.QObject):
+ started = QtCore.pyqtSignal()
+ finished = QtCore.pyqtSignal()
+ cancelled_operation = False
+
+ def __init__(self, parent=None):
+ QtCore.QObject.__init__(self)
+ self.cancelled_operation = False
+
+ def reset(self):
+ self.cancelled_operation = False
+
+ def set_file_read_started(self):
+ self.started.emit()
+
+ def set_file_read_finished(self):
+ self.finished.emit()
+
+ def set_cancel_operation(self):
+ self.finished.emit()
+ self.cancelled_operation = True
+
+
+class FileLoaderWorker(QtCore.QObject):
+ finished = QtCore.pyqtSignal(int)
+ progress = QtCore.pyqtSignal(int)
+
+ def __init__(self, segyio_wrapper):
+ QtCore.QObject.__init__(self)
+ self.segyio_wrapper = segyio_wrapper
+
+ def load_file(self):
+
+ if self.segyio_wrapper.read_all_traces_to_memory(progress_callback=self.progress.emit):
+ self.finished.emit(0)
+ else:
+ self.finished.emit(1)
+
+ return None
+
+
+class View(object):
+ """ A container for a standalone pre defined three-slices view, wrapped in a single QWidget. Plus monitor instances
+ for qt-signaling GUI events either from or to the slice viewers.
+
+ The widget, and monitors are provided through the class properties.
+ """
+
+ def __init__(self, segy):
+
+ self.segy = segy
+
+ self._file_activity_monitor = FileActivityMonitor()
+
+ self._swrap = SegyIOWrapper.wrap(segy, self.file_activity_monitor)
+
+ self._main_widget = QtGui.QWidget()
+ self._line_selection_monitor = LineSelectionMonitor(self._main_widget)
+ self._colormap_monitor = ColorMapMonitor(self._main_widget)
+
+ x_slice_widget, i_slice_widget, depth_slice_widget = initialize_slice_widgets(self._swrap,
+ self._line_selection_monitor,
+ self._colormap_monitor)
+ # layout for the single parent widget
+ top_row = QtGui.QHBoxLayout()
+ top_row.addWidget(x_slice_widget, 0)
+ top_row.addWidget(depth_slice_widget, 0)
+
+ bottom_row = QtGui.QHBoxLayout()
+ bottom_row.addWidget(i_slice_widget)
+
+ layout = QtGui.QVBoxLayout()
+ layout.addLayout(top_row)
+ layout.addLayout(bottom_row)
+
+
+ self._main_widget.setLayout(layout)
+
+ @property
+ def main_widget(self):
+ return self._main_widget
+
+ @property
+ def line_selection_monitor(self):
+ return self._line_selection_monitor
+
+ @property
+ def colormap_monitor(self):
+ return self._colormap_monitor
+
+ @property
+ def file_activity_monitor(self):
+ return self._file_activity_monitor
+
+
+def initialize_slice_widgets(segyio_wrapper, line_selection_monitor, colormap_monitor):
+ """
+ Given a segio_wrapper, and signal monitors, sliceviewer widgets for all three slices in a segy-cube are created.
+ :param segyio_wrapper:
+ :param line_selection_monitor:
+ :param colormap_monitor:
+ :return: three QWidgets for the three segy slices, in x, i and depth slice order.
+ """
+
+ # initialize slice widgets
+ x_slice_widget = SliceWidget(segyio_wrapper.xline, segyio_wrapper.xlines,
+ x_axis_indexes=('i-lines', segyio_wrapper.ilines),
+ y_axis_indexes=('depth', range(segyio_wrapper.samples)),
+ show_v_indicator=True,
+ v_min_max=segyio_wrapper.min_max)
+
+ i_slice_widget = SliceWidget(segyio_wrapper.iline, segyio_wrapper.ilines,
+ x_axis_indexes=('x-lines', segyio_wrapper.xlines),
+ y_axis_indexes=('depth', range(segyio_wrapper.samples)),
+ show_v_indicator=True,
+ v_min_max=segyio_wrapper.min_max)
+
+ depth_slice_widget = SliceWidget(segyio_wrapper.depth_slice, range(segyio_wrapper.samples),
+ x_axis_indexes=('i-lines', segyio_wrapper.ilines),
+ y_axis_indexes=('x-lines', segyio_wrapper.xlines),
+ show_v_indicator=True,
+ show_h_indicator=True,
+ v_min_max=segyio_wrapper.min_max)
+
+ # attach line-index change signals
+ x_slice_widget.index_changed.connect(line_selection_monitor.iline_updated)
+ i_slice_widget.index_changed.connect(line_selection_monitor.xline_updated)
+
+ line_selection_monitor.iline_changed.connect(x_slice_widget.set_vertical_line_indicator)
+ line_selection_monitor.iline_changed.connect(depth_slice_widget.set_vertical_line_indicator)
+ line_selection_monitor.iline_changed.connect(i_slice_widget.update_image)
+
+ line_selection_monitor.xline_changed.connect(i_slice_widget.set_vertical_line_indicator)
+ line_selection_monitor.xline_changed.connect(depth_slice_widget.set_horizontal_line_indicator)
+ line_selection_monitor.xline_changed.connect(x_slice_widget.update_image)
+
+ line_selection_monitor.depth_changed.connect(depth_slice_widget.update_image)
+
+ # colormap signals
+ colormap_monitor.cmap_changed.connect(x_slice_widget.set_cmap)
+ colormap_monitor.cmap_changed.connect(i_slice_widget.set_cmap)
+ colormap_monitor.cmap_changed.connect(depth_slice_widget.set_cmap)
+
+ return x_slice_widget, i_slice_widget, depth_slice_widget
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git
More information about the debian-science-commits
mailing list