flatcam/GUIElements.py

256 lines
7.6 KiB
Python

from PyQt4 import QtGui, QtCore
from copy import copy
import FlatCAMApp
import re
class RadioSet(QtGui.QWidget):
def __init__(self, choices, orientation='horizontal', parent=None):
"""
The choices are specified as a list of dictionaries containing:
* 'label': Shown in the UI
* 'value': The value returned is selected
:param choices: List of choices. See description.
:type choices: list
"""
super(RadioSet, self).__init__(parent)
self.choices = copy(choices)
if orientation == 'horizontal':
layout = QtGui.QHBoxLayout()
else:
layout = QtGui.QVBoxLayout()
group = QtGui.QButtonGroup(self)
for choice in self.choices:
choice['radio'] = QtGui.QRadioButton(choice['label'])
group.addButton(choice['radio'])
layout.addWidget(choice['radio'], stretch=0)
choice['radio'].toggled.connect(self.on_toggle)
layout.addStretch()
self.setLayout(layout)
self.group_toggle_fn = lambda: None
def on_toggle(self):
FlatCAMApp.App.log.debug("Radio toggled")
radio = self.sender()
if radio.isChecked():
self.group_toggle_fn()
return
def get_value(self):
for choice in self.choices:
if choice['radio'].isChecked():
return choice['value']
FlatCAMApp.App.log.error("No button was toggled in RadioSet.")
return None
def set_value(self, val):
for choice in self.choices:
if choice['value'] == val:
choice['radio'].setChecked(True)
return
FlatCAMApp.App.log.error("Value given is not part of this RadioSet: %s" % str(val))
class LengthEntry(QtGui.QLineEdit):
def __init__(self, output_units='IN', parent=None):
super(LengthEntry, self).__init__(parent)
self.output_units = output_units
self.format_re = re.compile(r"^([^\s]+)(?:\s([a-zA-Z]+))?$")
# Unit conversion table OUTPUT-INPUT
self.scales = {
'IN': {'IN': 1.0,
'MM': 1/25.4},
'MM': {'IN': 25.4,
'MM': 1.0}
}
def returnPressed(self, *args, **kwargs):
val = self.get_value()
if val is not None:
self.set_text(QtCore.QString(str(val)))
else:
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
def get_value(self):
raw = str(self.text()).strip(' ')
match = self.format_re.search(raw)
if not match:
return None
try:
if match.group(2) is not None and match.group(2).upper() in self.scales:
return float(eval(match.group(1)))*float(self.scales[self.output_units][match.group(2).upper()])
else:
return float(eval(match.group(1)))
except:
FlatCAMApp.App.log.warning("Could not parse value in entry: %s" % str(raw))
return None
def set_value(self, val):
self.setText(QtCore.QString(str(val)))
class FloatEntry(QtGui.QLineEdit):
def __init__(self, parent=None):
super(FloatEntry, self).__init__(parent)
def returnPressed(self, *args, **kwargs):
val = self.get_value()
if val is not None:
self.set_text(QtCore.QString(str(val)))
else:
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.text())
def get_value(self):
raw = str(self.text()).strip(' ')
try:
evaled = eval(raw)
except:
FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
return None
return float(evaled)
def set_value(self, val):
self.setText("%.6f"%val)
class IntEntry(QtGui.QLineEdit):
def __init__(self, parent=None):
super(IntEntry, self).__init__(parent)
def get_value(self):
return int(self.text())
def set_value(self, val):
self.setText(QtCore.QString(str(val)))
class FCEntry(QtGui.QLineEdit):
def __init__(self, parent=None):
super(FCEntry, self).__init__(parent)
def get_value(self):
return str(self.text())
def set_value(self, val):
self.setText(QtCore.QString(str(val)))
class EvalEntry(QtGui.QLineEdit):
def __init__(self, parent=None):
super(EvalEntry, self).__init__(parent)
def returnPressed(self, *args, **kwargs):
val = self.get_value()
if val is not None:
self.setText(QtCore.QString(str(val)))
else:
FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
def get_value(self):
raw = str(self.text()).strip(' ')
try:
return eval(raw)
except:
FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
return None
def set_value(self, val):
self.setText(QtCore.QString(str(val)))
class FCCheckBox(QtGui.QCheckBox):
def __init__(self, label='', parent=None):
super(FCCheckBox, self).__init__(QtCore.QString(label), parent)
def get_value(self):
return self.isChecked()
def set_value(self, val):
self.setChecked(val)
class FCTextArea(QtGui.QPlainTextEdit):
def __init__(self, parent=None):
super(FCTextArea, self).__init__(parent)
def set_value(self, val):
self.setPlainText(val)
def get_value(self):
return str(self.toPlainText())
class VerticalScrollArea(QtGui.QScrollArea):
"""
This widget extends QtGui.QScrollArea to make a vertical-only
scroll area that also expands horizontally to accomodate
its contents.
"""
def __init__(self, parent=None):
QtGui.QScrollArea.__init__(self, parent=parent)
self.setWidgetResizable(True)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
def eventFilter(self, source, event):
"""
The event filter gets automatically installed when setWidget()
is called.
:param source:
:param event:
:return:
"""
if event.type() == QtCore.QEvent.Resize and source == self.widget():
# FlatCAMApp.App.log.debug("VerticalScrollArea: Widget resized:")
# FlatCAMApp.App.log.debug(" minimumSizeHint().width() = %d" % self.widget().minimumSizeHint().width())
# FlatCAMApp.App.log.debug(" verticalScrollBar().width() = %d" % self.verticalScrollBar().width())
self.setMinimumWidth(self.widget().sizeHint().width() +
self.verticalScrollBar().sizeHint().width())
# if self.verticalScrollBar().isVisible():
# FlatCAMApp.App.log.debug(" Scroll bar visible")
# self.setMinimumWidth(self.widget().minimumSizeHint().width() +
# self.verticalScrollBar().width())
# else:
# FlatCAMApp.App.log.debug(" Scroll bar hidden")
# self.setMinimumWidth(self.widget().minimumSizeHint().width())
return QtGui.QWidget.eventFilter(self, source, event)
class OptionalInputSection():
def __init__(self, cb, optinputs):
assert isinstance(cb, FCCheckBox)
self.cb = cb
self.optinputs = optinputs
self.on_cb_change()
self.cb.stateChanged.connect(self.on_cb_change)
def on_cb_change(self):
if self.cb.checkState():
for widget in self.optinputs:
widget.setEnabled(True)
else:
for widget in self.optinputs:
widget.setEnabled(False)