37 from python_qt_binding.QtGui
import QIcon, QImage, QPainter, QPixmap
38 from python_qt_binding.QtWidgets
import QMessageBox
39 from python_qt_binding.QtSvg
import QSvgRenderer
44 Logs a message with ``rospy.loginfo`` and displays a ``QMessageBox`` to the user
46 :param msg: Message to display.
48 :param obj: Parent object for the ``QMessageBox``
50 :param title: An optional title for the `QMessageBox``
57 box.setWindowTitle(title)
60 obj._message_box = box
65 Logs a message with ``rospy.logwarn`` and displays a ``QMessageBox`` to the user
67 :param msg: Message to display.
69 :param obj: Parent object for the ``QMessageBox``
71 :param title: An optional title for the `QMessageBox``
78 box.setWindowTitle(title)
81 obj._message_box = box
86 Logs a message with ``rospy.logerr`` and displays a ``QMessageBox`` to the user
88 :param msg: Message to display.
90 :param obj: Parent object for the ``QMessageBox``
92 :param title: An optional title for the `QMessageBox``
99 box.setWindowTitle(title)
102 obj._message_box = box
107 Helper class to easily access images and build QIcons out of lists of file names
115 Paths added will be searched for images by the _find_image function
116 Paths will be searched in revearse order by add time
117 The last path to be searched is always rqt_robot_dashboard/images
118 Subdirectories are not recursively searched
120 :param path: The path to add to the image paths list
125 def make_icon(self, image_list, mode=QIcon.Normal, state=QIcon.On):
127 Helper function to create QIcons from lists of image files
128 Warning: svg files interleaved with other files will not render correctly
130 :param image_list: list of image paths to layer into an icon.
131 :type image: list of str
132 :param mode: The mode of the QIcon to be created.
134 :param state: the state of the QIcon to be created.
137 if type(image_list)
is not list:
138 image_list = [image_list]
139 if len(image_list) <= 0:
140 raise TypeError(
'The list of images is empty.')
143 for item
in image_list:
144 if item[-4:].lower() ==
'.svg':
145 num_svg = num_svg + 1
147 if num_svg != len(image_list):
149 icon_pixmap = QPixmap()
150 icon_pixmap.load(image_list[0])
151 painter = QPainter(icon_pixmap)
152 for item
in image_list[1:]:
153 painter.drawPixmap(0, 0, QPixmap(item))
155 icon.addPixmap(icon_pixmap, mode, state)
160 renderer = QSvgRenderer(image_list[0])
161 icon_image = QImage(renderer.defaultSize(), QImage.Format_ARGB32)
163 painter = QPainter(icon_image)
164 renderer.render(painter)
165 if len(image_list) > 1:
166 for item
in image_list[1:]:
168 renderer.render(painter)
171 icon_pixmap = QPixmap()
172 icon_pixmap.convertFromImage(icon_image)
173 icon = QIcon(icon_pixmap)
178 Convenience function to help with finding images.
179 Path can either be specified as absolute paths or relative to any path in ``_image_paths``
181 :param path: The path or name of the image.
184 if os.path.exists(path):
187 if os.path.exists(os.path.join(image_path, path)):
188 return os.path.join(image_path, path)
189 elif '.' in path
and os.path.exists(os.path.join(image_path,
'nonsvg', path)):
190 return os.path.join(image_path,
'nonsvg', path)
191 return os.path.join(self.
_image_paths[-1],
'ic-missing-icon.svg')
193 def build_icon(self, image_name_list, mode=QIcon.Normal, state=QIcon.On):
195 Convenience function to create an icon from a list of file names
197 :param image_name_list: List of file image names to make into an icon
198 :type image_name_list: list of str
199 :param mode: The mode of the QIcon to be created.
201 :param state: the state of the QIcon to be created.
205 for name
in image_name_list:
207 return self.
make_icon(found_list, mode, state)
211 Sets up the icon lists for the button states.
212 There must be one index in icons for each state.
214 :raises IndexError: if ``icons`` is not a list of lists of strings
216 :param icons: A list of lists of strings to create icons for the states of this button.\
217 If only one is supplied then ok, warn, error, stale icons will be created with overlays
219 :param clicked_icons: A list of clicked state icons. len must equal icons
220 :type clicked_icons: list
221 :param suppress_overlays: if false and there is only one icon path supplied
222 :type suppress_overlays: bool
224 if clicked_icons
is not None and len(icons) != len(clicked_icons):
225 rospy.logerr(
"%s: icons and clicked states are unequal" % self.
_name)
226 icons = clicked_icons = [[
'ic-missing-icon.svg']]
227 if not (type(icons)
is list
and type(icons[0])
is list
and type(icons[0][0]
is str)):
228 raise(IndexError(
"icons must be a list of lists of strings"))
230 rospy.logerr(
"%s: Icons not supplied" % self.
_name)
231 icons = clicked_icons = [
'ic-missing-icon.svg']
232 if len(icons) == 1
and suppress_overlays ==
False:
233 if icons[0][0][-4].lower() ==
'.svg':
234 icons.append(icons[0] + [
'ol-warn-badge.svg'])
235 icons.append(icons[0] + [
'ol-err-badge.svg'])
236 icons.append(icons[0] + [
'ol-stale-badge.svg'])
238 icons.append(icons[0] + [
'warn-overlay.png'])
239 icons.append(icons[0] + [
'err-overlay.png'])
240 icons.append(icons[0] + [
'stale-overlay.png'])
241 if clicked_icons
is None:
244 clicked_icons.append(name + [
'ol-click.svg'])
248 clicked_icons_conv = []
249 for icon
in clicked_icons:
250 clicked_icons_conv.append(self.
build_icon(icon))
251 return (icons_conv, clicked_icons_conv)