#!/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/>.
#
# ###########################################################################
"""
qsevensegmentdisplay.py
"""
from taurus.external.qt import Qt
__docformat__ = "restructuredtext"
POLY = Qt.QPolygonF
P = Qt.QPointF
[docs]
class Q7SegDigit(Qt.QWidget):
"""
A widget representing a single seven segment digit. The style can be
configured through the widget properties. For example, a typical LCD would
have the following style:
- bgColor 170, 170, 127
- ledOnPenColor 30,30,30
- ledOnBgColor 0,0,0
- ledOffPenColor 160, 160, 120
- ledOffbgColor 150, 150, 112
"""
Leds = (
(1, 1, 1, 0, 1, 1, 1), # 0
(0, 0, 1, 0, 0, 1, 0), # 1
(1, 0, 1, 1, 1, 0, 1), # 2
(1, 0, 1, 1, 0, 1, 1), # 3
(0, 1, 1, 1, 0, 1, 0), # 4
(1, 1, 0, 1, 0, 1, 1), # 5
(1, 1, 0, 1, 1, 1, 1), # 6
(1, 0, 1, 0, 0, 1, 0), # 7
(1, 1, 1, 1, 1, 1, 1), # 8
(1, 1, 1, 1, 0, 1, 0), # 9
(0, 0, 0, 0, 0, 0, 0), # 10 'nothing'
(0, 0, 0, 1, 0, 0, 0), # 11 -
(1, 0, 1, 1, 1, 1, 1), # 12 a
(0, 0, 0, 1, 1, 1, 0), # 13 n
)
LedGeometriesWithFrame300x400 = (
POLY([P(37, 30), P(263, 30), P(233, 60), P(67, 60), P(37, 30)]),
POLY([P(30, 37), P(60, 67), P(60, 178), P(30, 193), P(30, 37)]),
POLY([P(270, 37), P(240, 67), P(240, 178), P(270, 193), P(270, 37)]),
POLY(
[
P(37, 200),
P(67, 185),
P(233, 185),
P(263, 200),
P(233, 215),
P(67, 215),
P(37, 200),
]
),
POLY([P(30, 207), P(60, 222), P(60, 333), P(30, 363), P(30, 207)]),
POLY(
[P(270, 207), P(240, 222), P(240, 333), P(270, 363), P(270, 207)]
),
POLY([P(37, 370), P(263, 370), P(233, 340), P(67, 340), P(37, 370)]),
)
LedGeometriesWithoutFrame300x400 = (
POLY([P(7, 0), P(293, 0), P(263, 30), P(37, 30), P(7, 0)]),
POLY([P(0, 7), P(30, 37), P(30, 178), P(0, 193), P(0, 7)]),
POLY([P(300, 7), P(270, 37), P(270, 178), P(300, 193), P(300, 7)]),
POLY(
[
P(7, 200),
P(37, 185),
P(263, 185),
P(293, 200),
P(263, 215),
P(37, 215),
P(7, 200),
]
),
POLY([P(0, 207), P(30, 222), P(30, 363), P(0, 393), P(0, 207)]),
POLY(
[P(300, 207), P(270, 222), P(270, 363), P(300, 393), P(300, 207)]
),
POLY([P(7, 400), P(293, 400), P(263, 370), P(37, 370), P(7, 400)]),
)
LedGeometriesWithFrame300x300 = (
POLY([P(37, 30), P(263, 30), P(233, 60), P(67, 60), P(37, 30)]),
POLY([P(30, 37), P(60, 67), P(60, 128), P(30, 143), P(30, 37)]),
POLY([P(270, 37), P(240, 67), P(240, 128), P(270, 143), P(270, 37)]),
POLY(
[
P(37, 150),
P(67, 135),
P(233, 135),
P(263, 150),
P(233, 165),
P(67, 165),
P(37, 150),
]
),
POLY([P(30, 157), P(60, 172), P(60, 233), P(30, 263), P(30, 157)]),
POLY(
[P(270, 157), P(240, 172), P(240, 233), P(270, 263), P(270, 157)]
),
POLY([P(37, 270), P(263, 270), P(233, 240), P(67, 240), P(37, 270)]),
)
LedGeometriesWithoutFrame300x300 = (
POLY([P(7, 0), P(293, 0), P(263, 30), P(37, 30), P(7, 0)]),
POLY([P(0, 7), P(30, 37), P(30, 128), P(0, 143), P(0, 7)]),
POLY([P(300, 7), P(270, 37), P(270, 128), P(300, 143), P(300, 7)]),
POLY(
[
P(7, 150),
P(37, 135),
P(263, 135),
P(293, 150),
P(263, 165),
P(37, 165),
P(7, 150),
]
),
POLY([P(0, 157), P(30, 172), P(30, 263), P(0, 293), P(0, 157)]),
POLY(
[P(300, 157), P(270, 172), P(270, 263), P(300, 293), P(300, 157)]
),
POLY([P(7, 300), P(293, 300), P(263, 270), P(37, 270), P(7, 300)]),
)
DftLedOnPenColor = Qt.QColor(193, 0, 0, 255)
DftLedOnBgColor = Qt.Qt.red
DftLedOffPenColor = Qt.QColor(30, 30, 30, 255)
DftLedOffBgColor = Qt.QColor(40, 40, 40, 255)
DftBgBrush = Qt.QBrush(Qt.Qt.black, Qt.Qt.SolidPattern)
DftLedPenWidth = 5
DftValue = ""
DftWidth = 300
DftHeight = 300
DftAspectRatio = DftWidth // DftHeight
DftUseFrame = True
def __init__(self, parent=None, **kwargs):
Qt.QWidget.__init__(self, parent)
self._setLedPenWidth(Q7SegDigit.DftLedPenWidth)
self._setValue(Q7SegDigit.DftValue)
self._setLedOnPenColor(Q7SegDigit.DftLedOnPenColor)
self._setLedOnBgColor(Q7SegDigit.DftLedOnBgColor)
self._setLedOffPenColor(Q7SegDigit.DftLedOffPenColor)
self._setLedOffBgColor(Q7SegDigit.DftLedOffBgColor)
self._setBgBrush(Q7SegDigit.DftBgBrush)
self._setAspectRatio(Q7SegDigit.DftAspectRatio)
self._setUseFrame(Q7SegDigit.DftUseFrame)
self._updatePensAndBrushes()
[docs]
def minimumSizeHint(self):
return Qt.QSize(4, 5.9)
[docs]
def sizeHint(self):
# return Qt.QSize(Q7SegDigit.DftWidth, Q7SegDigit.DftHeight)
return Qt.QSize(40, 50)
def _updatePensAndBrushes(self):
pon = Qt.QPen(
self._ledOnPenColor,
self._ledPenWidth,
Qt.Qt.SolidLine,
Qt.Qt.RoundCap,
Qt.Qt.RoundJoin,
)
poff = Qt.QPen(
self._ledOffPenColor,
self._ledPenWidth,
Qt.Qt.SolidLine,
Qt.Qt.RoundCap,
Qt.Qt.RoundJoin,
)
bon = Qt.QBrush(self._ledOnBgColor, Qt.Qt.SolidPattern)
boff = Qt.QBrush(self._ledOffBgColor, Qt.Qt.SolidPattern)
pens, brushes = [], []
for nLeds in Q7SegDigit.Leds:
nPens = []
nBrushes = []
for onoff in nLeds:
if onoff:
pen, brush = pon, bon
else:
pen, brush = poff, boff
nPens.append(pen)
nBrushes.append(brush)
pens.append(nPens)
brushes.append(nBrushes)
self._pens, self._brushes = pens, brushes
self.update()
def __valueStrToLedIndex(self, s):
if s is None:
s = 10
elif s == "-":
s = 11
elif s == "a":
s = 12
elif s == "n":
s = 13
else:
try:
s = int(s)
except Exception:
s = 10
return s
[docs]
def paintEvent(self, evt):
painter = Qt.QPainter(self)
painter.setRenderHint(Qt.QPainter.Antialiasing)
painter.setWindow(0, 0, self.DftWidth, self.DftHeight)
w, h = float(self.width()), float(self.height())
aspect = w / h
if aspect > 0.75:
w = h * aspect
else:
h = w / aspect
painter.setViewport(0, 0, w, h)
self._paintBorder(painter)
self._paintSegment(painter)
def _paintBorder(self, painter):
if self.getUseFrame():
painter.setPen(
Qt.QPen(
Qt.Qt.black,
2,
Qt.Qt.SolidLine,
Qt.Qt.RoundCap,
Qt.Qt.RoundJoin,
)
)
linGrad = Qt.QLinearGradient(30, 200, 200, 150)
linGrad.setColorAt(0, Qt.Qt.darkGray)
linGrad.setColorAt(1, Qt.Qt.white)
linGrad.setSpread(Qt.QGradient.ReflectSpread)
painter.setBrush(linGrad)
border2 = Qt.QRectF(0, 0, self.DftWidth, self.DftHeight)
painter.drawRoundRect(border2, 10, 10)
painter.setBrush(self.getBgBrush())
dist = 20
border1 = Qt.QRectF(
dist, dist, self.DftWidth - 2 * dist, self.DftHeight - 2 * dist
)
painter.drawRoundRect(border1, 5, 5)
else:
painter.setBrush(self.getBgBrush())
border1 = Qt.QRectF(0, 0, self.DftWidth, self.DftHeight)
painter.drawRect(border1)
def _paintSegment(self, painter):
idx = self.__valueStrToLedIndex(self._value)
if self.getUseFrame():
if self.DftHeight == 300:
geom = self.LedGeometriesWithFrame300x300
else:
geom = self.LedGeometriesWithFrame300x400
else:
if self.DftHeight == 300:
geom = self.LedGeometriesWithoutFrame300x300
else:
geom = self.LedGeometriesWithoutFrame300x400
pens, brushes = self._pens[idx], self._brushes[idx]
for i in range(7):
seg = Qt.QPainterPath()
seg.addPolygon(geom[i])
painter.setPen(pens[i])
painter.setBrush(brushes[i])
painter.drawPath(seg)
def __str__(self):
_, idx = "", self.__valueStrToLedIndex(self._value)
leds = self.Leds[idx]
# line 0
c = " "
if leds[0]:
c = "_"
ret = " %c \n" % c
# line 1
c1, c2, c3 = " ", " ", " "
if leds[1]:
c1 = "|"
if leds[3]:
c2 = "_"
if leds[2]:
c3 = "|"
ret += "%c%c%c\n" % (c1, c2, c3)
# line 2
c1, c2, c3 = " ", " ", " "
if leds[4]:
c1 = "|"
if leds[6]:
c2 = "_"
if leds[5]:
c3 = "|"
ret += "%c%c%c" % (c1, c2, c3)
return ret
def _setValue(self, n):
if n is None:
self._value = n
else:
self._value = str(n)
def _setLedPenWidth(self, w):
self._ledPenWidth = w
def _setLedOnPenColor(self, penColor):
self._ledOnPenColor = penColor
def _setLedOnBgColor(self, bgColor):
self._ledOnBgColor = bgColor
def _setLedOffPenColor(self, penColor):
self._ledOffPenColor = penColor
def _setLedOffBgColor(self, bgColor):
self._ledOffBgColor = bgColor
def _setAspectRatio(self, aspectRatio):
self._aspectRatio = aspectRatio
def _setBgBrush(self, bgBrush):
if isinstance(bgBrush, Qt.QColor):
bgBrush = Qt.QBrush(bgBrush, Qt.Qt.SolidPattern)
self._bgBrush = bgBrush
def _setUseFrame(self, useFrame):
self._useFrame = useFrame
[docs]
def getLedOnPenColor(self):
return self._ledOnPenColor
[docs]
def setLedOnPenColor(self, penColor):
self._setLedOnPenColor(penColor)
self._updatePensAndBrushes()
[docs]
def resetLedOnPenColor(self):
self.setLenOnPenColor(Q7SegDigit.DftLedOnPenColor)
[docs]
def getLedOnBgColor(self):
return self._ledOnBgColor
[docs]
def setLedOnBgColor(self, bgColor):
self._setLedOnBgColor(bgColor)
self._updatePensAndBrushes()
[docs]
def resetLedOnBgColor(self):
self.setLedOnBgColor(Q7SegDigit.DftLedOnBgColor)
[docs]
def getLedOffPenColor(self):
return self._ledOffPenColor
[docs]
def setLedOffPenColor(self, penColor):
self._setLedOffPenColor(penColor)
self._updatePensAndBrushes()
[docs]
def resetLedOffPenColor(self):
self.setLenOffPenColor(Q7SegDigit.DftLedOffPenColor)
[docs]
def getLedOffBgColor(self):
return self._ledOffBgColor
[docs]
def setLedOffBgColor(self, bgColor):
self._setLedOffBgColor(bgColor)
self._updatePensAndBrushes()
[docs]
def resetLedOffBgColor(self):
self.setLedOffBgColor(Q7SegDigit.DftLedOffBgColor)
[docs]
def getBgBrush(self):
return self._bgBrush
[docs]
def setBgBrush(self, bgBrush):
self._setBgBrush(bgBrush)
self.update()
[docs]
def resetBgBrush(self):
self.setBgBrush(Q7SegDigit.DftBgBrush)
[docs]
def setValue(self, n):
self._setValue(n)
self.update()
[docs]
def getValue(self):
return self._value
[docs]
def resetValue(self):
self.setValue(Q7SegDigit.DftValue)
[docs]
def setLedPenWidth(self, w):
self._setLedPenWidth(w)
self._updatePensAndBrushes()
[docs]
def getLedPenWidth(self):
return self._ledPenWidth
[docs]
def resetLedPenWidth(self):
self.setLedPenWidth(Q7SegDigit.DftLenPenWidth)
[docs]
def setAspectRatio(self, apectRatio):
self._setAspectRatio(apectRatio)
self.update()
[docs]
def getAspectRatio(self):
return self._aspectRatio
[docs]
def resetAspectRatio(self):
self.setAspectRatio(Q7SegDigit.DftAspectRatio)
[docs]
def setUseFrame(self, useFrame):
self._setUseFrame(useFrame)
[docs]
def getUseFrame(self):
return self._useFrame
[docs]
def resetUseFrame(self):
self.setUseFrame(Q7SegDigit.DftUseFrame)
#: This property holds the led pen color when the led is light ON
#:
#: **Access functions:**
#:
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.getLedOnPenColor`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.setLedOnPenColor`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.resetLedOnPenColor`
#:
ledOnPenColor = Qt.pyqtProperty(
"QColor", getLedOnPenColor, setLedOnPenColor, resetLedOnPenColor
)
#: This property holds the led background color when the led is light ON
#:
#: **Access functions:**
#:
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.getLedOnBgColor`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.setLedOnBgColor`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.resetLedOnBgColor`
#:
ledOnBgColor = Qt.pyqtProperty(
"QColor", getLedOnBgColor, setLedOnBgColor, resetLedOnBgColor
)
#: This property holds the led pen color when the led is light OFF
#:
#: **Access functions:**
#:
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.getLedOffPenColor`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.setLedOffPenColor`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.resetLedOffPenColor`
#:
ledOffPenColor = Qt.pyqtProperty(
"QColor", getLedOffPenColor, setLedOffPenColor, resetLedOffPenColor
)
#: This property holds the led background color when the led is light OFF
#:
#: **Access functions:**
#:
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.getLedOffBgColor`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.setLedOffBgColor`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.resetLedOffBgColor`
#:
ledOffBgColor = Qt.pyqtProperty(
"QColor", getLedOffBgColor, setLedOffBgColor, resetLedOffBgColor
)
#: This property holds the background brush
#:
#: **Access functions:**
#:
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.getBgBrush`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.setBgBrush`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.resetBgBrush`
#:
bgBrush = Qt.pyqtProperty("QBrush", getBgBrush, setBgBrush, resetBgBrush)
#: This property holds the pen width
#:
#: **Access functions:**
#:
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.getLedPenWidth`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.setLedPenWidth`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.resetLedPenWidth`
#:
ledPenWidth = Qt.pyqtProperty(
"int", getLedPenWidth, setLedPenWidth, resetLedPenWidth
)
#: This property holds wheater of not to draw a frame
#:
#: **Access functions:**
#:
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.getUseFrame`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.setUseFrame`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.resetUseFrame`
#:
useFrame = Qt.pyqtProperty("bool", getUseFrame, setUseFrame, resetUseFrame)
#: This property holds the widget value
#:
#: **Access functions:**
#:
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.getValue`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.setValue`
#: * :meth:`taurus.qt.qtgui.display.Q7SegDigit.resetValue`
#:
value = Qt.pyqtProperty("QString", getValue, setValue, resetValue)
class Q7SegDisplay(Qt.QWidget):
def __init__(self, qt_parent=None):
Qt.QWidget.__init__(self, qt_parent)
self.__init()
def __init(self):
lyt = Qt.QHBoxLayout()
lyt.setSpacing(10)
lyt.setContentsMargins(5, 5, 5, 5)
self.setLayout(lyt)
self._digits = []
for i in range(5):
d = Q7SegDigit()
d.setUseFrame(False)
d.setValue(i)
lyt.addWidget(d, 0)
self._digits.append(d)
self.setAutoFillBackground(True)
palette = Qt.QPalette()
brush = Qt.QBrush(Qt.Qt.black)
palette.setBrush(Qt.QPalette.Active, Qt.QPalette.Window, brush)
self.setPalette(palette)
def __setBgBrush():
global digitWidget
color = Qt.QColorDialog.getColor(Qt.Qt.red)
if color.isValid():
digitWidget.setBgBrush(color)
def __setLedOnPenColor():
global digitWidget
color = Qt.QColorDialog.getColor(Qt.Qt.red)
if color.isValid():
digitWidget.setLedOnPenColor(color)
def __setLedOnBgColor():
global digitWidget
color = Qt.QColorDialog.getColor(Qt.Qt.red)
if color.isValid():
digitWidget.setLedOnBgColor(color)
def __setLedOffPenColor():
global digitWidget
color = Qt.QColorDialog.getColor(Qt.Qt.red)
if color.isValid():
digitWidget.setLedOffPenColor(color)
def __setLedOffBgColor():
global digitWidget
color = Qt.QColorDialog.getColor(Qt.Qt.red)
if color.isValid():
digitWidget.setLedOffBgColor(color)
def main1():
import sys
a = Qt.QApplication([])
panel = Qt.QWidget()
lyt = Qt.QHBoxLayout(panel)
digitWidget = Q7SegDigit()
digitWidget.setValue(int(sys.argv[1]))
lyt.addWidget(digitWidget)
lyt.addWidget(Q7SegDigit())
lyt.addWidget(Q7SegDigit())
lyt.setSpacing(0)
panel.setVisible(True)
a.exec_()
def main2():
import sys
a = Qt.QApplication([])
dw = Q7SegDigit()
dw.setValue(int(sys.argv[1]))
dw.setVisible(True)
print(dw)
a.exec_()
def main3():
a = Qt.QApplication([])
dw = Q7SegDisplay()
# dw.setValue(int(sys.argv[1]))
dw.setVisible(True)
a.exec_()
def main():
global digitWidget
a = Qt.QApplication([])
panel = Qt.QWidget()
lyt = Qt.QFormLayout(panel)
digitWidget = Q7SegDigit()
digitWidget.setStyleSheet("background-color:red;")
valueLineEdit = Qt.QLineEdit(digitWidget.getValue())
valueLineEdit.setMaxLength(1)
ledPenWidthWidget = Qt.QSpinBox()
ledPenWidthWidget.setRange(0, 20)
ledPenWidthWidget.setValue(digitWidget.getLedPenWidth())
bgBrushWidget = Qt.QPushButton("Bg brush")
LedOnPenColor = Qt.QPushButton("ON pen color")
LedOnBgColor = Qt.QPushButton("ON bg color")
LedOffPenColor = Qt.QPushButton("OFF pen color")
LedOffBgColor = Qt.QPushButton("OFF bg color")
lyt.addRow("Value", digitWidget)
lyt.addRow("Digit", valueLineEdit)
lyt.addRow("Pen width", ledPenWidthWidget)
lyt.addRow(bgBrushWidget)
lyt.addRow(LedOnPenColor)
lyt.addRow(LedOnBgColor)
lyt.addRow(LedOffPenColor)
lyt.addRow(LedOffBgColor)
valueLineEdit.textChanged.connect(digitWidget.setValue)
ledPenWidthWidget.valueChanged.connect(digitWidget.setLedPenWidth)
bgBrushWidget.clicked.connect(__setBgBrush)
LedOnPenColor.clicked.connect(__setLedOnPenColor)
LedOnBgColor.clicked.connect(__setLedOnBgColor)
LedOffPenColor.clicked.connect(__setLedOffPenColor)
LedOffBgColor.clicked.connect(__setLedOffBgColor)
panel.setVisible(True)
a.exec_()
if __name__ == "__main__":
main3()