Source code for taurus.qt.qtgui.input.choicedlg

#!/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 package provides a dialog for graphically choosing a Taurus class
"""

from taurus.external.qt import Qt


__docformat__ = "restructuredtext"


[docs] class GraphicalChoiceDlg(Qt.QDialog): """ A generic dialog for choosing among a set of choices which are presented as an array of, each with a given pixmap. The :meth:`getChoice` static method is provided for convenience so that the dialog can be invoked wit a single line:: chosen,ok = GraphicalChoiceDlg.getChoice( parent, title, msg, choices, pixmaps, size, defpixmap, horizontalScrollBarPolicy, verticalScrollBarPolicy ) """ def __init__( self, parent=None, designMode=False, choices=None, pixmaps=None, iconSize=128, defaultPixmap=None, horizontalScrollBarPolicy=Qt.Qt.ScrollBarAsNeeded, verticalScrollBarPolicy=Qt.Qt.ScrollBarAsNeeded, ): Qt.QDialog.__init__(self, parent) self._chosen = None self.setLayout(Qt.QVBoxLayout()) self.label = Qt.QLabel("Click on your choice:") self.layout().addWidget(self.label) self._iconsArea = GraphicalChoiceWidget( parent=parent, designMode=designMode, choices=choices, pixmaps=pixmaps, iconSize=iconSize, defaultPixmap=defaultPixmap, horizontalScrollBarPolicy=horizontalScrollBarPolicy, verticalScrollBarPolicy=verticalScrollBarPolicy, ) self.layout().addWidget(self._iconsArea) self._iconsArea.choiceMade.connect(self.onChoiceMade)
[docs] def setHorizontalScrollBarPolicy(self, policy): """sets horizontal scrollbar policy of scrollArea""" return self._iconsArea.setHorizontalScrollBarPolicy(policy)
[docs] def setVerticalScrollBarPolicy(self, policy): """sets vertical scrollbar policy of scrollArea""" return self._iconsArea.setVerticalScrollBarPolicy(policy)
[docs] def setMessage(self, msg): """sets the text which is shown to the user in the dialog""" self.label.setText(msg)
[docs] def onChoiceMade(self, chosen): """slot called when the user chooses an option""" self.accept()
[docs] def getChosen(self): """ returns the choice :return: :rtype: str """ return self._iconsArea.getChosen()
[docs] @staticmethod def getChoice( parent=None, title="", msg="", choices=None, pixmaps=None, iconSize=128, defaultPixmap=None, horizontalScrollBarPolicy=Qt.Qt.ScrollBarAsNeeded, verticalScrollBarPolicy=Qt.Qt.ScrollBarAsNeeded, ): """ Static method which launches a GraphicalChoiceDlg with the given options and returns the result :param parent: The parent of the dialog (it will be centered on it) :type parent: QWidget :param title: the text which is displayed in the title bar of the dialog :type title: str :param msg: the text which is shown to the user in the dialog, above the choices. :type msg: str :param choices: a list of lists of strings to be used as choices names. The (possibly sparse) 2D array defined by the nested lists will be used to present the choices in a grid. The choice names will be used as keys for pixmaps :type choices: list<list> :param pixmaps: dictionary mapping the choices text to corresponding pixmap. If no valid pixmap is provided for a given choice, the defaultPixmap will be used :type pixmaps: dict<str,QPixmap> :param iconSize: size of the icons to be displayed (128px by default) :type iconSize: int :param defaultPixmap: Default Pixmap to use if none passed for a given choice. No Pixmap will be used if None passed. :type defaultPixmap: QPixmap :param horizontalScrollBarPolicy: defines the mode of the horizontal scroll bar. The default mode is ScrollBarAsNeeded. :type horizontalScrollBarPolicy: enum Qt.ScrollBarPolicy :param verticalScrollBarPolicy: defines the mode of the vertical scroll bar. The default mode is ScrollBarAsNeeded :type verticalScrollBarPolicy: enum Qt.ScrollBarPolicy :return: A tuple containing choice,ok. choice is the name of the chosen option. ok is true if the user pressed OK and false if the user pressed Cancel. :rtype: tuple<str,bool> """ dlg = GraphicalChoiceDlg( parent=parent, choices=choices, pixmaps=pixmaps, iconSize=iconSize, defaultPixmap=defaultPixmap, horizontalScrollBarPolicy=horizontalScrollBarPolicy, verticalScrollBarPolicy=verticalScrollBarPolicy, ) dlg.setWindowTitle(title) dlg.setMessage(msg) dlg.exec_() return dlg.getChosen(), (dlg.result() == dlg.Accepted)
[docs] class GraphicalChoiceWidget(Qt.QScrollArea): """A widget that presents a 2D grid of buttons""" choiceMade = Qt.pyqtSignal("QString") def __init__( self, parent=None, designMode=False, choices=None, pixmaps=None, iconSize=128, defaultPixmap=None, horizontalScrollBarPolicy=Qt.Qt.ScrollBarAsNeeded, verticalScrollBarPolicy=Qt.Qt.ScrollBarAsNeeded, ): Qt.QScrollArea.__init__(self, parent) self._chosen = None self._iconSize = iconSize if defaultPixmap is None: defaultPixmap = Qt.QPixmap() self._defaultPixmap = defaultPixmap self.setFrameShape(Qt.QFrame.NoFrame) self.setWidgetResizable(True) self.setHorizontalScrollBarPolicy(horizontalScrollBarPolicy) self.setVerticalScrollBarPolicy(verticalScrollBarPolicy) w = Qt.QWidget() self.gridLayout = Qt.QGridLayout() w.setLayout(self.gridLayout) self.setWidget(w) if choices is not None: self.setChoices(choices, pixmaps) elif designMode: from taurus.qt.qtgui.icon import getCachedPixmap pm = getCachedPixmap("logos:taurus.png") self.setChoices( [["choice1", "choice2"], ["choice3", "choice4"]], dict(choice1=pm, choice2=pm, choice3=pm, choice4=pm), )
[docs] def setChoices(self, choices, pixmaps=None): """ sets the available options :param choices: a list of lists of strings to be used as choices names. The (possibly sparse) 2D array defined by the nested lists will be used to present the choices in a grid. The choice names will be used as keys for pixmaps :type choices: list<list> :param pixmaps: dictionary mapping the choices text to corresponding pixmap. If no valid pixmap is provided for a given choice, a default pixmap will be used :type pixmaps: dict<str,QPixmap> """ if pixmaps is None: pixmaps = {} for i, rowlist in enumerate(choices): for j, choice in enumerate(rowlist): self.setChoice( i, j, str(choice), pixmap=pixmaps.get(choice, None) )
[docs] def setChoice(self, row, col, text, pixmap=None, tooltip=None): """ sets the option for a given row,column coordinate in the grid :param row: row in the grid for this option :type row: int :param col: column in the grid for this option :type col: int :param text: name for this option :type text: str :param pixmap: If no valid pixmap is provided for a given choice, the default one will be used :type pixmap: QPixmap or None :param tooltip: tooltip for this option (if None given, the `text` is used) :type tooltip: str """ if not pixmap or pixmap is None or pixmap.isNull(): pixmap = self._defaultPixmap if tooltip is None: tooltip = text button = Qt.QToolButton() button.setText(text) button.setIcon(Qt.QIcon(pixmap)) button.setIconSize(Qt.QSize(self._iconSize, self._iconSize)) button.setToolTip(tooltip) button.clicked.connect(self.onClick) self.gridLayout.addWidget(button, row, col, Qt.Qt.AlignCenter) # ------------------------------------------------------- # Work around for https://bugs.kde.org/show_bug.cgi?id=345023 # TODO: make better solution for this button._id = text # <-- ugly monkey-patch!
# -------------------------------------------------------
[docs] def onClick(self): """slot called when a button is clicked""" # ------------------------------------------------------- # Work around for https://bugs.kde.org/show_bug.cgi?id=345023 # TODO: make better solution for this # self._chosen = str(self.sender().text()) # <- fails due to added "&" self._chosen = self.sender()._id # <-- this was monkey-patched # ------------------------------------------------------- self.choiceMade.emit(self._chosen)
[docs] def getChosen(self): """ returns the choice :return: :rtype: str """ return self._chosen
[docs] @classmethod def getQtDesignerPluginInfo(cls): """Returns pertinent information in order to be able to build a valid QtDesigner widget plugin The dictionary returned by this method should contain *at least* the following keys and values: - 'module' : a string representing the full python module name (ex.: 'taurus.qt.qtgui.base') - 'icon' : a string representing valid resource icon (ex.: 'designer:combobox.png') - 'container' : a bool telling if this widget is a container widget or not. This default implementation returns the following dictionary:: { 'group' : 'Taurus Widgets', 'icon' : 'logos:taurus.png', 'container' : False } :return: a map with pertinent designer information :rtype: dict """ return { "module": "taurus.qt.qtgui.input", "group": "Taurus Input", "icon": "logos:taurus.png", "container": False, }
def testWidget(): import sys from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication(sys.argv, cmd_line_parser=None) w = GraphicalChoiceWidget(None, True) w.show() sys.exit(app.exec_()) def main(): import sys from taurus.qt.qtgui.icon import getCachedPixmap from taurus.qt.qtgui.application import TaurusApplication app = TaurusApplication(sys.argv, cmd_line_parser=None) pixmaps = {} choices = [["TaurusForm", "TaurusTrend"], ["TaurusPlot", "Qub"]] for row in choices: for k in row: pixmaps[k] = getCachedPixmap("snapshot:%s.png" % k) print( GraphicalChoiceDlg.getChoice( parent=None, title="Panel chooser", msg="Choose the type of Panel:", choices=choices, pixmaps=pixmaps, ) ) sys.exit(app.exec_()) if __name__ == "__main__": main() # testWidget()