summaryrefslogtreecommitdiff
path: root/silx/gui/_utils.py
diff options
context:
space:
mode:
authorPicca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>2018-07-31 16:22:25 +0200
committerPicca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>2018-07-31 16:22:25 +0200
commit159ef14fb9e198bb0066ea14e6b980f065de63dd (patch)
treebc37c7d4ba09ee59deb708897fa0571709aec293 /silx/gui/_utils.py
parent270d5ddc31c26b62379e3caa9044dd75ccc71847 (diff)
New upstream version 0.8.0+dfsg
Diffstat (limited to 'silx/gui/_utils.py')
-rw-r--r--silx/gui/_utils.py175
1 files changed, 0 insertions, 175 deletions
diff --git a/silx/gui/_utils.py b/silx/gui/_utils.py
deleted file mode 100644
index d91a572..0000000
--- a/silx/gui/_utils.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# coding: utf-8
-# /*##########################################################################
-#
-# Copyright (c) 2017-2018 European Synchrotron Radiation Facility
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-# ###########################################################################*/
-"""This module provides convenient functions to use with Qt objects.
-
-It provides:
-- conversion between numpy and QImage:
- :func:`convertArrayToQImage`, :func:`convertQImageToArray`
-- Execution of function in Qt main thread: :func:`submitToQtMainThread`
-"""
-
-from __future__ import division
-
-
-__authors__ = ["T. Vincent"]
-__license__ = "MIT"
-__date__ = "16/01/2017"
-
-
-import sys
-import numpy
-
-from silx.third_party.concurrent_futures import Future
-
-from . import qt
-
-
-def convertArrayToQImage(image):
- """Convert an array-like RGB888 image to a QImage.
-
- The created QImage is using a copy of the array data.
-
- Limitation: Only supports RGB888 format.
-
- :param image: Array-like image data
- :type image: numpy.ndarray of uint8 of dimension HxWx3
- :return: Corresponding Qt image
- :rtype: QImage
- """
- # Possible extension: add a format argument to support more formats
-
- image = numpy.array(image, copy=False, order='C', dtype=numpy.uint8)
-
- height, width, depth = image.shape
- assert depth == 3
-
- qimage = qt.QImage(
- image.data,
- width,
- height,
- image.strides[0], # bytesPerLine
- qt.QImage.Format_RGB888)
-
- return qimage.copy() # Making a copy of the image and its data
-
-
-def convertQImageToArray(image):
- """Convert a RGB888 QImage to a numpy array.
-
- Limitation: Only supports RGB888 format.
- If QImage is not RGB888 it gets converted to this format.
-
- :param QImage: The QImage to convert.
- :return: The image array
- :rtype: numpy.ndarray of uint8 of shape HxWx3
- """
- # Possible extension: avoid conversion to support more formats
-
- if image.format() != qt.QImage.Format_RGB888:
- # Convert to RGB888 if needed
- image = image.convertToFormat(qt.QImage.Format_RGB888)
-
- ptr = image.bits()
- if qt.BINDING not in ('PySide', 'PySide2'):
- ptr.setsize(image.byteCount())
- if qt.BINDING == 'PyQt4' and sys.version_info[0] == 2:
- ptr = ptr.asstring()
- elif sys.version_info[0] == 3: # PySide with Python3
- ptr = ptr.tobytes()
-
- array = numpy.fromstring(ptr, dtype=numpy.uint8)
-
- # Lines are 32 bits aligned: remove padding bytes
- array = array.reshape(image.height(), -1)[:, :image.width() * 3]
- array.shape = image.height(), image.width(), 3
- return array
-
-
-class _QtExecutor(qt.QObject):
- """Executor of tasks in Qt main thread"""
-
- __sigSubmit = qt.Signal(Future, object, tuple, dict)
- """Signal used to run tasks."""
-
- def __init__(self):
- super(_QtExecutor, self).__init__(parent=None)
-
- # Makes sure the executor lives in the main thread
- app = qt.QApplication.instance()
- assert app is not None
- mainThread = app.thread()
- if self.thread() != mainThread:
- self.moveToThread(mainThread)
-
- self.__sigSubmit.connect(self.__run)
-
- def submit(self, fn, *args, **kwargs):
- """Submit fn(*args, **kwargs) to Qt main thread
-
- :param callable fn: Function to call in main thread
- :return: Future object to retrieve result
- :rtype: concurrent.future.Future
- """
- future = Future()
- self.__sigSubmit.emit(future, fn, args, kwargs)
- return future
-
- def __run(self, future, fn, args, kwargs):
- """Run task in Qt main thread
-
- :param concurrent.future.Future future:
- :param callable fn: Function to run
- :param tuple args: Arguments
- :param dict kwargs: Keyword arguments
- """
- if not future.set_running_or_notify_cancel():
- return
-
- try:
- result = fn(*args, **kwargs)
- except BaseException as e:
- future.set_exception(e)
- else:
- future.set_result(result)
-
-
-_executor = None
-"""QObject running the tasks in main thread"""
-
-
-def submitToQtMainThread(fn, *args, **kwargs):
- """Run fn(*args, **kwargs) in Qt's main thread.
-
- If not called from the main thread, this is run asynchronously.
-
- :param callable fn: Function to call in main thread.
- :return: A future object to retrieve the result
- :rtype: concurrent.future.Future
- """
- global _executor
- if _executor is None: # Lazy-loading
- _executor = _QtExecutor()
-
- return _executor.submit(fn, *args, **kwargs)