GUIElements.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. from PyQt4 import QtGui, QtCore
  2. from copy import copy
  3. import FlatCAMApp
  4. import re
  5. class RadioSet(QtGui.QWidget):
  6. def __init__(self, choices, orientation='horizontal', parent=None):
  7. """
  8. The choices are specified as a list of dictionaries containing:
  9. * 'label': Shown in the UI
  10. * 'value': The value returned is selected
  11. :param choices: List of choices. See description.
  12. :type choices: list
  13. """
  14. super(RadioSet, self).__init__(parent)
  15. self.choices = copy(choices)
  16. if orientation == 'horizontal':
  17. layout = QtGui.QHBoxLayout()
  18. else:
  19. layout = QtGui.QVBoxLayout()
  20. group = QtGui.QButtonGroup(self)
  21. for choice in self.choices:
  22. choice['radio'] = QtGui.QRadioButton(choice['label'])
  23. group.addButton(choice['radio'])
  24. layout.addWidget(choice['radio'], stretch=0)
  25. choice['radio'].toggled.connect(self.on_toggle)
  26. layout.addStretch()
  27. self.setLayout(layout)
  28. self.group_toggle_fn = lambda: None
  29. def on_toggle(self):
  30. FlatCAMApp.App.log.debug("Radio toggled")
  31. radio = self.sender()
  32. if radio.isChecked():
  33. self.group_toggle_fn()
  34. return
  35. def get_value(self):
  36. for choice in self.choices:
  37. if choice['radio'].isChecked():
  38. return choice['value']
  39. FlatCAMApp.App.log.error("No button was toggled in RadioSet.")
  40. return None
  41. def set_value(self, val):
  42. for choice in self.choices:
  43. if choice['value'] == val:
  44. choice['radio'].setChecked(True)
  45. return
  46. FlatCAMApp.App.log.error("Value given is not part of this RadioSet: %s" % str(val))
  47. class LengthEntry(QtGui.QLineEdit):
  48. def __init__(self, output_units='IN', parent=None):
  49. super(LengthEntry, self).__init__(parent)
  50. self.output_units = output_units
  51. self.format_re = re.compile(r"^([^\s]+)(?:\s([a-zA-Z]+))?$")
  52. # Unit conversion table OUTPUT-INPUT
  53. self.scales = {
  54. 'IN': {'IN': 1.0,
  55. 'MM': 1/25.4},
  56. 'MM': {'IN': 25.4,
  57. 'MM': 1.0}
  58. }
  59. def returnPressed(self, *args, **kwargs):
  60. val = self.get_value()
  61. if val is not None:
  62. self.set_text(QtCore.QString(str(val)))
  63. else:
  64. FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
  65. def get_value(self):
  66. raw = str(self.text()).strip(' ')
  67. match = self.format_re.search(raw)
  68. if not match:
  69. return None
  70. try:
  71. if match.group(2) is not None and match.group(2).upper() in self.scales:
  72. return float(eval(match.group(1)))*float(self.scales[self.output_units][match.group(2).upper()])
  73. else:
  74. return float(eval(match.group(1)))
  75. except:
  76. FlatCAMApp.App.log.warning("Could not parse value in entry: %s" % str(raw))
  77. return None
  78. def set_value(self, val):
  79. self.setText(QtCore.QString(str(val)))
  80. class FloatEntry(QtGui.QLineEdit):
  81. def __init__(self, parent=None):
  82. super(FloatEntry, self).__init__(parent)
  83. def returnPressed(self, *args, **kwargs):
  84. val = self.get_value()
  85. if val is not None:
  86. self.set_text(QtCore.QString(str(val)))
  87. else:
  88. FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.text())
  89. def get_value(self):
  90. raw = str(self.text()).strip(' ')
  91. try:
  92. evaled = eval(raw)
  93. except:
  94. FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
  95. return None
  96. return float(evaled)
  97. def set_value(self, val):
  98. self.setText("%.6f"%val)
  99. class IntEntry(QtGui.QLineEdit):
  100. def __init__(self, parent=None):
  101. super(IntEntry, self).__init__(parent)
  102. def get_value(self):
  103. return int(self.text())
  104. def set_value(self, val):
  105. self.setText(QtCore.QString(str(val)))
  106. class FCEntry(QtGui.QLineEdit):
  107. def __init__(self, parent=None):
  108. super(FCEntry, self).__init__(parent)
  109. def get_value(self):
  110. return str(self.text())
  111. def set_value(self, val):
  112. self.setText(QtCore.QString(str(val)))
  113. class EvalEntry(QtGui.QLineEdit):
  114. def __init__(self, parent=None):
  115. super(EvalEntry, self).__init__(parent)
  116. def returnPressed(self, *args, **kwargs):
  117. val = self.get_value()
  118. if val is not None:
  119. self.setText(QtCore.QString(str(val)))
  120. else:
  121. FlatCAMApp.App.log.warning("Could not interpret entry: %s" % self.get_text())
  122. def get_value(self):
  123. raw = str(self.text()).strip(' ')
  124. try:
  125. return eval(raw)
  126. except:
  127. FlatCAMApp.App.log.error("Could not evaluate: %s" % str(raw))
  128. return None
  129. def set_value(self, val):
  130. self.setText(QtCore.QString(str(val)))
  131. class FCCheckBox(QtGui.QCheckBox):
  132. def __init__(self, label='', parent=None):
  133. super(FCCheckBox, self).__init__(QtCore.QString(label), parent)
  134. def get_value(self):
  135. return self.isChecked()
  136. def set_value(self, val):
  137. self.setChecked(val)
  138. class FCTextArea(QtGui.QPlainTextEdit):
  139. def __init__(self, parent=None):
  140. super(FCTextArea, self).__init__(parent)
  141. def set_value(self, val):
  142. self.setPlainText(val)
  143. def get_value(self):
  144. return str(self.toPlainText())
  145. class VerticalScrollArea(QtGui.QScrollArea):
  146. """
  147. This widget extends QtGui.QScrollArea to make a vertical-only
  148. scroll area that also expands horizontally to accomodate
  149. its contents.
  150. """
  151. def __init__(self, parent=None):
  152. QtGui.QScrollArea.__init__(self, parent=parent)
  153. self.setWidgetResizable(True)
  154. self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
  155. self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
  156. def eventFilter(self, source, event):
  157. """
  158. The event filter gets automatically installed when setWidget()
  159. is called.
  160. :param source:
  161. :param event:
  162. :return:
  163. """
  164. if event.type() == QtCore.QEvent.Resize and source == self.widget():
  165. # FlatCAMApp.App.log.debug("VerticalScrollArea: Widget resized:")
  166. # FlatCAMApp.App.log.debug(" minimumSizeHint().width() = %d" % self.widget().minimumSizeHint().width())
  167. # FlatCAMApp.App.log.debug(" verticalScrollBar().width() = %d" % self.verticalScrollBar().width())
  168. self.setMinimumWidth(self.widget().sizeHint().width() +
  169. self.verticalScrollBar().sizeHint().width())
  170. # if self.verticalScrollBar().isVisible():
  171. # FlatCAMApp.App.log.debug(" Scroll bar visible")
  172. # self.setMinimumWidth(self.widget().minimumSizeHint().width() +
  173. # self.verticalScrollBar().width())
  174. # else:
  175. # FlatCAMApp.App.log.debug(" Scroll bar hidden")
  176. # self.setMinimumWidth(self.widget().minimumSizeHint().width())
  177. return QtGui.QWidget.eventFilter(self, source, event)