Source code for taurus.qt.qtgui.dialog.taurusmessagebox

#!/usr/bin/env python

# ###########################################################################
#
# This file is part of Taurus
#
# http://taurus-scada.org
#
# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
#
# Taurus is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Taurus is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Taurus.  If not, see <http://www.gnu.org/licenses/>.
#
# ###########################################################################

"""This module provides a set of dialog based widgets
"""

import sys

from taurus.external.qt import Qt
from taurus.core.util.excepthook import BaseExceptHook
from taurus.core.util.log import LogExceptHook
from taurus.core.util.wrap import wraps


__docformat__ = "restructuredtext"


[docs]class TaurusMessageBox(Qt.QDialog): """A panel intended to display a taurus error. Example:: dev = taurus.Device("sys/tg_test/1") try: print(dev.read_attribute("throw_exception")) except PyTango.DevFailed, df: msgbox = TaurusMessageBox() msgbox.show() You can show the error outside the exception handling code. If you do this, you should keep a record of the exception information as given by :func:`sys.exc_info`:: dev = taurus.Device("sys/tg_test/1") exc_info = None try: print(dev.read_attribute("throw_exception")) except PyTango.DevFailed, df: exc_info = sys.exc_info() if exc_info: msgbox = TaurusMessageBox(*exc_info) msgbox.show() """ def __init__( self, err_type=None, err_value=None, err_traceback=None, parent=None, designMode=False, ): Qt.QDialog.__init__(self, parent) layout = Qt.QVBoxLayout() self.setLayout(layout) import taurus.qt.qtgui.panel MsgPanel = taurus.qt.qtgui.panel.TaurusMessagePanel self._panel = MsgPanel( err_type, err_value, err_traceback, self, designMode ) layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self._panel) self.panel().buttonBox().accepted.connect(self.accept) self._panel.toggledDetails.connect(self._onShowDetails) def _onShowDetails(self, show): self.adjustSize()
[docs] def panel(self): """Returns the :class:`taurus.qt.qtgui.panel.TaurusMessagePanel`. :return: the internal panel :rtype: taurus.qt.qtgui.panel.TaurusMessagePanel """ return self._panel
[docs] def addButton(self, button, role=Qt.QDialogButtonBox.ActionRole): """Adds the given button with the given to the button box :param button: the button to be added :type button: PyQt5.Qt.QPushButton :param role: button role :type role: PyQt5.Qt.QDialogButtonBox.ButtonRole """ self.panel().addButton(button, role)
[docs] def setIconPixmap(self, pixmap): """Sets the icon to the dialog :param pixmap: the icon pixmap :type pixmap: PyQt5.Qt.QPixmap """ self._panel.setIconPixmap(pixmap)
[docs] def setText(self, text): """Sets the text of the dialog :param text: the new text :type text: str """ self._panel.setText(text)
[docs] def getText(self): """Returns the current text of this panel :return: the text for this panel :rtype: str """ return self._panel.getText()
[docs] def setDetailedText(self, text): """Sets the detailed text of the dialog :param text: the new text :type text: str """ self._panel.setDetailedText(text)
[docs] def setError(self, err_type=None, err_value=None, err_traceback=None): """Sets the exception object. Example usage:: dev = taurus.Device("sys/tg_test/1") exc_info = None msgbox = TaurusMessageBox() try: print(dev.read_attribute("throw_exception")) except PyTango.DevFailed, df: exc_info = sys.exc_info() if exc_info: msgbox.setError(*exc_info) msgbox.show() :param err_type: the exception type of the exception being handled (a class object) :type error: class object :param err_value: exception object :type err_value: object :param err_traceback: a traceback object which encapsulates the call stack at the point where the exception originally occurred :type err_traceback: TracebackType """ self._panel.setError(err_type, err_value, err_traceback)
_PROTECT_MESSAGE_BOX = None def _ProtectMessageBox( err_type=None, err_value=None, err_traceback=None, parent=None ): global _PROTECT_MESSAGE_BOX box = _PROTECT_MESSAGE_BOX if box is None: _PROTECT_MESSAGE_BOX = box = TaurusMessageBox( err_type=err_type, err_value=err_value, err_traceback=err_traceback, parent=parent, ) box.panel().setCheckBoxVisible(True) else: box.setError( err_type=err_type, err_value=err_value, err_traceback=err_traceback ) if box.panel().checkBoxState() == Qt.Qt.Checked: return return box
[docs]def protectTaurusMessageBox(fn): """The idea of this function is to be used as a decorator on any method you which to protect against exceptions. The handle of the exception is to display a :class:`TaurusMessageBox` with the exception information. Example:: @protectTaurusMessgeBox def turnBeamOn(device_name): d = taurus.Device(device_name) d.TurnOn() """ @wraps(fn) def wrapped(*args, **kwargs): try: return fn(*args, **kwargs) except Exception: msgbox = _ProtectMessageBox(*sys.exc_info()) if msgbox is None: return msgbox.exec_() return wrapped
[docs]class ProtectTaurusMessageBox(object): """The idea of this class is to be used as a decorator on any method you which to protect against exceptions. The handle of the exception is to display a :class:`TaurusMessageBox` with the exception information. The optional parameter title gives the window bar a customized title. The optional parameter msg allows you to give a customized message in the dialog. Example:: @ProtectTaurusMessgeBox(title="Error trying to turn the beam on") def turnBeamOn(device_name): d = taurus.Device(device_name) d.TurnOn() """ def __init__(self, title=None, msg=None): self._title = title self._msg = msg def __call__(self, fn): @wraps(fn) def wrapped(*args, **kwargs): try: return fn(*args, **kwargs) except Exception: msgbox = _ProtectMessageBox(*sys.exc_info()) if msgbox is None: return if self._title is not None: msgbox.setWindowTitle(self._title) if self._msg is not None: msgbox.setText(self._msg) msgbox.exec_() return wrapped
[docs]class TaurusExceptHookMessageBox(BaseExceptHook): """A callable class that acts as an excepthook that displays an unhandled exception in a :class:`~taurus.qt.qtgui.dialog.TaurusMessageBox`. :param hook_to: callable excepthook that will be called at the end of this hook handling [default: None] :type hook_to: callable :param title: message box title [default: None meaning use exception value] :type name: str :param msg: message box text [default: None meaning use exception] """ MSG_BOX = None def __init__(self, hook_to=None, title=None, msg=None): BaseExceptHook.__init__(self, hook_to=hook_to) self._title = title self._msg = msg def _getMessageBox( self, err_type=None, err_value=None, err_traceback=None, parent=None ): box = self.__class__.MSG_BOX if box is None: self.__class__.MSG_BOX = box = TaurusMessageBox( err_type=err_type, err_value=err_value, err_traceback=err_traceback, parent=parent, ) box.panel().setCheckBoxVisible(True) else: box.setError( err_type=err_type, err_value=err_value, err_traceback=err_traceback, ) if box.panel().checkBoxState() == Qt.Qt.Checked: return return box
[docs] def report(self, *exc_info): app = Qt.QApplication.instance() if app is None: LogExceptHook().report(*exc_info) return msgbox = self._getMessageBox(*exc_info) if msgbox is None: return if self._title is not None: msgbox.setWindowTitle(self._title) if self._msg is not None: msgbox.setText(self._msg) msgbox.exec_()
class DemoException(Exception): pass def s1(): return s2() def s2(): return s3() def s3(): raise DemoException("A demo exception occurred") def py_exc(): try: s1() except Exception: msgbox = TaurusMessageBox(*sys.exc_info()) msgbox.exec_() def tg_exc(): import PyTango # TODO: tango-centric try: PyTango.Except.throw_exception( "TangoException", "A simple tango exception", "right here" ) except PyTango.DevFailed: msgbox = TaurusMessageBox(*sys.exc_info()) msgbox.exec_() def tg_serv_exc(): import PyTango # TODO: tango-centric import taurus dev = taurus.Device("sys/tg_test/1") try: dev.read_attribute("throw_exception") except PyTango.DevFailed: msgbox = TaurusMessageBox(*sys.exc_info()) msgbox.exec_() except Exception: msgbox = TaurusMessageBox(*sys.exc_info()) msgbox.exec_() def py_tg_serv_exc(): import PyTango # TODO: tango-centric try: PyTango.Except.throw_exception( "TangoException", "A simple tango exception", "right here" ) except PyTango.DevFailed as df1: try: import traceback import io origin = io.StringIO() traceback.print_stack(file=origin) origin.seek(0) origin = origin.read() PyTango.Except.re_throw_exception( df1, "PyDs_Exception", "DevFailed: A simple tango " "exception", origin, ) except PyTango.DevFailed: msgbox = TaurusMessageBox(*sys.exc_info()) msgbox.exec_() def demo(): """Message dialog""" panel = Qt.QWidget() layout = Qt.QVBoxLayout() panel.setLayout(layout) m1 = Qt.QPushButton("Python exception") layout.addWidget(m1) m1.clicked.connect(py_exc) m2 = Qt.QPushButton("Tango exception") layout.addWidget(m2) m2.clicked.connect(tg_exc) layout.addWidget(m2) m3 = Qt.QPushButton("Tango server exception") layout.addWidget(m3) m3.clicked.connect(tg_serv_exc) layout.addWidget(m3) m4 = Qt.QPushButton("Python tango server exception") layout.addWidget(m4) m4.clicked.connect(py_tg_serv_exc) layout.addWidget(m4) panel.show() return panel def main(): import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: app = Qt.QApplication([]) app.setApplicationName("Taurus message demo") app.setApplicationVersion("1.0") w = demo() if owns_app: sys.exit(app.exec_()) else: return w if __name__ == "__main__": main()