Source code for taurus.qt.qtgui.container.qcontainer

#!/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 basic pure Qt container widgets
"""

import json

from taurus.external.qt import Qt
from taurus.qt.qtgui.icon import getStandardIcon


__docformat__ = "restructuredtext"


_TitleBarStyleExpanded = """.QFrame {{
border-width: 0px;
border-style: solid;
border-color: {stop_color};
border-top-left-radius: {border_radius};
border-top-right-radius: {border_radius};
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                  stop: 0 {start_color}, stop: 1 {stop_color});
}}"""

_TitleBarStyleCollapsed = """.QFrame {{
border-width: 0px;
border-style: solid;
border-color: {stop_color};
border-top-left-radius: {border_radius};
border-top-right-radius: {border_radius};
border-bottom-left-radius: {border_radius};
border-bottom-right-radius: {border_radius};
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
                                  stop: 0 {start_color}, stop: 1 {stop_color});
}}"""

_TitleLabelStyle = """.QLabel {{ color : {font_color}; }}"""

_ContentBarStyleWithTitle = """ContentFrame {{
border-top-width: 0px;
border-left-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-style: solid;
border-color: {border_color};
border-top-left-radius: 0px;
border-top-right-radius: 0px;
border-bottom-left-radius: {border_radius};
border-bottom-right-radius: {border_radius};
background-color: qlineargradient(x1: 0, y1: 0, x2: 1.0, y2: 1.0,
                                  stop: 0 {start_color}, stop: 1 {stop_color});
/*
  background-position: center center;
*/
}}"""

_ContentBarStyleWithoutTitle = """ContentFrame {{
border-width: 1px;
border-style: solid;
border-color: {border_color};
border-top-left-radius: {border_radius};
border-top-right-radius: {border_radius};
border-bottom-left-radius: {border_radius};
border-bottom-right-radius: {border_radius};
background-color: qlineargradient(x1: 0, y1: 0, x2: 1.0, y2: 1.0,
                                  stop: 0 {start_color}, stop: 1 {stop_color});
/*
  background-position: center center;
*/
}}"""

# Empty content QFrame to avoid frame style to be propagated
# to child QFrame widgets


class ContentFrame(Qt.QFrame):
    pass


[docs]class QGroupWidget(Qt.QWidget): """An expandable/collapsible composite widget""" DefaultTitleBarVisible = True DefaultTitleBarHeight = 16 DefaultTitleBarStyle = { "start_color": "rgb(60, 150, 255)", "stop_color": "rgb(0, 65, 200)", "font_color": "white", "border_radius": "5px", } DefaultContentVisible = True DefaultContentStyle = { "start_color": "rgb(224, 224, 224)", "stop_color": "rgb(255, 255, 255)", "border_color": "rgb(0, 85, 227)", "border_radius": "5px", } def __init__(self, parent=None, designMode=False): Qt.QWidget.__init__(self, parent) self._titleVisible = self.DefaultTitleBarVisible self._contentVisible = self.DefaultContentVisible self._titleBarStyle = self.DefaultTitleBarStyle self._contentStyle = self.DefaultContentStyle self.__init() self._updateStyle() self.resetContentVisible() self.resetTitleHeight() self.resetTitleVisible() def __init(self): panelLayout = Qt.QVBoxLayout() panelLayout.setSpacing(0) panelLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(panelLayout) self._titleBar = titleBar = Qt.QFrame() panelLayout.addWidget(titleBar, 0) lyt = Qt.QHBoxLayout() lyt.setContentsMargins(2, 2, 2, 2) lyt.setSpacing(2) self._titleBar.setLayout(lyt) self._titleButton = Qt.QToolButton() self._titleButton.setStyleSheet("border: 0px") styleOption = Qt.QStyleOption() styleOption.initFrom(self._titleButton) style = Qt.QApplication.style() icon = style.standardIcon( Qt.QStyle.SP_DesktopIcon, styleOption, self._titleButton ) self._titleButton.setIcon(icon) self._titleLabel = Qt.QLabel() self._upDownButton = Qt.QToolButton() self._upDownButton.setStyleSheet("border: 0px") self._upDownButton.clicked.connect(self.switchContentVisible) lyt.addWidget(self._titleButton, 0) lyt.addWidget(self._titleLabel, 1) lyt.addWidget(self._upDownButton, 0) self._content = content = ContentFrame() lyt = Qt.QHBoxLayout() lyt.setContentsMargins(0, 0, 0, 0) content.setLayout(lyt) panelLayout.addWidget(content, 1) def _updateStyle(self): """Internal method that updates the style""" if self.contentVisible: ts = _TitleBarStyleExpanded else: ts = _TitleBarStyleCollapsed fullTitleBarStyle = ts.format(**self._titleBarStyle) fullTitleLabelStyle = _TitleLabelStyle.format(**self._titleBarStyle) if self.titleVisible: contentStyleTemplate = _ContentBarStyleWithTitle else: contentStyleTemplate = _ContentBarStyleWithoutTitle contentStyle = self._contentStyle.copy() contentStyle["border_color"] = self._titleBarStyle["stop_color"] fullContentStyle = contentStyleTemplate.format(**contentStyle) self._titleBar.setStyleSheet(fullTitleBarStyle) self._titleLabel.setStyleSheet(fullTitleLabelStyle) self._content.setStyleSheet(fullContentStyle)
[docs] @classmethod def getQtDesignerPluginInfo(cls): return { "module": "taurus.qt.qtgui.container", "group": "Taurus Containers", "icon": "designer:groupwidget.png", "container": True, }
[docs] def content(self): """Returns the contents widget :return: the content widget :rtype: Qt.QFrame """ return self._content
[docs] def titleBar(self): """Returns the title bar widget :return: the title bar widget :rtype: Qt.QFrame """ return self._titleBar
[docs] def titleButton(self): """Returns the title button widget :return: the title button widget :rtype: Qt.QToolButton """ return self._titleButton
[docs] def collapseButton(self): """Returns the collapse button widget :return: the collapse button widget :rtype: Qt.QToolButton """ return self._upDownButton
[docs] def setTitle(self, title): """Sets this widget's title :param title: the new widget title :type title: str """ self._titleLabel.setText(title)
[docs] def getTitle(self): """Returns this widget's title :return: this widget's title :rtype: str """ return self._titleLabel.text()
[docs] def setTitleIcon(self, icon): """Sets this widget's title icon :param icon: the new widget title icon :type icon: Qt.QIcon """ self._titleButton.setIcon(icon)
[docs] def getTitleIcon(self): """Returns this widget's title icon :return: this widget's title icon :rtype: Qt.QIcon """ return self._titleButton.icon()
[docs] def switchContentVisible(self): """Switches this widget's contents visibility""" self.setContentVisible(not self.isContentVisible())
[docs] def isContentVisible(self): """Returns this widget's contents visibility :return: this widget's contents visibility :rtype: bool """ return self._contentVisible
[docs] def resetContentVisible(self): """Resets this widget's contents visibility""" self.setContentVisible(self.DefaultContentVisible)
[docs] def setContentVisible(self, show): """Sets this widget's contents visibility :param show: the new widget contents visibility :type show: bool """ self._contentVisible = show self._updateStyle() # if show: icon_name = "go-previous" # else: icon_name = "go-down" # icon = Qt.QIcon.fromTheme(icon_name) if show: icon_name = Qt.QStyle.SP_TitleBarShadeButton else: icon_name = Qt.QStyle.SP_TitleBarUnshadeButton icon = getStandardIcon(icon_name, self._upDownButton) self._upDownButton.setIcon(icon) self._content.setVisible(show) self.adjustSize()
[docs] def isTitleVisible(self): """Returns this widget's title visibility :return: this widget's title visibility :rtype: bool """ return self._titleVisible
[docs] def resetTitleVisible(self): """Resets this widget's title visibility""" self.setTitleVisible(self.DefaultTitleBarVisible)
[docs] def setTitleVisible(self, show): """Sets this widget's title visibility :param icon: the new widget title visibility :type icon: bool """ self._titleVisible = show self._titleBar.setVisible(show) self._updateStyle()
[docs] def getTitleHeight(self): """Returns this widget's title height :return: this widget's title height :rtype: bool """ return self.titleButton().iconSize().height()
[docs] def setTitleHeight(self, h): """Sets this widget's title height :param icon: the new widget title height :type icon: bool """ s = Qt.QSize(h, h) self.titleButton().setIconSize(s) self.collapseButton().setIconSize(s)
[docs] def resetTitleHeight(self): """Resets this widget's title height""" self.setTitleHeight(self.DefaultTitleBarHeight)
[docs] def getTitleStyle(self): """Returns this widget's title style :return: this widget's title style :rtype: dict """ return self._titleBarStyle
[docs] def setTitleStyle(self, style_map): """Sets this widget's title style Used key/values for style_map: - 'start_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') - 'stop_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') - 'font_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') - 'border_radius': radius (Ex.: '5px', '5px,2px') :param style_map: the new widget title style :type style_map: dict """ style = self.DefaultTitleBarStyle.copy() style.update(style_map) self._titleBarStyle = style self._updateStyle()
[docs] def resetTitleStyle(self): """Resets this widget's title style""" self.setTitleStyle({})
[docs] def getTitleStyleStr(self): """Returns this widget's title style :return: this widget's title style :rtype: dict """ return json.dumps(self._titleBarStyle)
[docs] def setTitleStyleStr(self, style_map): """Sets this widget's title style Used key/values for style_map: - 'start_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') - 'stop_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') - 'font_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') - 'border_radius': radius (Ex.: '5px', '5px,2px') :param style_map: the new widget title style :type style_map: dict """ style_map = json.loads(str(style_map)) self.setTitleStyle(style_map)
[docs] def resetTitleStyleStr(self): """Resets this widget's title style""" self.resetTitleStyle()
[docs] def getContentStyle(self): """Returns this widget's content style :return: this widget's content style :rtype: dict """ return self._contentStyle
[docs] def setContentStyle(self, style_map): """Sets this widget's content style Used key/values for style_map: - 'start_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') - 'stop_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') :param style_map: the new widget content style :type style_map: dict """ style = self.DefaultContentStyle.copy() style.update(style_map) self._contentStyle = style self._updateStyle()
[docs] def resetContentStyle(self): """Resets this widget's content style""" self.setContentStyle({})
[docs] def getContentStyleStr(self): """Returns this widget's content style :return: this widget's content style :rtype: dict """ return json.dumps(self._contentStyle)
[docs] def setContentStyleStr(self, style_map): """Sets this widget's content style Used key/values for style_map: - 'start_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') - 'stop_color' : brush (Ex.: '#E0E0E0', 'rgb(0,0,0)', 'white') :param style_map: the new widget content style :type style_map: dict """ style_map = json.loads(str(style_map)) self.setContentStyle(style_map)
[docs] def resetContentStyleStr(self): """Resets this widget's content style""" self.resetContentStyle()
#: This property contains the widget's title #: #: **Access functions:** #: #: * :meth:`getTitle` #: * :meth:`setTitle` title = Qt.pyqtProperty("QString", getTitle, setTitle) #: This property contains the widget's title icon #: #: **Access functions:** #: #: * :meth:`getTitleIcon` #: * :meth:`setTitleIcon` titleIcon = Qt.pyqtProperty("QIcon", getTitleIcon, setTitleIcon) #: This property contains the widget's title height #: #: **Access functions:** #: #: * :meth:`getTitleHeight` #: * :meth:`setTitleHeight` #: * :meth:`resetTitleHeight` titleHeight = Qt.pyqtProperty( "int", getTitleHeight, setTitleHeight, resetTitleHeight ) #: This property contains the widget's title visibility #: #: **Access functions:** #: #: * :meth:`isTitleVisible` #: * :meth:`setTitleVisible` titleVisible = Qt.pyqtProperty("bool", isTitleVisible, setTitleVisible) #: This property contains the widget's content's visibility #: #: **Access functions:** #: #: * :meth:`isContentVisible` #: * :meth:`setContentVisible` #: * :meth:`resetContentVisible` contentVisible = Qt.pyqtProperty( "bool", isContentVisible, setContentVisible, resetContentVisible ) # : This property contains the widget's content style # : The style must be a json dictionary # : # : **Access functions:** # : # : * :meth:`getContentStyleStr` # : * :meth:`setContentStyleStr` # : * :meth:`resetContentStyleStr` contentStyle = Qt.pyqtProperty( "QString", getContentStyleStr, setContentStyleStr, resetContentStyleStr, doc="The style must be a json dictionary", ) # : This property contains the widget's title style # : The style must be a json dictionary # : # : **Access functions:** # : # : * :meth:`getTitleStyleStr` # : * :meth:`setTitleStyleStr` # : * :meth:`resetTitleStyleStr` titleStyle = Qt.pyqtProperty( "QString", getTitleStyleStr, setTitleStyleStr, resetTitleStyleStr, doc="The style must be a json dictionary", )
def demo(): "QGroup Widget" w = Qt.QWidget() lyt = Qt.QVBoxLayout() w.setLayout(lyt) panel = QGroupWidget() panel.title = "Database" contentLayout = Qt.QFormLayout() panel.content().setLayout(contentLayout) contentLayout.addRow("&Host", Qt.QLineEdit()) contentLayout.addRow("&Port", Qt.QLineEdit()) lyt.addWidget(panel, 0) panel = QGroupWidget() panel.title = "Hello world" panel.titleIcon = Qt.QIcon.fromTheme("video-x-generic") panel.setTitleStyle( { "start_color": "rgb(255, 60, 60)", "stop_color": "rgb(200, 0, 0)", "font_color": "rgb(140, 0, 0)", "border_radius": "10px", } ) panel.setContentStyle( { "border_radius": "0px", } ) contentLayout = Qt.QFormLayout() panel.content().setLayout(contentLayout) contentLayout.addRow("State", Qt.QPushButton("Press here")) contentLayout.addRow("Status", Qt.QLineEdit()) contentLayout.addRow("Coment", Qt.QLineEdit()) contentLayout.addRow("Build", Qt.QCheckBox()) contentLayout.addRow("Upper limit", Qt.QSpinBox()) contentLayout.addRow("Lower limit", Qt.QSpinBox()) lyt.addWidget(panel, 0) panel = QGroupWidget() panel.title = "Hello world 2" panel.titleIcon = Qt.QIcon.fromTheme("network-server") panel.titleVisible = False contentLayout = Qt.QFormLayout() panel.content().setLayout(contentLayout) contentLayout.addRow("Something", Qt.QLineEdit()) contentLayout.addRow("More", Qt.QLineEdit()) lyt.addWidget(panel, 0) panel = QGroupWidget() panel.title = "5" panel.titleIcon = Qt.QIcon.fromTheme("folder") contentLayout = Qt.QVBoxLayout() panel.content().setLayout(contentLayout) panel2 = QGroupWidget() panel2.title = "5.1" panel2.titleIcon = Qt.QIcon.fromTheme("folder") panel2.titleHeight = 48 contentLayout2 = Qt.QFormLayout() panel2.content().setLayout(contentLayout2) contentLayout2.addRow("Something", Qt.QLineEdit()) contentLayout2.addRow("More", Qt.QLineEdit()) contentLayout.addWidget(panel2, 0) lyt.addWidget(panel, 0) lyt.addStretch(1) w.show() w.adjustSize() return w def main(): import sys import taurus.qt.qtgui.application Application = taurus.qt.qtgui.application.TaurusApplication app = Application.instance() owns_app = app is None if owns_app: app = Application( app_name="Group widget demo", app_version="1.0", org_domain="Taurus", org_name="Tango community", ) w = demo() w.show() if owns_app: sys.exit(app.exec_()) else: return w if __name__ == "__main__": main()