608 lines
22 KiB
Python
608 lines
22 KiB
Python
#!/usr/bin/env python3
|
|
# qtVcp simple widgets
|
|
#
|
|
# Copyright (c) 2017 Chris Morley <chrisinnanaimo@hotmail.com>
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program 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 General Public License for more details.
|
|
|
|
import enum
|
|
from qtpy import QtCore, QtGui, QtWidgets
|
|
from qtpy.QtCore import Property, Slot
|
|
try:
|
|
from qtpy.QtCore import QEnum
|
|
except ImportError:
|
|
try:
|
|
from qtpy.QtCore import Q_ENUM as QEnum
|
|
except ImportError:
|
|
# before Qt 5.10
|
|
from qtpy.QtCore import Q_ENUMS as QEnum
|
|
from qtvcp.widgets.widget_baseclass import (_HalWidgetBase,
|
|
_HalToggleBase, _HalSensitiveBase, _HalScaleBase)
|
|
from qtvcp.widgets.indicatorMixIn import IndicatedMixIn
|
|
from qtvcp.lib.aux_program_loader import Aux_program_loader as _loader
|
|
from qtvcp.core import Action, Status, Info
|
|
import hal
|
|
|
|
AUX_PRGM = _loader()
|
|
ACTION = Action()
|
|
STATUS = Status()
|
|
INFO = Info()
|
|
|
|
# Set up logging
|
|
from qtvcp import logger
|
|
LOG = logger.getLogger(__name__)
|
|
|
|
# Force the log level for this module
|
|
#LOG.setLevel(logger.DEBUG) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
|
|
|
|
class HALPinType(enum.IntEnum):
|
|
NONE = 0
|
|
BIT = hal.HAL_BIT
|
|
S32 = hal.HAL_S32
|
|
FLOAT = hal.HAL_FLOAT
|
|
|
|
# reacts to HAL pin changes
|
|
class LCDNumber(QtWidgets.QLCDNumber, _HalWidgetBase):
|
|
def __init__(self, parent=None):
|
|
super(LCDNumber, self).__init__(parent)
|
|
self._floatTemplate = ''
|
|
self._bit_pin_type = False
|
|
self._s32_pin_type = False
|
|
self._float_pin_type = True
|
|
|
|
def _hal_init(self):
|
|
if self._pin_name_ == '':
|
|
pname = self.HAL_NAME_
|
|
else:
|
|
pname = self._pin_name_
|
|
if self._bit_pin_type:
|
|
self.hal_pin = self.HAL_GCOMP_.newpin(pname, hal.HAL_BIT, hal.HAL_IN)
|
|
self.hal_pin.value_changed.connect(lambda data: self.updateDisplay(data))
|
|
elif self._float_pin_type:
|
|
self.hal_pin = self.HAL_GCOMP_.newpin(pname, hal.HAL_FLOAT, hal.HAL_IN)
|
|
self.hal_pin.value_changed.connect(lambda data: self.updateFloatDisplay(data))
|
|
elif self._s32_pin_type:
|
|
self.hal_pin = self.HAL_GCOMP_.newpin(pname, hal.HAL_S32, hal.HAL_IN)
|
|
self.hal_pin.value_changed.connect(lambda data: self.updateDisplay(data))
|
|
|
|
def updateDisplay(self, data):
|
|
self.display(data)
|
|
|
|
def updateFloatDisplay(self, data):
|
|
try:
|
|
if self._floatTemplate == '':
|
|
self.updateDisplay(data)
|
|
return
|
|
t = lambda s: self._floatTemplate % s
|
|
self.display(t(data))
|
|
except:
|
|
self.display('{:.2f}'.format(data))
|
|
LOG.warning("(LCDNumber) Float formatting string: {} not valid-using {}".format(
|
|
self._floatTemplate, '{:.2f}'))
|
|
|
|
#########################################################################
|
|
# This is how designer can interact with our widget properties.
|
|
# designer will show the Property properties in the editor
|
|
# it will use the get set and reset calls to do those actions
|
|
########################################################################
|
|
|
|
def _toggle_properties(self, picked):
|
|
data = ('bit', 's32', 'float')
|
|
|
|
for i in data:
|
|
if not i == picked:
|
|
self[i+'_pin_type'] = False
|
|
|
|
def set_pin_name(self, value):
|
|
self._pin_name_ = value
|
|
def get_pin_name(self):
|
|
return self._pin_name_
|
|
def reset_pin_name(self):
|
|
self._pin_name_ = ''
|
|
|
|
def set_bit_pin_type(self, value):
|
|
self._bit_pin_type = value
|
|
if value:
|
|
self._toggle_properties('bit')
|
|
def get_bit_pin_type(self):
|
|
return self._bit_pin_type
|
|
def reset_bit_pin_type(self):
|
|
self._bit_pin_type = ''
|
|
|
|
def set_s32_pin_type(self, value):
|
|
self._s32_pin_type = value
|
|
if value:
|
|
self._toggle_properties('s32')
|
|
def get_s32_pin_type(self):
|
|
return self._s32_pin_type
|
|
def reset_s32_pin_type(self):
|
|
self._s32_pin_type = ''
|
|
|
|
def set_float_pin_type(self, value):
|
|
self._float_pin_type = value
|
|
if value:
|
|
self._toggle_properties('float')
|
|
def get_float_pin_type(self):
|
|
return self._float_pin_type
|
|
def reset_float_pin_type(self):
|
|
self._float_pin_type = ''
|
|
|
|
def set_floatTemplate(self, data):
|
|
self._floatTemplate = data
|
|
def get_floatTemplate(self):
|
|
return self._floatTemplate
|
|
def reset_floatTemplate(self):
|
|
self._floatTemplate = ''
|
|
|
|
# designer will show these properties in this order:
|
|
pin_name = QtCore.Property(str, get_pin_name, set_pin_name, reset_pin_name)
|
|
bit_pin_type = QtCore.Property(bool, get_bit_pin_type, set_bit_pin_type, reset_bit_pin_type)
|
|
s32_pin_type = QtCore.Property(bool, get_s32_pin_type, set_s32_pin_type, reset_s32_pin_type)
|
|
float_pin_type = QtCore.Property(bool, get_float_pin_type, set_float_pin_type, reset_float_pin_type)
|
|
floatTemplate = QtCore.Property(str, get_floatTemplate, set_floatTemplate, reset_floatTemplate)
|
|
|
|
##############################
|
|
# required class boiler code #
|
|
##############################
|
|
|
|
def __getitem__(self, item):
|
|
return getattr(self, item)
|
|
def __setitem__(self, item, value):
|
|
return setattr(self, item, value)
|
|
|
|
class CheckBox(QtWidgets.QCheckBox, _HalToggleBase):
|
|
def __init__(self, parent=None):
|
|
super(CheckBox, self).__init__(parent)
|
|
|
|
|
|
class RadioButton(QtWidgets.QRadioButton, _HalToggleBase):
|
|
def __init__(self, parent=None):
|
|
super(RadioButton, self).__init__(parent)
|
|
|
|
|
|
class Slider(QtWidgets.QSlider, _HalWidgetBase):
|
|
def __init__(self, parent=None):
|
|
super(Slider, self).__init__(parent)
|
|
|
|
def _hal_init(self):
|
|
if self._pin_name_ == '':
|
|
pname = self.HAL_NAME_
|
|
else:
|
|
pname = self._pin_name_
|
|
self.hal_pin_s = self.HAL_GCOMP_.newpin(str(pname +'-s'), hal.HAL_S32, hal.HAL_OUT)
|
|
self.hal_pin_f = self.HAL_GCOMP_.newpin(pname +'-f', hal.HAL_FLOAT, hal.HAL_OUT)
|
|
self.hal_pin_scale = self.HAL_GCOMP_.newpin(pname +'-scale', hal.HAL_FLOAT, hal.HAL_IN)
|
|
self.hal_pin_scale.set(1)
|
|
self.updateValue(self.value())
|
|
self.valueChanged.connect(lambda data:self.updateValue(data))
|
|
|
|
def updateValue(self, data):
|
|
scale = self.hal_pin_scale.get()
|
|
self.hal_pin_s.set(data)
|
|
self.hal_pin_f.set(data*scale)
|
|
|
|
def set_pin_name(self, value):
|
|
self._pin_name_ = value
|
|
def get_pin_name(self):
|
|
return self._pin_name_
|
|
def reset_pin_name(self):
|
|
self._pin_name_ = ''
|
|
pin_name = QtCore.Property(str, get_pin_name, set_pin_name, reset_pin_name)
|
|
|
|
class Dial(QtWidgets.QDial, _HalWidgetBase):
|
|
def __init__(self, parent=None):
|
|
super(Dial, self).__init__(parent)
|
|
self._lastRawCount = 0
|
|
self._currentTotalCount = 0
|
|
self._deltaScaled = 0
|
|
self.epiLow = int(self.maximum() * .25)
|
|
self.epiHigh = self.maximum() - self.epiLow
|
|
self.scale = 1
|
|
|
|
def _hal_init(self):
|
|
if self._pin_name_ == '':
|
|
pname = self.HAL_NAME_
|
|
else:
|
|
pname = self._pin_name_
|
|
self.hal_pin_s = self.HAL_GCOMP_.newpin(str(pname +'-s'), hal.HAL_S32, hal.HAL_OUT)
|
|
self.hal_pin_f = self.HAL_GCOMP_.newpin(pname +'-f', hal.HAL_FLOAT, hal.HAL_OUT)
|
|
self.hal_pin_d = self.HAL_GCOMP_.newpin(pname +'-d', hal.HAL_FLOAT, hal.HAL_OUT)
|
|
self.hal_pin_scale = self.HAL_GCOMP_.newpin(pname +'-scale', hal.HAL_FLOAT, hal.HAL_IN)
|
|
self.hal_pin_scale.value_changed.connect(lambda data: self.updateScale(data))
|
|
self.hal_pin_scale.set(1)
|
|
self.updateCount(self.value())
|
|
self.valueChanged.connect(lambda data:self.updateCount(data))
|
|
|
|
def updateScale(self, data):
|
|
self.scale = data
|
|
self.hal_pin_f.set(self._currentTotalCount * data)
|
|
|
|
def updateCount(self, count):
|
|
# wrapping dials -> 0 and maximum is the same position
|
|
if count == self.maximum() and self.wrapping(): count = 0
|
|
|
|
delta = self._lastRawCount - count
|
|
#print 'last:',self._lastRawCount ,'raw count',count,'delta',delta,'count:',count
|
|
if self._lastRawCount > self.epiHigh and count < self.epiLow :
|
|
change = self.maximum() - self._lastRawCount + count
|
|
self._currentTotalCount += change
|
|
self._deltaScaled += change * self.scale
|
|
elif count > self.epiHigh and self._lastRawCount < self.epiLow :
|
|
change = self.maximum() - count + self._lastRawCount
|
|
self._currentTotalCount -= change
|
|
self._deltaScaled -= change * self.scale
|
|
else:
|
|
self._currentTotalCount -= delta
|
|
self._deltaScaled -= delta * self.scale
|
|
|
|
|
|
self._lastRawCount = count
|
|
self.hal_pin_s.set(self._currentTotalCount)
|
|
self.hal_pin_f.set(self._currentTotalCount * self.scale)
|
|
self.hal_pin_d.set(self._deltaScaled)
|
|
|
|
def set_pin_name(self, value):
|
|
self._pin_name_ = value
|
|
def get_pin_name(self):
|
|
return self._pin_name_
|
|
def reset_pin_name(self):
|
|
self._pin_name_ = ''
|
|
pin_name = QtCore.Property(str, get_pin_name, set_pin_name, reset_pin_name)
|
|
|
|
class DoubleScale(QtWidgets.QDoubleSpinBox, _HalScaleBase):
|
|
intOutput = QtCore.Signal(int)
|
|
floatOutput = QtCore.Signal(float)
|
|
|
|
def __init__(self, parent=None):
|
|
super(DoubleScale, self).__init__(parent)
|
|
self.setValue(1)
|
|
|
|
# one can connect signals to this widget to
|
|
# feed an input that gets scaled by this widget.
|
|
@QtCore.Slot(float)
|
|
@QtCore.Slot(int)
|
|
def setInput(self, data):
|
|
self.input = data
|
|
self.valueChanged.emit(self.value())
|
|
|
|
# call original pin update then
|
|
# update anything connected to signals
|
|
def _pin_update(self, data):
|
|
super(DoubleScale, self)._pin_update(data)
|
|
self.intOutput.emit(int(self.hal_pin_s.get()))
|
|
self.floatOutput.emit(self.hal_pin_f.get())
|
|
|
|
def set_pin_name(self, value):
|
|
self._pin_name_ = value
|
|
def get_pin_name(self):
|
|
return self._pin_name_
|
|
def reset_pin_name(self):
|
|
self._pin_name_ = ''
|
|
pin_name = QtCore.Property(str, get_pin_name, set_pin_name, reset_pin_name)
|
|
|
|
class GridLayout(QtWidgets.QWidget, _HalSensitiveBase):
|
|
def __init__(self, parent=None):
|
|
super(GridLayout, self).__init__(parent)
|
|
|
|
|
|
class RichButton(QtWidgets.QPushButton):
|
|
def __init__(self, parent=None):
|
|
super(RichButton, self).__init__(parent)
|
|
self._text = self.text()
|
|
|
|
self._label = QtWidgets.QLabel(self._text, self)
|
|
self._label.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents )
|
|
self._label.setAlignment(QtCore.Qt.AlignCenter|QtCore.Qt.AlignVCenter)
|
|
self._label.show()
|
|
|
|
def setText(self, text):
|
|
self._label.setText(text)
|
|
|
|
def text(self):
|
|
try:
|
|
return self._label.text()
|
|
except:
|
|
pass
|
|
|
|
def event(self, event):
|
|
if event.type() == QtCore.QEvent.Resize:
|
|
w = QtGui.QResizeEvent.size(event)
|
|
try:
|
|
self._label.resize(w.width(), w.height())
|
|
self.resize(w.width(), w.height())
|
|
except:
|
|
pass
|
|
return True
|
|
else:
|
|
return super(RichButton, self).event( event)
|
|
|
|
def set_richText(self, data):
|
|
self.setText(data)
|
|
def get_richText(self):
|
|
return self.text()
|
|
def reset_richText(self):
|
|
self.setText('Button')
|
|
richtext_string = QtCore.Property(str, get_richText, set_richText, reset_richText)
|
|
|
|
# button for function callbacks rather then HAL pins
|
|
class IndicatedPushButton(QtWidgets.QPushButton, IndicatedMixIn):
|
|
def __init__(self, parent=None):
|
|
super(IndicatedPushButton, self).__init__(parent)
|
|
|
|
# Override setText function so we can toggle displayed text
|
|
def setText(self, text):
|
|
if not self._state_text:
|
|
super(IndicatedPushButton, self).setText(text)
|
|
return
|
|
if self.isCheckable():
|
|
if self.isChecked():
|
|
super(IndicatedPushButton, self).setText(self._true_string)
|
|
else:
|
|
super(IndicatedPushButton, self).setText(self._false_string)
|
|
elif self._indicator_state:
|
|
super(IndicatedPushButton, self).setText(self._true_string)
|
|
else:
|
|
super(IndicatedPushButton, self).setText(self._false_string)
|
|
|
|
# button controls HAL pins
|
|
class PushButton(QtWidgets.QPushButton, IndicatedMixIn):
|
|
HALPinType = HALPinType
|
|
QEnum(HALPinType)
|
|
|
|
# older version of pyqt5 need this as well as QEnum
|
|
NONE = 0
|
|
BIT = hal.HAL_BIT
|
|
S32 = hal.HAL_S32
|
|
FLOAT = hal.HAL_FLOAT
|
|
|
|
def __init__(self, parent=None):
|
|
super(PushButton, self).__init__(parent)
|
|
|
|
self._pin_type = HALPinType.S32
|
|
self._groupPinName = ''
|
|
self._exclusiveValue = 0.0
|
|
self.halPinGroup = None
|
|
|
|
# Override setText function so we can toggle displayed text
|
|
def setText(self, text):
|
|
if not self._state_text:
|
|
super(PushButton,self).setText(text)
|
|
return
|
|
if self.isCheckable():
|
|
if self.isChecked():
|
|
super(PushButton, self).setText(self._true_string)
|
|
else:
|
|
super(PushButton, self).setText(self._false_string)
|
|
elif self._indicator_state:
|
|
super(PushButton, self).setText(self._true_string)
|
|
else:
|
|
super(PushButton, self).setText(self._false_string)
|
|
|
|
# make the super class (pushbutton) HAL pins
|
|
# then the button pins
|
|
# this overrides the super class function
|
|
# but then calls it after to connect signals etc.
|
|
def _hal_init(self):
|
|
if self.autoExclusive():
|
|
self.makeGroupPin()
|
|
if self._pin_name_ == '':
|
|
pname = self.HAL_NAME_
|
|
else:
|
|
pname = self._pin_name_
|
|
self.hal_pin = self.HAL_GCOMP_.newpin(str(pname), hal.HAL_BIT, hal.HAL_OUT)
|
|
|
|
super(PushButton, self)._hal_init()
|
|
|
|
# done so we can adjust 'checkable' signals at run time
|
|
# ie delete all signals an re apply them
|
|
# this overrides the super class function
|
|
def connectSignals(self):
|
|
super().connectSignals()
|
|
def _update(state):
|
|
self.hal_pin.set(state)
|
|
if self.autoExclusive() and state:
|
|
self.updateGroup()
|
|
if self.isCheckable():
|
|
self.toggled[bool].connect(_update)
|
|
else:
|
|
self.pressed.connect(lambda: _update(True))
|
|
self.released.connect(lambda: _update(False))
|
|
_update(self.isChecked())
|
|
|
|
# find the first button in group
|
|
# it's the 'driver' button widget
|
|
# then if it's this instance, make a HAL pin for the group
|
|
def makeGroupPin(self):
|
|
for i in self.parent().children():
|
|
if isinstance(i, PushButton):
|
|
|
|
# are we the group's driver widget?
|
|
if i is self:
|
|
# make pin based on type and name
|
|
if not self._pin_type == HALPinType.NONE:
|
|
ptype = self._pin_type
|
|
if self._groupPinName == '':
|
|
name = HALPinType(self._pin_type).name
|
|
pname = self.HAL_NAME_ + '.exclusive'+name
|
|
else:
|
|
pname = self._groupPinName
|
|
self.halPinGroup = self.HAL_GCOMP_.newpin(pname , ptype, hal.HAL_OUT)
|
|
break
|
|
break
|
|
|
|
# find the driver widget and update it's group HAL pin
|
|
def updateGroup(self):
|
|
value = 0 # flag and value of pin
|
|
for i in self.parent().children():
|
|
if isinstance(i, QtWidgets.QAbstractButton):
|
|
if value == 0:
|
|
driver = i
|
|
value = -1 # flag we found the driver
|
|
if i.isChecked():
|
|
#print(self.objectName(),' Checked:',i.objectName()
|
|
value = i._exclusiveValue
|
|
#print('value:',value)
|
|
break
|
|
|
|
if self._pin_type == HALPinType.BIT:
|
|
data = bool(value)
|
|
elif self._pin_type == HALPinType.FLOAT:
|
|
data = float(value)
|
|
elif self._pin_type == HALPinType.S32:
|
|
data = int(value)
|
|
else:
|
|
return
|
|
|
|
# update the pin of the 'driver' widget
|
|
try:
|
|
if not driver.halPinGroup is None:
|
|
driver.halPinGroup.set(data)
|
|
except Exception as e:
|
|
print(e)
|
|
|
|
########################################################################
|
|
# This is how designer can interact with our widget properties.
|
|
# designer will show the QtCore.Property properties in the editor
|
|
# it will use the get set and reset calls to do those actions
|
|
########################################################################
|
|
|
|
def set_pin_type(self, value):
|
|
self._pin_type = value
|
|
def get_pin_type(self):
|
|
return self._pin_type
|
|
def reset_pin_type(self):
|
|
self._pin_type = HALPinType.S32
|
|
|
|
# designer will show these properties in this order:
|
|
pin_type = QtCore.Property(HALPinType, get_pin_type, set_pin_type, reset_pin_type)
|
|
|
|
def set_group_pin_name(self, value):
|
|
self._groupPinName = value
|
|
def get_group_pin_name(self):
|
|
return self._groupPinName
|
|
def reset_group_pin_name(self):
|
|
self._groupPinName = ''
|
|
groupPinName = QtCore.Property(str, get_group_pin_name, set_group_pin_name, reset_group_pin_name)
|
|
|
|
def set_exclusive_value(self, data):
|
|
self._exclusiveValue = data
|
|
self.updateGroup()
|
|
def get_exclusive_value(self):
|
|
return self._exclusiveValue
|
|
def reset_exclusive_value(self):
|
|
self._exclusiveValue = 0.0
|
|
self.updateGroup()
|
|
|
|
exclusiveHALValue = QtCore.Property(float, get_exclusive_value, set_exclusive_value, reset_exclusive_value)
|
|
|
|
class ScaledLabel(QtWidgets.QLabel):
|
|
'''
|
|
Label that scales the text based on available size.
|
|
Base widget for DRO display.
|
|
'''
|
|
def __init__(self, parent=None):
|
|
super(ScaledLabel, self).__init__(parent)
|
|
self._text = ''
|
|
self._scaled = True
|
|
|
|
def _hal_init(self):
|
|
if self.textFormat() in( 0,1) and self._scaled:
|
|
self.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Ignored,
|
|
QtWidgets.QSizePolicy.Ignored))
|
|
self.setMinSize(15)
|
|
|
|
def textSample(self):
|
|
'''
|
|
Holds a sample of text to reserve space for the longest text.
|
|
'''
|
|
if self._text =='':
|
|
return self.text()
|
|
return self._text
|
|
|
|
def setMinSize(self, minfs):
|
|
f = self.font()
|
|
f.setPointSizeF(minfs)
|
|
br = QtGui.QFontMetrics(f).boundingRect(self.textSample())
|
|
self.setMinimumSize(br.width(), br.height())
|
|
|
|
def setMaxSize(self, maxfs):
|
|
f = self.font()
|
|
f.setPointSizeF(maxfs)
|
|
br = QtGui.QFontMetrics(f).boundingRect(self.textSample())
|
|
self.setMaximumSize(br.width(), br.height())
|
|
|
|
def resizeEvent(self, event):
|
|
super(ScaledLabel, self).resizeEvent(event)
|
|
if not self._scaled:
|
|
return
|
|
#if self.textFormat() == QtCore.Qt.RichText:
|
|
#print(self.text())
|
|
#print(self.styleSheet(),self.text(),self.font().pointSizeF())
|
|
if not self.text() or self.textFormat() == QtCore.Qt.AutoText:
|
|
return
|
|
|
|
#--- fetch current parameters ----
|
|
f = self.font()
|
|
cr = self.contentsRect()
|
|
|
|
#--- iterate to find the font size that fits the contentsRect ---
|
|
dw = event.size().width() - event.oldSize().width() # width change
|
|
dh = event.size().height() - event.oldSize().height() # height change
|
|
fs = max(f.pointSizeF(), .5)
|
|
while True:
|
|
f.setPointSize(int(fs))
|
|
#gives bigger text
|
|
#br = QtGui.QFontMetrics(f).tightBoundingRect(self.textSample())
|
|
# then this
|
|
br = QtGui.QFontMetrics(f).boundingRect(self.textSample())
|
|
if dw >= 0 and dh >= 0: # label is expanding
|
|
if br.height() <= cr.height() and br.width() <= cr.width():
|
|
fs += .5
|
|
else:
|
|
f.setPointSizeF(max(fs - .5, .5)) # backtrack
|
|
break
|
|
|
|
else: # label is shrinking
|
|
if br.height() > cr.height() or br.width() > cr.width():
|
|
fs -= .5
|
|
else:
|
|
break
|
|
|
|
if fs < .5: break
|
|
|
|
#print (br, cr)
|
|
#--- update font size ---
|
|
if self.textFormat() == QtCore.Qt.RichText:
|
|
self.setStyleFontSize(f.pointSizeF())
|
|
else:
|
|
self.setFont(f)
|
|
|
|
def setStyleFontSize(self, fs):
|
|
self.setStyleSheet(' font: {}pt ;'.format(fs))
|
|
|
|
def set_scaleText(self, data):
|
|
self._scaled = data
|
|
def get_scaleText(self):
|
|
return self._scaled
|
|
def reset_scaleText(self):
|
|
self._scaled = True
|
|
|
|
def set_testSample(self, data):
|
|
self._text = data
|
|
def get_testSample(self):
|
|
return self._text
|
|
def reset_testSample(self):
|
|
self._text = ''
|
|
|
|
scaleText = QtCore.Property(bool, get_scaleText, set_scaleText, reset_scaleText)
|
|
textSpaceSample = QtCore.Property(str, get_testSample, set_testSample, reset_testSample)
|
|
|