00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import math
00036 import os
00037
00038 from dynamic_reconfigure.msg import Config as ConfigMsg
00039 from python_qt_binding import loadUi
00040 from python_qt_binding.QtCore import Qt, Signal
00041 from python_qt_binding.QtGui import QCheckBox, QComboBox, QDoubleValidator, QIntValidator, QHBoxLayout, QLabel, QLineEdit, QPainter, QSlider, QWidget
00042 import rospy
00043
00044 from .param_updater import ParamUpdater
00045
00046 EDITOR_TYPES = {
00047 'bool': 'BooleanEditor',
00048 'str': 'StringEditor',
00049 'int': 'IntegerEditor',
00050 'double': 'DoubleEditor',
00051 }
00052
00053 class EditorWidget(QWidget):
00054
00055 def __init__(self, updater, config):
00056 """
00057 :param updater:
00058 :type updater: rqt_param.ParamUpdater
00059 """
00060
00061 super(EditorWidget, self).__init__()
00062
00063 self.updater = updater
00064 self.name = config['name']
00065
00066 self.old_value = None
00067
00068 def _update(self, value):
00069 if value != self.old_value:
00070 self.update_configuration(value)
00071 self.old_value = value
00072
00073 def update_value(self, value):
00074 pass
00075
00076 def update_configuration(self, value):
00077 self.updater.update({self.name : value})
00078
00079 def display(self, grid, row):
00080 """
00081 Should be overridden in subclass.
00082
00083 :type grid: ???
00084 :type row: ???
00085 """
00086 pass
00087
00088 def close(self):
00089 """
00090 Should be overridden in subclass.
00091 """
00092 pass
00093
00094 class BooleanEditor(EditorWidget):
00095 def __init__(self, updater, config):
00096 super(BooleanEditor, self).__init__(updater, config)
00097
00098 ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
00099 'ui/editor_bool.ui')
00100 loadUi(ui_file, self)
00101
00102 self.update_value(config['default'])
00103 self._checkbox.clicked.connect(self._update)
00104
00105 def update_value(self, value):
00106 self._checkbox.setChecked(value)
00107
00108 def display(self, grid, row):
00109 grid.addWidget(QLabel(self.name), row, 0, Qt.AlignRight)
00110 grid.addWidget(self, row, 1)
00111
00112 class StringEditor(EditorWidget):
00113 def __init__(self, updater, config):
00114 super(StringEditor, self).__init__(updater, config)
00115 ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
00116 'ui/editor_string.ui')
00117 loadUi(ui_file, self)
00118
00119 self._paramval_lineedit.editingFinished.connect(self.edit_finished)
00120
00121 def update_value(self, value):
00122 self._paramval_lineedit.setText(value)
00123
00124 def edit_finished(self):
00125 self._update(self._paramval_lineedit.text())
00126
00127 def display(self, grid, row):
00128 grid.addWidget(QLabel(self.name), row, 0, Qt.AlignRight)
00129 grid.addWidget(self, row, 1)
00130
00131 class IntegerEditor(EditorWidget):
00132 def __init__(self, updater, config):
00133 super(IntegerEditor, self).__init__(updater, config)
00134
00135 ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
00136 'ui/editor_number.ui')
00137 loadUi(ui_file, self)
00138
00139 self.min = int(config['min'])
00140 self.max = int(config['max'])
00141 self._min_val_label.setText(str(self.min))
00142 self._max_val_label.setText(str(self.max))
00143
00144 self._slider_horizontal.setRange(self.min, self.max)
00145 self._slider_horizontal.sliderReleased.connect(self.slider_released)
00146 self._slider_horizontal.sliderMoved.connect(self.update_text)
00147
00148
00149
00150 self._paramval_lineEdit.setValidator(QIntValidator(self.min,
00151 self.max, self))
00152 self._paramval_lineEdit.editingFinished.connect(self.editing_finished)
00153
00154
00155 self._paramval_lineEdit.setText(str(config['default']))
00156 self._slider_horizontal.setSliderPosition(int(config['default']))
00157
00158 def slider_released(self):
00159 self.update_text(self._slider_horizontal.value())
00160 self._update(self._slider_horizontal.value())
00161
00162 def update_text(self, val):
00163 rospy.logdebug(' IntegerEditor.update_text val=%s', str(val))
00164 self._paramval_lineEdit.setText(str(val))
00165
00166 def editing_finished(self):
00167 self._slider_horizontal.setSliderPosition(
00168 int(self._paramval_lineEdit.text()))
00169 self._update(int(self._paramval_lineEdit.text()))
00170
00171 def update_value(self, val):
00172 self._slider_horizontal.setSliderPosition(int(val))
00173 self._paramval_lineEdit.setText(str(val))
00174
00175 def display(self, grid, row):
00176 grid.addWidget(QLabel(self.name), row, 0, Qt.AlignRight)
00177 grid.addWidget(self, row, 1)
00178
00179 class DoubleEditor(EditorWidget):
00180 def __init__(self, updater, config):
00181 super(DoubleEditor, self).__init__(updater, config)
00182
00183 ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
00184 'ui/editor_number.ui')
00185 loadUi(ui_file, self)
00186
00187
00188 if config['min'] != -float('inf'):
00189 self.min = float(config['min'])
00190 self._min_val_label.setText(str(self.min))
00191 self.func = lambda x: x
00192 self.ifunc = self.func
00193 else:
00194 self.min = -1e10000
00195 self._min_val_label.setText('-inf')
00196 self.func = lambda x: math.atan(x)
00197 self.ifunc = lambda x: math.tan(x)
00198
00199 if config['max'] != float('inf'):
00200 self.max = float(config['max'])
00201 self._max_val_label.setText(str(self.max))
00202 self.func = lambda x: x
00203 self.ifunc = self.func
00204 else:
00205 self.max = 1e10000
00206 self.max_val_label.setText('inf')
00207 self.func = lambda x: math.atan(x)
00208 self.ifunc = lambda x: math.tan(x)
00209
00210 self.scale = (self.func(self.max) - self.func(self.min)) / 100
00211 self.offset = self.func(self.min)
00212
00213 self._slider_horizontal.setRange(self.slider_value(self.min),
00214 self.slider_value(self.max))
00215 self._slider_horizontal.sliderReleased.connect(self.slider_released)
00216 self._slider_horizontal.sliderMoved.connect(self.update_text)
00217
00218 self._paramval_lineEdit.setValidator(QDoubleValidator(
00219 self.min, self.max,
00220 4, self))
00221 self._paramval_lineEdit.editingFinished.connect(self.editing_finished)
00222
00223 self._paramval_lineEdit.setText(str(config['default']))
00224 self._slider_horizontal.setSliderPosition(
00225 self.slider_value(config['default']))
00226
00227 def get_value(self):
00228 return self.ifunc(self._slider_horizontal.value() * self.scale)
00229
00230 def slider_value(self, value):
00231 return int(round((self.func(value)) / self.scale))
00232
00233 def slider_released(self):
00234 self.update_text(self.get_value())
00235 self._update(self.get_value())
00236
00237 def update_text(self, value):
00238 self._paramval_lineEdit.setText(str(self.get_value()))
00239
00240 def editing_finished(self):
00241 self._slider_horizontal.setSliderPosition(
00242 self.slider_value(float(self._paramval_lineEdit.text())))
00243 self._update(float(self._paramval_lineEdit.text()))
00244
00245 def update_value(self, val):
00246 self._slider_horizontal.setSliderPosition(
00247 self.slider_value(float(val)))
00248 self._paramval_lineEdit.setText(str(val))
00249
00250 def display(self, grid, row):
00251 grid.addWidget(QLabel(self.name), row, 0, Qt.AlignRight)
00252 grid.addWidget(self, row, 1)
00253
00254 class EnumEditor(EditorWidget):
00255 def __init__(self, updater, config):
00256 super(EnumEditor, self).__init__(updater, config)
00257
00258 ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
00259 'ui/editor_enum.ui')
00260 loadUi(ui_file, self)
00261
00262 try:
00263 enum = eval(config['edit_method'])['enum']
00264 except:
00265 print("Malformed enum")
00266 return
00267
00268 self.names = [item['name'] for item in enum]
00269 self.values = [item['value'] for item in enum]
00270
00271 items = ["%s (%s)" % (self.names[i], self.values[i])
00272 for i in range(0, len(self.names))]
00273
00274 self._combobox.addItems(items)
00275 self._combobox.currentIndexChanged['int'].connect(self.selected)
00276
00277 def selected(self, index):
00278 self._update(self.values[index])
00279
00280 def update_value(self, val):
00281 self._combobox.setCurrentIndex(self.values.index(val))
00282
00283 def display(self, grid, row):
00284 grid.addWidget(QLabel(self.name), row, 0, Qt.AlignRight)
00285 grid.addWidget(self, row, 1)
00286