1 from distutils.version
import LooseVersion
6 import python_qt_binding
7 import python_qt_binding.QtCore
as QtCore
8 from python_qt_binding.QtCore
import QEvent
9 from python_qt_binding.QtCore
import QSize
10 from python_qt_binding.QtCore
import Qt
11 from python_qt_binding.QtCore
import QTimer
12 from python_qt_binding.QtCore
import qWarning
13 from python_qt_binding.QtCore
import Slot
14 import python_qt_binding.QtGui
as QtGui
15 from python_qt_binding.QtGui
import QBrush
16 from python_qt_binding.QtGui
import QColor
17 from python_qt_binding.QtGui
import QFont
18 from python_qt_binding.QtGui
import QIcon
19 from python_qt_binding.QtGui
import QPainter
20 from python_qt_binding.QtGui
import QPen
23 from resource_retriever
import get_filename
26 from std_msgs.msg
import Bool
27 from std_msgs.msg
import Time
28 from std_srvs.srv
import Empty
29 from std_srvs.srv
import SetBool
30 from std_srvs.srv
import Trigger
32 if LooseVersion(python_qt_binding.QT_BINDING_VERSION).version[0] >= 5:
33 from python_qt_binding.QtWidgets
import QAction
34 from python_qt_binding.QtWidgets
import QComboBox
35 from python_qt_binding.QtWidgets
import QCompleter
36 from python_qt_binding.QtWidgets
import QDialog
37 from python_qt_binding.QtWidgets
import QGroupBox
38 from python_qt_binding.QtWidgets
import QHBoxLayout
39 from python_qt_binding.QtWidgets
import QLineEdit
40 from python_qt_binding.QtWidgets
import QMenu
41 from python_qt_binding.QtWidgets
import QMessageBox
42 from python_qt_binding.QtWidgets
import QPushButton
43 from python_qt_binding.QtWidgets
import QRadioButton
44 from python_qt_binding.QtWidgets
import QSizePolicy
45 from python_qt_binding.QtWidgets
import QToolButton
46 from python_qt_binding.QtWidgets
import QVBoxLayout
47 from python_qt_binding.QtWidgets
import QWidget
50 from python_qt_binding.QtGui
import QAction
51 from python_qt_binding.QtGui
import QComboBox
52 from python_qt_binding.QtGui
import QCompleter
53 from python_qt_binding.QtGui
import QDialog
54 from python_qt_binding.QtGui
import QGroupBox
55 from python_qt_binding.QtGui
import QHBoxLayout
56 from python_qt_binding.QtGui
import QLineEdit
57 from python_qt_binding.QtGui
import QMenu
58 from python_qt_binding.QtGui
import QMessageBox
59 from python_qt_binding.QtGui
import QPushButton
60 from python_qt_binding.QtGui
import QRadioButton
61 from python_qt_binding.QtGui
import QSizePolicy
62 from python_qt_binding.QtGui
import QToolButton
63 from python_qt_binding.QtGui
import QVBoxLayout
64 from python_qt_binding.QtGui
import QWidget
69 super(LineEditDialog, self).
__init__()
71 vbox = QVBoxLayout(self)
73 model = QtGui.QStandardItemModel(self)
74 for elm
in rospy.get_param_names():
75 model.setItem(model.rowCount(), 0, QtGui.QStandardItem(elm))
78 self.combo_box.setLineEdit(self.
line_edit)
79 self.combo_box.setCompleter(QCompleter())
80 self.combo_box.setModel(model)
81 self.combo_box.completer().setModel(model)
82 self.combo_box.lineEdit().setText(
'')
85 button = QPushButton()
86 button.setText(
"Done")
88 vbox.addWidget(button)
92 self.
value = self.line_edit.text()
98 Qt widget to visualize multiple buttons 101 super(ServiceButtonGeneralWidget, self).
__init__()
106 if rospy.has_param(
"~layout_yaml_file"):
112 QMessageBox.about(self,
"ERROR", message)
117 layout_yaml_file = rospy.get_param(
"~layout_yaml_file", layout_param)
118 resolved_layout_yaml_file = get_filename(
119 layout_yaml_file)[len(
"file://"):]
121 if not os.path.exists(resolved_layout_yaml_file):
123 layout_yaml_file, resolved_layout_yaml_file))
130 Parse yaml file and setup Buttons. Format of the yaml file should be: 131 - name: 'button name' (required) 132 image: 'path to image for icon' (optional) 133 image_size: 'width and height of icon' (optional) 134 service: 'service' (required) 135 column: 'column index' (optional, defaults to 0) 138 with open(yaml_file)
as f:
139 yaml_data = yaml.load(f)
141 direction =
'vertical' 143 if d.has_key(
'direction'):
144 if d[
'direction'] ==
'horizontal':
145 direction =
'horizontal' 147 direction =
'vertical' 151 column_indices = [d[
'column']
for d
in yaml_data]
152 if len(column_indices) > 1:
153 max_column_index = max(*column_indices)
155 max_column_index = column_indices[0]
156 if direction ==
'vertical':
159 for i
in range(max_column_index + 1)]
161 self.
layout = QVBoxLayout()
163 for i
in range(max_column_index + 1)]
165 for i
in range(max_column_index + 1)]
166 for button_data
in yaml_data:
168 if not button_data.has_key(
"name"):
169 self.
showError(
"name field is missed in yaml")
170 raise Exception(
"name field is missed in yaml")
171 if not button_data.has_key(
"service"):
172 self.
showError(
"service field is missed in yaml")
173 raise Exception(
"service field is missed in yaml")
175 button = QToolButton()
177 button = QRadioButton()
178 button.setSizePolicy(
179 QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred))
180 if button_data.has_key(
"image"):
181 image_file = get_filename(
182 button_data[
"image"])[len(
"file://"):]
183 if os.path.exists(image_file):
184 icon = QtGui.QIcon(image_file)
186 if button_data.has_key(
"image_size"):
187 button.setIconSize(QSize(
188 button_data[
"image_size"][0],
189 button_data[
"image_size"][1]))
191 button.setIconSize(QSize(100, 100))
192 if button_data.has_key(
"name"):
193 name = button_data[
'name']
195 if button_data.has_key(
'service_type'):
196 if button_data[
'service_type'] ==
'Trigger':
197 service_type = Trigger
198 elif button_data[
'service_type'] ==
'Empty':
200 elif button_data[
'service_type'] ==
'SetBool':
201 service_type = SetBool
203 raise Exception(
"Unsupported service type: {}".format(
204 button_data[
'service_type']))
207 if service_type == SetBool:
208 button.setCheckable(
True)
209 button.clicked.connect(
210 self.
buttonCallback(button_data[
'service'], service_type, button))
212 button.setToolButtonStyle(
213 QtCore.Qt.ToolButtonTextUnderIcon)
214 if ((self.
button_type ==
"radio" or service_type == SetBool)
215 and (
"default_value" in button_data
216 and button_data[
'default_value'])):
217 button.setChecked(
True)
218 self.
layout_boxes[button_data[
'column']].addWidget(button)
219 self.buttons.append(button)
223 self.layout.addWidget(group)
224 self.setLayout(self.
layout)
228 return function as callback 230 return lambda checked: self.
buttonCallbackImpl(checked, service_name, service_type, button)
233 srv = rospy.ServiceProxy(service_name, service_type)
235 if service_type == SetBool:
239 if hasattr(res,
'success'):
240 success = res.success
243 "Succeeded to call {}, but service response is res.success=False" 244 .format(service_name))
245 if service_type == SetBool
and not button
is None:
246 button.setChecked(
not checked)
247 except rospy.ServiceException
as e:
248 self.
showError(
"Failed to call %s" % service_name)
249 if service_type == SetBool
and not button
is None:
250 button.setChecked(
not checked)
254 instance_settings.set_value(
"layout_param", self.
_layout_param)
255 rospy.loginfo(
"save setting is called. %s" % self.
_layout_param)
258 if instance_settings.value(
"layout_param"):
261 rospy.loginfo(
"restore setting is called. %s" % self.
_layout_param)
268 "trigger configuration is called. %s" % self._dialog.value)