#!/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 an arrow based widget."""
__all__ = ["QWheelEdit"]
__docformat__ = 'restructuredtext'
import os
import math
import numpy
from taurus.external.qt import Qt
from taurus.external.pint import Q_
class _ArrowButton(Qt.QPushButton):
"""Private class to be used by QWheelEdit for an arrow button"""
ArrowPixmapName = "extra_icons:arrow01.svg"
ButtonSize = 14
IconSize = ButtonSize - 2
def __init__(self, id, parent=None):
Qt.QPushButton.__init__(self, parent)
self.setAutoDefault(False)
pixmap = self.getPixmap()
self.setIcon(Qt.QIcon(pixmap))
self.setIconSize(
Qt.QSize(_ArrowButton.IconSize, _ArrowButton.IconSize))
self.setFocusPolicy(Qt.Qt.ClickFocus)
self.setFlat(True)
self.setStyleSheet('_ArrowButton { border: 0px; }')
self.setMaximumSize(_ArrowButton.ButtonSize, _ArrowButton.ButtonSize)
#self.setMinimumSize(_ArrowButton.ButtonSize, _ArrowButton.ButtonSize)
self._id = id
self._inc = math.pow(10, id)
class _UpArrowButton(_ArrowButton):
"""Private class to be used by QWheelEdit for an up arrow button"""
ArrowPixmapKey = "upArrow01"
def __init__(self, id, parent=None):
_ArrowButton.__init__(self, id, parent)
def getPixmap(self):
pm = Qt.QPixmapCache.find(_UpArrowButton.ArrowPixmapKey)
if pm is None:
pm = Qt.QPixmap(self.ArrowPixmapName)
Qt.QPixmapCache.insert(_UpArrowButton.ArrowPixmapKey, pm)
return pm
class _DownArrowButton(_ArrowButton):
"""Private class to be used by QWheelEdit for a down arrow button"""
ArrowPixmapKey = "downArrow01"
def __init__(self, id, parent=None):
_ArrowButton.__init__(self, id, parent)
self._inc = -self._inc
def getPixmap(self):
pm = Qt.QPixmapCache.find(_DownArrowButton.ArrowPixmapKey)
if pm is None:
pm = Qt.QPixmap(self.ArrowPixmapName)
pm = pm.transformed(Qt.QMatrix().rotate(180))
Qt.QPixmapCache.insert(_DownArrowButton.ArrowPixmapKey, pm)
return pm
class _DigitLabel(Qt.QLabel):
"""A private single digit label to be used by QWheelEdit widget"""
PixmapKeys = map(str, xrange(10)) + ['blank', 'minus', 'point']
def __init__(self, lbl, parent=None):
Qt.QLabel.__init__(self, parent)
self.setAlignment(Qt.Qt.AlignCenter)
self.setFocusPolicy(Qt.Qt.StrongFocus)
self.setStyleSheet(
"""QLabel:focus {background-color: rgb(180,180,255); border-width: 1px; border-style: solid; border-color: rgb(200,200,255);}""")
self.resetSkin()
self.setText(lbl)
self._upButton = None
self._downButton = None
def setButtons(self, up, down):
self._upButton = up
self._downButton = down
def keyPressEvent(self, key_event):
if key_event.key() == Qt.Qt.Key_Up:
self._upButton.click()
elif key_event.key() == Qt.Qt.Key_Down:
self._downButton.click()
elif key_event.key() == Qt.Qt.Key_Right:
self.focusNextChild()
elif key_event.key() == Qt.Qt.Key_Left:
self.focusPreviousChild()
Qt.QLabel.keyPressEvent(self, key_event)
def _update_skin_cache(self):
skin = os.path.join('digits', self.getSkin())
for i, d in enumerate(self.PixmapKeys):
full_name = os.path.join(skin, d)
pm = Qt.QPixmapCache.find(full_name)
if pm is None:
file_name = '%s.png' % full_name
pm = Qt.QPixmap(file_name)
if pm is None:
continue
if not pm.isNull():
Qt.QPixmapCache.insert(full_name, pm)
def setSkin(self, skin_name):
self._skin = skin_name
self._update_skin_cache()
self.update()
def getSkin(self):
return self._skin
def resetSkin(self):
self.setSkin('Nixie')
def setText(self, t):
k = t
if k == '.':
k = 'point'
elif k == '-':
k = 'minus'
elif k is None or k == '+':
k = 'blank'
k = os.path.join('digits', self.getSkin(), k)
pm = Qt.QPixmapCache.find(k)
if pm is None:
Qt.QLabel.setText(self, t)
return
Qt.QLabel.setText(self, '')
self.setPixmap(pm)
skin = Qt.pyqtProperty('QString', getSkin, setSkin, resetSkin)
class _NumericEditor(Qt.QLineEdit):
"""A private editor to be used by QWheelEdit widget"""
def __init__(self, parent=None):
Qt.QLineEdit.__init__(self, parent)
self.setValidator(Qt.QDoubleValidator(self))
self.setFrame(False)
[docs]class QWheelEdit(Qt.QFrame):
"""A widget designed to handle numeric scalar values. It allows interaction
based on single digit as well as normal value edition."""
numberChanged = Qt.pyqtSignal(float)
numberEdited = Qt.pyqtSignal(float)
returnPressed = Qt.pyqtSignal()
DefaultIntDigitCount = 6
DefaultDecDigitCount = 2
def __init__(self, parent=None):
"""__init__(self, parent = None) -> QWheelEdit
Constructor
@param[in] parent (QWidget) the parent widget (optional, default is None
meaning there is no parent
"""
Qt.QFrame.__init__(self, parent)
Qt.QGridLayout(self)
self._roundFunc = None
self._previous_value = 0
self._value = 0
self._value_str = '0'
self._minValue = numpy.finfo('d').min # -inf
self._maxValue = numpy.finfo('d').max # inf
self._editor = None
self._editing = False
self._showArrowButtons = True
self._setDigits(QWheelEdit.DefaultIntDigitCount,
QWheelEdit.DefaultDecDigitCount)
self._setValue(0)
self._build()
def _getMinPossibleValue(self):
"""_getMinPossibleValue(self) -> None
Determines which is the minimum possible value that can be represented
with the current total number of digits.
@return (float) the minimum possible value
"""
decmax = 0
for i in xrange(self.getDecDigitCount()):
decmax += 9 * math.pow(10, -(i + 1))
return -math.pow(10.0, self.getIntDigitCount()) + 1 - decmax
def _getMaxPossibleValue(self):
"""_getMaxPossibleValue(self) -> None
Determines which is the maximum possible value that can be represented
with the current total number of digits.
@return (float) the maximum possible value
"""
decmax = 0
for i in xrange(self.getDecDigitCount()):
decmax += 9 * math.pow(10, -(i + 1))
return math.pow(10.0, self.getIntDigitCount()) - 1 + decmax
def _build(self):
"""_build(self) -> None
Builds this widget sub-items"""
l = self.layout()
l.setSpacing(0)
l.setMargin(0)
id = self.getIntDigitCount()
dd = self.getDecDigitCount()
digits = self.getDigitCount()
self._upButtons = Qt.QButtonGroup()
self._downButtons = Qt.QButtonGroup()
self._digitLabels = []
for l in self._digitLabels:
l.setAlignment(Qt.AlignCenter)
showDot = self.getDecDigitCount() > 0
signLabel = _DigitLabel('+')
signLabel.setFocusPolicy(Qt.Qt.NoFocus)
signLabel.setAlignment(Qt.Qt.AlignRight | Qt.Qt.AlignVCenter)
self._digitLabels.append(signLabel)
l.addWidget(signLabel, 1, 0)
l.setRowMinimumHeight(1, signLabel.minimumSizeHint().height())
l.setColumnMinimumWidth(0, _ArrowButton.ButtonSize)
l.setColumnStretch(0, 1)
for i in xrange(id):
col = i + 1
d = _DigitLabel('0')
up = _UpArrowButton(id - i - 1)
down = _DownArrowButton(id - i - 1)
d.setButtons(up, down)
up.setFocusProxy(d)
down.setFocusProxy(d)
self._upButtons.addButton(up, col)
self._downButtons.addButton(down, col)
self._digitLabels.append(d)
if self.getShowArrowButtons():
l.addWidget(up, 0, col)
l.addWidget(down, 2, col)
l.addWidget(d, 1, col)
if showDot:
dotLabel = _DigitLabel('.')
dotLabel.setFocusPolicy(Qt.Qt.NoFocus)
dotLabel.setAlignment(Qt.Qt.AlignCenter)
self._digitLabels.append(dotLabel)
l.addWidget(dotLabel, 1, id + 1)
for i in xrange(id, digits):
col = i + 1
if showDot:
col += 1
d = _DigitLabel('0')
up = _UpArrowButton(id - i - 1)
down = _DownArrowButton(id - i - 1)
d.setButtons(up, down)
up.setFocusProxy(d)
down.setFocusProxy(d)
self._upButtons.addButton(up, col)
self._downButtons.addButton(down, col)
self._digitLabels.append(d)
if self.getShowArrowButtons():
l.addWidget(up, 0, col)
l.addWidget(down, 2, col)
l.addWidget(d, 1, col)
self._upButtons.buttonClicked.connect(self.buttonPressed)
self._downButtons.buttonClicked.connect(self.buttonPressed)
ed = _NumericEditor(self)
ed.returnPressed.connect(self.editingFinished)
ed.lostFocus.connect(ed.hide)
rect = Qt.QRect(l.cellRect(1, 0).topLeft(), l.cellRect(1,
l.columnCount() - 1).bottomRight())
ed.setGeometry(rect)
ed.setAlignment(Qt.Qt.AlignRight)
ed.validator().setRange(self.getMinValue(), self.getMaxValue(),
self.getDecDigitCount())
ed.setVisible(False)
self._editor = ed
self.clearWarning()
def _clear(self):
"""_clear(self) -> None
Clears this widget sub-items"""
self._upButtons.buttonClicked.disconnect(self.buttonPressed)
self._downButtons.buttonClicked.disconnect(self.buttonPressed)
for b in self._upButtons.buttons():
self._upButtons.removeButton(b)
b.setParent(None)
b.destroy()
for b in self._downButtons.buttons():
self._downButtons.removeButton(b)
b.setParent(None)
b.destroy()
for label in self._digitLabels:
label.setParent(None)
label.destroy()
self._digitLabels = None
self._upButtons.setParent(None)
self._downButtons.setParent(None)
self._upButtons = None
self._downButtons = None
self._editor.setParent(None)
self._editor.destroy()
self._editor = None
def _setMinMax(self, min, max):
"""_setMinMax(self, min, max) -> None
Sets the minimum and maximum values for this widget
@param[in] min(float) minimum value
@param[in] max(float) maximum value
"""
self._minValue = min
self._maxValue = max
def _setDigits(self, int_nb=None, dec_nb=None):
"""_setDigits(self, int_nb=None, dec_nb=None) -> None
Sets the number of digits that this widget shows. It will ensure that
the current value can be displayed (i.e., int_nb will be forced to be
large enough for displaying the integer representation of the value)
@param[in] int_nb (int) number of integer digits (optional, default is
None, meaning use the existing number of integer digits
@param[in] dec_nb (int) number of decimal digits (optional, default is
None, meaning use the existing number of decimal digits
"""
if not int_nb is None:
self._intDigitCount = int_nb
if not dec_nb is None:
self._decDigitCount = dec_nb
# make sure that the current value can be displayed
self._intDigitCount = max(self._intDigitCount, len("%d" % self._value))
self._digitCount = self._intDigitCount + self._decDigitCount
total_chars = self._digitCount
total_chars += 1 # for sign
if self._decDigitCount > 0:
total_chars += 1 # for dot
self._valueFormat = '%%+0%d.%df' % (total_chars, self._decDigitCount)
self._setMinMax(self._getMinPossibleValue(),
self._getMaxPossibleValue())
# we call setValue to update the self._value_str
self._setValue(self.getValue())
def _buildValueStr(self, v):
"""_buildValueStr(self, v) -> str
Builds a string representation of the given value according to the
number of digits this widget can currently represent
@param[in] v (float) the value to be translated
@return (str) a proper string representation of the given value
"""
if v is None:
ret = (self._valueFormat % 0).replace('0', '-')
else:
ret = self._valueFormat % v
if ret.endswith('nan'):
ret = ret.replace('0', ' ')
self._value_str = ret
return ret
def _updateDigits(self):
"""_updateDigits(self) -> None
Updates this widget contents (sub-widgets) according to the current
widget configuration
"""
self._clear()
self._build()
self._updateValue(False, False)
def _updateValue(self, trigValueChanged=True, trigValueEdited=True):
"""_updateValue(self, trigValueChanged=True, trigValueEdited=True) -> None
Updates this widget displayed value and potentially send signal(s)
@param[in] trigValueChanged (bool) (optional, default is True) wheather or
not to send signal 'valueChanged(double)'
@param[in] trigValueEdited (bool) (optional, default is True) wheather or
not to send signal 'valueEdit(double)'
"""
v, v_str = self.getValue(), self.getValueStr()
if len(v_str) > len(self._digitLabels):
# do auto adjust
if '.' in v_str:
dc = map(len, v_str.split('.'))
else:
dc = len(v_str), 0
self._setDigits(*dc)
v_str = self._buildValueStr(v)
self._clear()
self._build()
for i, c in enumerate(v_str):
self._digitLabels[i].setText(c)
if trigValueChanged:
self.numberChanged.emit(v)
if trigValueEdited:
self.numberEdited.emit(v)
[docs] def setRoundFunc(self, roundFunc):
"""setRoundFunc(self, roundFunc) -> None
Sets the rounding function to use when calling _setValue(). This allows you to
filter invalid user input
@param[in] roundFunc (callable) the rounding function to use
"""
self._roundFunc = roundFunc
[docs] def getPreviousValue(self):
"""getPreviousValue(self) -> float
Gives the previous value of this widget
@return (float) the previous value of this widget
"""
return self._previous_value
def _setValue(self, v):
"""_setValue(self, v) -> None
Sets value of this widget. If the given value exceeds any limit, the
value is NOT set.
"""
if self._roundFunc:
v = self._roundFunc(v)
if v > self._maxValue or v < self._minValue:
return
self._previous_value = self._value
self._value = v
self._buildValueStr(v)
[docs] def setWarning(self, msg):
"""setWarning(self, msg) -> None
Activates the warning style for this widget. This means a violet border
and a tooltip with the given message.
@param[in] msg (str) the message to be displayed as tooltip
"""
self.setStyleSheet(
'QWheelEdit {border: 1px solid; border-radius: 4px; border-color: violet}')
self.setToolTip(msg)
[docs] def clearWarning(self):
"""clearWarning(self) -> None
Clears the warning style. If not in warning mode, nothing is done.
"""
self.setStyleSheet(
'QWheelEdit {border: 1px solid; border-radius: 4px; border-color: rgba(0,0,0,0)}')
self.setToolTip('')
[docs] def setDigitCount(self, int_nb, dec_nb):
"""setDigitCount(self, int_nb, dec_nb) -> None
Updates the displayed digits.
@param[in] int_nb(int) number of integer digits
@param[in] dec_nb(int) number of decimal digits
"""
self._setDigits(int_nb=int_nb, dec_nb=dec_nb)
self._updateDigits()
[docs] def getDigitCount(self):
"""getDigitCount(self) -> int
Gets the total number of digits this widget displays
@return (int) the total number of digits this widget displays
"""
return self._digitCount
[docs] def getIntDigitCount(self):
"""getIntDigitCount(self) -> int
Gets the number of integer digits this widget displays
@return (int) the number of integer digits this widget displays
"""
return self._intDigitCount
[docs] def setIntDigitCount(self, n):
"""setIntDigitCount(self, n) -> None
Sets the number of integer digits this widget displays
@param[in] n (int) the number of integer digits to display
"""
self._setDigits(int_nb=n)
self._updateDigits()
[docs] def resetIntDigitCount(self):
"""resetIntDigitCount(self) -> None
Resets the number of integer digits this widget displays to DefaultIntDigitCount
"""
self.setIntDigitCount(QWheelEdit.DefaultIntDigitCount)
[docs] def getDecDigitCount(self):
"""getDecDigitCount(self) -> int
Gets the number of decimal digits this widget displays
@return (int) the number of decimal digits this widget displays
"""
return self._decDigitCount
[docs] def setDecDigitCount(self, n):
"""setDecDigitCount(self, n) -> None
Sets the number of decimal digits this widget displays
@param[in] n (int) the number of decimal digits to display
"""
self._setDigits(dec_nb=n)
self._updateDigits()
[docs] def resetDecDigitCount(self):
"""resetDecDigitCount(self) -> None
Resets the number of decimal digits this widget displays to DefaultDecDigitCount
"""
self.setDecDigitCount(QWheelEdit.DefaultDecDigitCount)
[docs] def setValue(self, v):
"""setValue(self, v) -> None
Sets the value of this widget.
Send a 'valueChanged(double)' Qt signal
@param[in] v (float/Quantity) the value to be set
"""
if isinstance(v, Q_):
v = v.magnitude
self._setValue(v)
self._updateValue(trigValueEdited=False)
[docs] def resetValue(self):
"""resetValue(self) -> None
Resets the value of this widget to 0.0
"""
self.setValue(0.0)
[docs] def getValue(self):
"""getValue(self) -> float
Gets the current value of this widget
@return (float) the value currently displayed by the widget
"""
return self._value
[docs] def getValueStr(self):
"""getValueStr(self) -> str
Gets the current value string of this widget
@return (str) the value currently displayed by the widget
"""
return self._value_str
[docs] def getMinValue(self):
"""getMinValue(self) -> float
Gets the minimum allowed value
@return (float) the minimum allowed value
"""
return self._minValue
[docs] def setMinValue(self, v):
"""setMinValue(self, v) -> None
Sets the minimum allowed value for the widget
@param[in] v (float) the new minimum allowed value
"""
self._minValue = v
w = self.getEditWidget()
if not w is None:
w.validator().setRange(self._minValue, self._maxValue, self._decDigitCount)
[docs] def resetMinValue(self):
"""resetMinValue(self) -> None
Resets the minimum allowed value to the minimum possible according to
the current total number of digits
"""
self.setMinValue(self._getMinPossibleValue())
[docs] def getMaxValue(self):
"""getMaxValue(self) -> float
Gets the maximum allowed value
@return (float) the maximum allowed value
"""
return self._maxValue
[docs] def setMaxValue(self, v):
"""setMaxValue(self, v) -> None
Sets the maximum allowed value for the widget
@param[in] v (float) the new maximum allowed value
"""
self._maxValue = v
w = self.getEditWidget()
if not w is None:
w.validator().setRange(self._minValue, self._maxValue, self._decDigitCount)
[docs] def resetMaxValue(self):
"""resetMaxValue(self) -> None
Resets the maximum allowed value to the maximum possible according to
the current total number of digits
"""
self.setMaxValue(self._getMaxPossibleValue())
[docs] def getAutoRepeat(self):
return self._upButtons.buttons()[0].autoRepeat()
[docs] def setAutoRepeat(self, v):
for b in self._upButtons.buttons():
b.setAutoRepeat(v)
for b in self._downButtons.buttons():
b.setAutoRepeat(v)
[docs] def resetAutoRepeat(self):
self.setAutoRepeat(False)
[docs] def getAutoRepeatDelay(self):
return self._upButtons.buttons()[0].autoRepeatDelay()
[docs] def setAutoRepeatDelay(self, milisecs):
for b in self._upButtons.buttons():
b.setAutoRepeatDelay(milisecs)
for b in self._downButtons.buttons():
b.setAutoRepeatDelay(milisecs)
[docs] def getAutoRepeatInterval(self):
return self._upButtons.buttons()[0].autoRepeatInterval()
[docs] def setAutoRepeatInterval(self, milisecs):
for b in self._upButtons.buttons():
b.setAutoRepeatInterval(milisecs)
for b in self._downButtons.buttons():
b.setAutoRepeatInterval(milisecs)
[docs] def editingFinished(self):
"""editingFinished(self) -> None
Slot called when the user finishes editing
"""
ed = self.getEditWidget()
v = float(ed.text())
self._setValue(v)
self._updateValue()
[docs] def wheelEvent(self, evt):
numDegrees = evt.delta() / 8
numSteps = numDegrees / 15
#w = Qt.QApplication.focusWidget()
w = self.focusWidget()
if not isinstance(w, _DigitLabel):
return Qt.QFrame.wheelEvent(self, evt)
if numSteps > 0:
inc = w._upButton._inc
else:
inc = -w._downButton._inc
numSteps *= inc
self.setValue(self.getValue() + numSteps)
evt.accept()
[docs] def mouseDoubleClickEvent(self, mouse_event):
"""mouseDoubleClickEvent(self, mouse_event)
Executed when user presses double click. This widget shows the edition
widget when this happens
"""
self.showEditWidget()
self._editing = True
[docs] def keyPressEvent(self, key_event):
"""keyPressEvent(self, key_event) -> None
Exectuted when the user presses a key.
F2 enters/leaves edition mode. ESC leaves edition mode
"""
k = key_event.key()
if k == Qt.Qt.Key_F2:
if self._editing:
self.hideEditWidget()
self._editing = False
else:
self.showEditWidget()
self._editing = True
return
elif k == Qt.Qt.Key_Escape:
if self._editing:
self.hideEditWidget()
self._editing = False
return
elif k in (Qt.Qt.Key_Return, Qt.Qt.Key_Enter):
if self._editing:
self.hideEditWidget()
self._editing = False
else:
self.returnPressed.emit()
# TODO Decide when to emit editingFinished for completeness
Qt.QWidget.keyPressEvent(self, key_event)
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
# QT properties
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
showArrowButtons = Qt.pyqtProperty("bool", getShowArrowButtons,
setShowArrowButtons,
resetShowArrowButtons)
integerDigits = Qt.pyqtProperty("int", getIntDigitCount,
setIntDigitCount, resetIntDigitCount)
decimalDigits = Qt.pyqtProperty("int", getDecDigitCount,
setDecDigitCount, resetDecDigitCount)
value = Qt.pyqtProperty("double", getValue,
setValue, resetValue)
minValue = Qt.pyqtProperty("double", getMinValue,
setMinValue, resetMinValue)
maxValue = Qt.pyqtProperty("double", getMaxValue,
setMaxValue, resetMaxValue)
autoRepeat = Qt.pyqtProperty("bool", getAutoRepeat,
setAutoRepeat, resetAutoRepeat)
autoRepeatDelay = Qt.pyqtProperty("int", getAutoRepeatDelay,
setAutoRepeatDelay)
autoRepeatInterval = Qt.pyqtProperty("int", getAutoRepeatInterval,
setAutoRepeatInterval)
def main():
global arrowWidget
def resetAll():
arrowWidget.resetIntDigitCount()
arrowWidget.resetDecDigitCount()
arrowWidget.resetMinValue()
arrowWidget.resetMaxValue()
arrowWidget.resetValue()
def setNAN():
arrowWidget.setValue(float('nan'))
def setNone():
arrowWidget.setValue(None)
a = Qt.QApplication([])
panel = Qt.QWidget()
l = Qt.QFormLayout(panel)
button_layout = Qt.QVBoxLayout()
arrowWidget = QWheelEdit(panel)
isb, dsb = Qt.QSpinBox(panel), Qt.QSpinBox(panel)
minv, maxv = Qt.QDoubleSpinBox(panel), Qt.QDoubleSpinBox(panel)
resetbutton = Qt.QPushButton("Reset", panel)
resetbutton.setDefault(True)
nanbutton = Qt.QPushButton("Set NAN", panel)
nonebutton = Qt.QPushButton("Set None", panel)
showarrowbutton = Qt.QCheckBox("", panel)
l.addRow("Value", arrowWidget)
l.addRow("Integer digits:", isb)
l.addRow("Decimal digits:", dsb)
l.addRow("Minimum value:", minv)
l.addRow("Maximum value:", maxv)
l.addRow("Show arrows:", showarrowbutton)
l.addRow(button_layout)
button_layout.addWidget(nanbutton)
button_layout.addWidget(nonebutton)
button_layout.addWidget(resetbutton)
isb.setValue(arrowWidget.getIntDigitCount())
dsb.setValue(arrowWidget.getDecDigitCount())
minv.setRange(numpy.finfo('d').min, numpy.finfo('d').max)
maxv.setRange(numpy.finfo('d').min, numpy.finfo('d').max)
minv.setValue(arrowWidget.getMinValue())
maxv.setValue(arrowWidget.getMaxValue())
showarrowbutton.setChecked(arrowWidget.getShowArrowButtons())
isb.valueChanged.connect(arrowWidget.setIntDigitCount)
dsb.valueChanged.connect(arrowWidget.setDecDigitCount)
minv.valueChanged.connect(arrowWidget.setMinValue)
showarrowbutton.stateChanged.connect(arrowWidget.setShowArrowButtons)
nanbutton.clicked.connect(setNAN)
nonebutton.clicked.connect(setNone)
resetbutton.clicked.connect(resetAll)
panel.setVisible(True)
a.exec_()
if __name__ == "__main__":
main()