def _keyframeRecorded(self):
     item = QTreeWidgetItem()
     title = "(#{}) ".format(self.playbackTree.topLevelItemCount()) + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
     item.setText(0, title)
     self.playbackTree.addTopLevelItem(item)
     self.playbackTree.scrollToItem(item)
     self.keyframeCount.setText("{} keyframe(s) recorded".format(self.playbackTree.topLevelItemCount()))
 def on_search_result(self, search_text, found, path, index, linenr, line):
     '''
     Slot to handle the signals for search result. This signals are forwarded used
     search_result_signal.
     '''
     if found and search_text == self.current_search_text:
         id = "%d:%s" % (index, path)
         self.search_results_fileset.add(path)
         item = (search_text, found, path, index)
         if item not in self.search_results:
             self.search_results.append((id, search_text, found, path, index, linenr, line))
         if self._wait_for_result:
             self._search_result_index += 1
             if index >= self._tabwidget.currentWidget().textCursor().position() or self._tabwidget.currentWidget().filename != path:
                 self._wait_for_result = False
                 self.search_result_signal.emit(search_text, found, path, index)
                 self.replace_button.setEnabled(True)
         pkg, rpath = package_name(os.path.dirname(path))
         itemstr = '%s [%s]' % (os.path.basename(path), pkg)
         if not self.found_files_list.findItems(itemstr, Qt.MatchExactly):
             list_item = QTreeWidgetItem(self.found_files_list)
             list_item.setText(0, itemstr)
             list_item.setToolTip(0, path)
             self.found_files_list.insertTopLevelItem(0, list_item)
             self.found_files_list.expandAll()
         for i in range(self.found_files_list.topLevelItemCount()):
             top_item = self.found_files_list.topLevelItem(i)
             if top_item.text(0) == itemstr:
                 sub_item_str = "%d: %s" % (linenr, line)
                 list_item2 = QTreeWidgetItem()
                 list_item2.setText(0, sub_item_str)
                 list_item2.setWhatsThis(0, id)
                 top_item.addChild(list_item2)
             #self.found_files_list.setVisible(len(self.search_results_fileset) > 0)
     self._update_label()
示例#3
0
    def _update_robot_list(self):
        self._widget.robot_list_tree_widget.clear()
        robot_list = self.teleop_app_info.robot_list

        for k in robot_list.values():
            robot_item = QTreeWidgetItem(self._widget.robot_list_tree_widget)
            robot_item.setText(0, k["name"].string)
            self.robot_item_list[robot_item] = k
示例#4
0
 def _update_implementation_tree(self, rapp):
     self._widget.implementation_tree_widget.clear()
     self.selected_impl = None
     self.impls = {}
     for impl in rapp['implementations']:
         impl_item = QTreeWidgetItem(
             self._widget.implementation_tree_widget)
         impl_item.setText(0, impl)
         self.impls[impl_item] = impl
 def _keyframeRecorded(self):
     item = QTreeWidgetItem()
     title = "(#{}) ".format(
         self.playbackTree.topLevelItemCount()) + time.strftime(
             '%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
     item.setText(0, title)
     self.playbackTree.addTopLevelItem(item)
     self.playbackTree.scrollToItem(item)
     self.keyframeCount.setText("{} keyframe(s) recorded".format(
         self.playbackTree.topLevelItemCount()))
示例#6
0
    def _refresh_resource_list(self, resource_list):
        self._lock.acquire()
        self.resource_list_tree_widget.clear()
        self.resource_item_list = {}

        for r in resource_list:
            uri = rocon_uri.parse(r)
            resource_item = QTreeWidgetItem(self.resource_list_tree_widget)
            resource_item.setText(0, uri.name.string)
            self.resource_item_list[resource_item] = r
        self._lock.release()
    def on_call_service_button_clicked(self):
        self.response_tree_widget.clear()

        request = self._service_info['service_class']._request_class()
        self.fill_message_slots(request, self._service_info['service_name'],
                                self._service_info['expressions'],
                                self._service_info['counter'])
        try:
            response = self._service_info['service_proxy'](request)
        except rospy.ServiceException as e:
            qWarning(
                'ServiceCaller.on_call_service_button_clicked(): request:\n%r'
                % (request))
            qWarning(
                'ServiceCaller.on_call_service_button_clicked(): error calling service "%s":\n%s'
                % (self._service_info['service_name'], e))
            top_level_item = QTreeWidgetItem()
            top_level_item.setText(self._column_index['service'], 'ERROR')
            top_level_item.setText(self._column_index['type'],
                                   'rospy.ServiceException')
            top_level_item.setText(self._column_index['expression'], str(e))
        else:
            #qDebug('ServiceCaller.on_call_service_button_clicked(): response: %r' % (response))
            top_level_item = self._recursive_create_widget_items(
                None, '/', response._type, response, is_editable=False)

        self.response_tree_widget.addTopLevelItem(top_level_item)
        # resize columns
        self.response_tree_widget.expandAll()
        for i in range(self.response_tree_widget.columnCount()):
            self.response_tree_widget.resizeColumnToContents(i)
    def _on_plans(self, msg):
        if self._plans == msg.plans:
            return
        self._plans = msg.plans

        mission_tree = self._widget.findChild(QTreeWidget, "missionTreeWidget")
        mission_tree.clear()
        contigency_combo = self._widget.findChild(QComboBox, "contigencyCombo")
        contigency_combo.clear()

        for plan in sorted(self._plans, key=lambda plan: plan.name):
            item = QTreeWidgetItem([plan.name])
            for entry in plan.entries:
                contigency = entry.contigency_plan
                if len(contigency) == 0:
                    contigency = "none"
                dist = str(entry.dist) if entry.dist != 0 else ""
                subitem = QTreeWidgetItem([entry.mission, str(entry.timeout.secs), contigency, entry.path, dist])
                item.setFlags(item.flags() | Qt.ItemIsEditable)
                item.addChild(subitem)
            mission_tree.addTopLevelItem(item)
            item.setExpanded(True)
            if plan.name != "main":
                contigency_combo.addItem(plan.name)
        contigency_combo.addItem("none")

        mission_combo = self._widget.findChild(QComboBox, "missionCombo")
        mission_combo.clear()
        mission_combo.addItems(sorted(msg.available_missions))
示例#9
0
    def _recursive_create_widget_items(self, parent, topic_name, type_name,
                                       message):
        if parent is self.topics_tree_widget:
            # show full topic name with preceding namespace on toplevel item
            topic_text = topic_name
        else:
            topic_text = topic_name.split('/')[-1]
            if '[' in topic_text:
                topic_text = topic_text[topic_text.index('['):]
        item = QTreeWidgetItem(parent)
        item.setText(self._column_index['topic'], topic_text)
        item.setText(self._column_index['type'], type_name)
        item.setData(0, Qt.UserRole, topic_name)
        self._tree_items[topic_name] = item
        if hasattr(message, '__slots__') and hasattr(message, '_slot_types'):
            for slot_name, type_name in zip(message.__slots__,
                                            message._slot_types):
                self._recursive_create_widget_items(
                    item, topic_name + '/' + slot_name, type_name,
                    getattr(message, slot_name))

        else:
            base_type_str, array_size = self._extract_array_info(type_name)
            try:
                base_instance = roslib.message.get_message_class(
                    base_type_str)()
            except ValueError:
                base_instance = None
            if array_size is not None and hasattr(base_instance, '__slots__'):
                for index in range(array_size):
                    self._recursive_create_widget_items(
                        item, topic_name + '[%d]' % index, base_type_str,
                        base_instance)
        return item
    def __init__(self,
                 parent=None,
                 logger=Logger(),
                 param=None,
                 name=str(),
                 namespace=str()):
        QTreeWidgetItem.__init__(self, parent)
        self.set_logger(logger)

        if param is not None:
            self.set_param(param)
        elif len(name) > 0:
            self.set_name(name)
        self.namespace = namespace
示例#11
0
 def _handle_operator_name_change(self, operatorName, combo):
     self.operatorView.clear()
     root = self.operatorView.invisibleRootItem()
     for i in range(len(self._parameter_label_list[operatorName])):
         # fetch types for combo box
         cmb = QComboBox()
         instance_client = rospy.ServiceProxy('/kcl_rosplan/get_current_instances', GetInstanceService)
         resp = instance_client(self._parameter_type_list[operatorName][i])
         for instancename in resp.instances:
             cmb.addItem(instancename,instancename)
         # create row
         item = QTreeWidgetItem(self.operatorView)
         item.setText(0, self._parameter_label_list[operatorName][i])
         item.setText(1, self._parameter_type_list[operatorName][i])
         self.operatorView.setItemWidget(item, 2, cmb)
示例#12
0
    def _create_item(self, status, select, expand_if_error):
        if (status.level == DiagnosticStatus.OK):
            parent_node = self._ok_node
        elif (status.level == DiagnosticStatus.WARN):
            parent_node = self._warning_node
        elif (status.level == -1) or (status.level == 3):
            parent_node = self._stale_node
        else:  # ERROR
            parent_node = self._error_node

        item = TreeItem(
            status,
            QTreeWidgetItem(parent_node,
                            [status.name + ": " + status.message]))
        item.tree_node.setData(0, Qt.UserRole, item)
        parent_node.addChild(item.tree_node)

        self._name_to_item[status.name] = item

        parent_node.sortChildren(0, Qt.AscendingOrder)

        if (select):
            item.tree_node.setSelected(True)

        if (expand_if_error and (status.level > 1 or status.level == -1)):
            parent_node.setExpanded(True)

        item.mark = True

        return item
    def __init__(self, topic="diagnostics"):
        super(RuntimeMonitorWidget, self).__init__()
        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_runtime_monitor'), 'resource', 'runtime_monitor_widget.ui')
        loadUi(ui_file, self)
        self.setObjectName('RuntimeMonitorWidget')

        self._mutex = threading.Lock()

        self._error_icon = QIcon.fromTheme('dialog-error')
        self._warning_icon = QIcon.fromTheme('dialog-warning')
        self._ok_icon = QIcon.fromTheme('dialog-information')

        self._stale_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Stale (0)'])
        self._stale_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._stale_node)

        self._error_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Errors (0)'])
        self._error_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._error_node)

        self._warning_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Warnings (0)'])
        self._warning_node.setIcon(0, self._warning_icon)
        self.tree_widget.addTopLevelItem(self._warning_node)

        self._ok_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Ok (0)'])
        self._ok_node.setIcon(0, self._ok_icon)
        self.tree_widget.addTopLevelItem(self._ok_node)
        self.tree_widget.itemSelectionChanged.connect(self._refresh_selection)
        self.keyPressEvent = self._on_key_press

        self._name_to_item = {}
        self._new_errors_callback = None

        self._subscriber = rospy.Subscriber(topic, DiagnosticArray, self._diagnostics_callback)

        self._previous_ros_time = rospy.Time.now()
        self._timer = QTimer()
        self._timer.timeout.connect(self._on_timer)
        self._timer.start(1000)

        self._msg_timer = QTimer()
        self._msg_timer.timeout.connect(self._update_messages)
        self._msg_timer.start(100)

        self._messages = []
        self._used_items = 0
示例#14
0
    def add_sensor(self, name, topic, ttype, freq):

        sensor = QTreeWidgetItem()
        sensor.setData(0, Qt.DisplayRole, name)
        sensor.setData(1, Qt.DisplayRole, topic)
        sensor.setData(2, Qt.DisplayRole, "0/" + str(freq))
        sensor.setData(3, Qt.DecorationRole, self.abnormal_image)
        self.sensors[name] = sensor
        self._widget.sensor_list.addTopLevelItem(sensor)

        self.ts_list[name] = []
        self.freq[name] = freq
        self.has_msg[name] = False
        rospy.Subscriber(topic,
                         ttype,
                         self.callback, (name, topic),
                         queue_size=10)
示例#15
0
    def __init__(self, topic="diagnostics"):
        super(RuntimeMonitorWidget, self).__init__()
        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_runtime_monitor'), 'resource',
                               'runtime_monitor_widget.ui')
        loadUi(ui_file, self)
        self.setObjectName('RuntimeMonitorWidget')

        self._mutex = threading.Lock()

        self._error_icon = QIcon.fromTheme('dialog-error')
        self._warning_icon = QIcon.fromTheme('dialog-warning')
        self._ok_icon = QIcon.fromTheme('dialog-information')

        self._stale_node = QTreeWidgetItem(
            self.tree_widget.invisibleRootItem(), ['Stale (0)'])
        self._stale_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._stale_node)

        self._error_node = QTreeWidgetItem(
            self.tree_widget.invisibleRootItem(), ['Errors (0)'])
        self._error_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._error_node)

        self._warning_node = QTreeWidgetItem(
            self.tree_widget.invisibleRootItem(), ['Warnings (0)'])
        self._warning_node.setIcon(0, self._warning_icon)
        self.tree_widget.addTopLevelItem(self._warning_node)

        self._ok_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(),
                                        ['Ok (0)'])
        self._ok_node.setIcon(0, self._ok_icon)
        self.tree_widget.addTopLevelItem(self._ok_node)
        self.tree_widget.itemSelectionChanged.connect(self._refresh_selection)
        self.keyPressEvent = self._on_key_press

        self._name_to_item = {}
        self._new_errors_callback = None

        self._subscriber = rospy.Subscriber(topic, DiagnosticArray,
                                            self._diagnostics_callback)

        self._previous_ros_time = rospy.Time.now()
        self._timer = QTimer()
        self._timer.timeout.connect(self._on_timer)
        self._timer.start(1000)

        self._msg_timer = QTimer()
        self._msg_timer.timeout.connect(self._update_messages)
        self._msg_timer.start(100)

        self._messages = []
        self._used_items = 0
示例#16
0
    def update_one_item(self, row, info):
        twi = QTreeWidgetItem()
        for col, field in enumerate(self.out_fields):
            val = info[field]
            twi.setText(col, self.format_strs[col] % val)
        self._table_widget.insertTopLevelItem(row, twi)

        for col, (key, func) in self.tooltips.iteritems():
            twi.setToolTip(col, func(info[key]))

        with self._selected_node_lock:
            if twi.text(0) == self._selected_node:
                twi.setSelected(True)

        self._table_widget.setItemHidden(
            twi,
            len(self.name_filter.findall(info['node_name'])) == 0)
示例#17
0
    def update_one_item(self, row, info):
        twi = QTreeWidgetItem()
        for col, field in enumerate(self.out_fields):
            val = info[field]
            twi.setText(col, self.format_strs[col] % val)
        self._table_widget.insertTopLevelItem(row, twi)

        for col, (key, func) in self.tooltips.iteritems():
            twi.setToolTip(col, func(info[key]))

        with self._selected_node_lock:
            if twi.text(0) == self._selected_node:
                twi.setSelected(True)

        self._table_widget.setItemHidden(twi, len(self.name_filter.findall(info['node_name'])) == 0)
示例#18
0
    def _update_rapp_list(self):
        self._widget.rapp_info_text.clear()
        self._widget.rapp_tree_widget.clear()
        self.rapps = {}
        rapps = self.qt_rapp_manager_info.rapps
        for k in rapps.values():
            rapp = QTreeWidgetItem(self._widget.rapp_tree_widget)
            rapp.setText(0, k["name"])
            self.rapps[rapp] = k

        self._widget.running_rapp_tree_widget.clear()
        rapps = self.qt_rapp_manager_info.running_rapps
        self._manage_buttons()
        for k in rapps.values():
            rapp = QTreeWidgetItem(self._widget.running_rapp_tree_widget)
            rapp.setText(0, k["name"])
            self.rapps[rapp] = k
 def _handle_operator_name_change(self, operatorName, combo):
     self.operatorView.clear()
     root = self.operatorView.invisibleRootItem()
     for i in range(len(self._parameter_label_list[operatorName])):
         # fetch types for combo box
         cmb = QComboBox()
         instance_client = rospy.ServiceProxy('/kcl_rosplan/get_current_instances', GetInstanceService)
         resp = instance_client(self._parameter_type_list[operatorName][i])
         for instancename in resp.instances:
             cmb.addItem(instancename,instancename)
         # create row
         item = QTreeWidgetItem(self.operatorView)
         item.setText(0, self._parameter_label_list[operatorName][i])
         item.setText(1, self._parameter_type_list[operatorName][i])
         self.operatorView.setItemWidget(item, 2, cmb)
示例#20
0
    def _update_service_list(self):
        self._widget.service_tree_widget.clear()
        self._widget.service_info_text.clear()
        self._widgetitem_service_pair = {}
        service_list = self.admin_app_interface.service_list

        for k in service_list.values():
            # Top service
            service_item = QTreeWidgetItem(self._widget.service_tree_widget)
            # service_item=QTreeWidgetItem()
            service_item.setText(0, k['name'])

            # set Top Level Font
            font = service_item.font(0)
            font.setPointSize(20)
            font.setBold(True)
            service_item.setFont(0, font)

            self._widgetitem_service_pair[service_item] = k
    def on_call_service_button_clicked(self):
        self.response_tree_widget.clear()

        request = self._service_info['service_class']._request_class()
        self.fill_message_slots(request, self._service_info['service_name'], self._service_info['expressions'], self._service_info['counter'])
        try:
            response = self._service_info['service_proxy'](request)
        except rospy.ServiceException as e:
            qWarning('ServiceCaller.on_call_service_button_clicked(): request:\n%r' % (request))
            qWarning('ServiceCaller.on_call_service_button_clicked(): error calling service "%s":\n%s' % (self._service_info['service_name'], e))
            top_level_item = QTreeWidgetItem()
            top_level_item.setText(self._column_index['service'], 'ERROR')
            top_level_item.setText(self._column_index['type'], 'rospy.ServiceException')
            top_level_item.setText(self._column_index['expression'], str(e))
        else:
            #qDebug('ServiceCaller.on_call_service_button_clicked(): response: %r' % (response))
            top_level_item = self._recursive_create_widget_items(None, '/', response._type, response, is_editable=False)

        self.response_tree_widget.addTopLevelItem(top_level_item)
        # resize columns
        self.response_tree_widget.expandAll()
        for i in range(self.response_tree_widget.columnCount()):
            self.response_tree_widget.resizeColumnToContents(i)
    def refresh_ctrlers(self):
        if self.cm_namespace_combo.count() == 0:
            # no controller managers found so there are no controllers to update
            # remove old controllers
            for old_ctrler_name in self._ctrlers.keys():
                self.remove_ctrler_from_list(old_ctrler_name)
            return

        ctrlman_ns = self.cm_namespace_combo.currentText()

        if self.ctrlman_ns_cur != ctrlman_ns:
            # new controller manager selected

            # remove old controllers from list from last CM
            for old_ctrler_name in self._ctrlers.keys():
                self.remove_ctrler_from_list(old_ctrler_name)
            self.ctrlman_ns_cur = ctrlman_ns

        rospy.wait_for_service(
            ctrlman_ns + '/controller_manager/list_controllers', 0.2)
        try:
            resp = self.list_ctrlers[ctrlman_ns].call(ListControllersRequest())
        except rospy.ServiceException as e:
            # TODO: display warning somehow
            return

        controller_list = resp.controller
        new_ctrlers = {}
        for c in controller_list:
            if c.name not in self._ctrlers:
                # new controller
                item = QTreeWidgetItem(self.ctrl_list_tree_widget)
                item.setData(0, Qt.UserRole, c.name)
                ctrler = {
                    'item': item,
                    'state': c.state,
                    'type': c.type,
                    'hw_iface': c.hardware_interface,
                    'resources': "[" + ", ".join(c.resources) + "]"
                }
                ctrler['item'].setText(self._column_index['name'], c.name)
                update_type = True
                update_state = True
            else:
                # controller already in list
                ctrler = self._ctrlers[c.name]
                update_type = False
                update_state = False
                if ctrler['type'] != c.type or ctrler[
                        'hw_iface'] != c.hardware_interface:
                    # total controller change
                    ctrler['state'] = c.state
                    ctrler['type'] = c.type
                    ctrler['hw_iface'] = c.hardware_interface
                    ctrler['resources'] = "[" + ", ".join(c.resources) + "]"
                    update_type = True
                if ctrler['state'] != c.state:
                    # state change
                    ctrler['state'] = c.state
                    update_state = True

            # update entries if needed
            if update_type:
                ctrler['item'].setText(self._column_index['type'],
                                       ctrler['type'])
                ctrler['item'].setText(self._column_index['hw_iface'],
                                       ctrler['hw_iface'])
                ctrler['item'].setText(self._column_index['resources'],
                                       ctrler['resources'])
            if update_state or update_type:
                ctrler['item'].setText(self._column_index['state'],
                                       ctrler['state'])
            new_ctrlers[c.name] = ctrler

        # remove missing controllers
        for old_ctrler_name in self._ctrlers.keys():
            if old_ctrler_name not in new_ctrlers:
                self.remove_ctrler_from_list(old_ctrler_name)

        # update current controllers
        self._ctrlers = new_ctrlers
示例#23
0
    def _update_service_list(self):
        self._widget.service_tree_widget.clear()
        self._widget.service_info_text.clear()
        self._widgetitem_service_pair = {}
        service_list = self.admin_app_info.service_list

        for k in service_list.values():
            #Top service
            service_item = QTreeWidgetItem(self._widget.service_tree_widget)
            #service_item=QTreeWidgetItem()
            service_item.setText(0, k['name'])

            #set Top Level Font
            font = service_item.font(0)
            font.setPointSize(20)
            font.setBold(True)
            service_item.setFont(0, font)

            #set client item
            for l in k["client_list"]:
                client_item = QTreeWidgetItem()
                client_item.setText(0, l)
                font = client_item.font(0)
                font.setPointSize(15)
                client_item.setFont(0, font)
                service_item.addChild(client_item)

            self._widgetitem_service_pair[service_item] = k

            #self._widget.service_tree_widget.addTopLevelItem(service_item)
        pass
示例#24
0
    def refresh_ctrlers(self):
        if self.cm_namespace_combo.count() == 0:
            # no controller managers found so there are no controllers to update
            # remove old controllers
            for old_ctrler_name in self._ctrlers.keys():
                self.remove_ctrler_from_list(old_ctrler_name)
            return

        ctrlman_ns = self.cm_namespace_combo.currentText()

        if self.ctrlman_ns_cur != ctrlman_ns:
            # new controller manager selected

            # remove old controllers from list from last CM
            for old_ctrler_name in self._ctrlers.keys():
                self.remove_ctrler_from_list(old_ctrler_name)
            self.ctrlman_ns_cur = ctrlman_ns

        rospy.wait_for_service(ctrlman_ns + '/controller_manager/list_controllers', 0.2)
        try:
            resp = self.list_ctrlers[ctrlman_ns].call(ListControllersRequest())
        except rospy.ServiceException as e:
            # TODO: display warning somehow
            return 

        controller_list = resp.controller
        new_ctrlers = {}
        for c in controller_list:
            if c.name not in self._ctrlers:
                # new controller
                item = QTreeWidgetItem(self.ctrl_list_tree_widget)
                item.setData(0, Qt.UserRole, c.name)
                ctrler = {'item' : item,
                          'state' : c.state,
                          'type' : c.type,
                          'hw_iface' : c.hardware_interface,
                          'resources' : "[" + ", ".join(c.resources) + "]"}
                ctrler['item'].setText(self._column_index['name'], c.name)
                update_type = True
                update_state = True
            else:
                # controller already in list
                ctrler = self._ctrlers[c.name]
                update_type = False
                update_state = False
                if ctrler['type'] != c.type or ctrler['hw_iface'] != c.hardware_interface:
                    # total controller change
                    ctrler['state'] = c.state
                    ctrler['type'] = c.type
                    ctrler['hw_iface'] = c.hardware_interface
                    ctrler['resources'] = "[" + ", ".join(c.resources) + "]"
                    update_type = True
                if ctrler['state'] != c.state:
                    # state change
                    ctrler['state'] = c.state
                    update_state = True

            # update entries if needed
            if update_type:
                ctrler['item'].setText(self._column_index['type'], ctrler['type'])
                ctrler['item'].setText(self._column_index['hw_iface'], ctrler['hw_iface'])
                ctrler['item'].setText(self._column_index['resources'], ctrler['resources'])
            if update_state or update_type:
                ctrler['item'].setText(self._column_index['state'], ctrler['state'])
            new_ctrlers[c.name] = ctrler

        # remove missing controllers
        for old_ctrler_name in self._ctrlers.keys():
            if old_ctrler_name not in new_ctrlers:
                self.remove_ctrler_from_list(old_ctrler_name)
                
        # update current controllers
        self._ctrlers = new_ctrlers
示例#25
0
class RuntimeMonitorWidget(QWidget):
    def __init__(self, topic="diagnostics"):
        super(RuntimeMonitorWidget, self).__init__()
        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_runtime_monitor'), 'resource',
                               'runtime_monitor_widget.ui')
        loadUi(ui_file, self)
        self.setObjectName('RuntimeMonitorWidget')

        self._mutex = threading.Lock()

        self._error_icon = QIcon.fromTheme('dialog-error')
        self._warning_icon = QIcon.fromTheme('dialog-warning')
        self._ok_icon = QIcon.fromTheme('dialog-information')

        self._stale_node = QTreeWidgetItem(
            self.tree_widget.invisibleRootItem(), ['Stale (0)'])
        self._stale_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._stale_node)

        self._error_node = QTreeWidgetItem(
            self.tree_widget.invisibleRootItem(), ['Errors (0)'])
        self._error_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._error_node)

        self._warning_node = QTreeWidgetItem(
            self.tree_widget.invisibleRootItem(), ['Warnings (0)'])
        self._warning_node.setIcon(0, self._warning_icon)
        self.tree_widget.addTopLevelItem(self._warning_node)

        self._ok_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(),
                                        ['Ok (0)'])
        self._ok_node.setIcon(0, self._ok_icon)
        self.tree_widget.addTopLevelItem(self._ok_node)
        self.tree_widget.itemSelectionChanged.connect(self._refresh_selection)
        self.keyPressEvent = self._on_key_press

        self._name_to_item = {}
        self._new_errors_callback = None

        self._subscriber = rospy.Subscriber(topic, DiagnosticArray,
                                            self._diagnostics_callback)

        self._previous_ros_time = rospy.Time.now()
        self._timer = QTimer()
        self._timer.timeout.connect(self._on_timer)
        self._timer.start(1000)

        self._msg_timer = QTimer()
        self._msg_timer.timeout.connect(self._update_messages)
        self._msg_timer.start(100)

        self._messages = []
        self._used_items = 0

    def __del__(self):
        self.shutdown()

    def shutdown(self):
        """
        Unregisters subscriber and stops timers
        """
        self._msg_timer.stop()
        self._timer.stop()

        if rospy.is_shutdown():
            return

        if self._subscriber:
            self._subscriber.unregister()
            self._subscriber = None

    def change_diagnostic_topic(self, topic):
        """
        Changes diagnostics topic name. Must be of type diagnostic_msgs/DiagnosticArray
        """
        if not topic:
            self.reset_monitor()
            return

        if self._subscriber:
            self._subscriber.unregister()
            self._subscriber = rospy.Subscriber(str(topic), DiagnosticArray,
                                                self._diagnostics_callback)
        self.reset_monitor()

    def reset_monitor(self):
        """
        Removes all values from monitor display, resets buffers
        """
        self._name_to_item = {}  # Reset all stale topics
        self._messages = []
        self._clear_tree()

    def _clear_tree(self):
        for index in range(self._stale_node.childCount()):
            self._stale_node.removeChild(self._stale_node.child(index))
        for index in range(self._error_node.childCount()):
            self._error_node.removeChild(self._error_node.child(index))
        for index in range(self._warning_node.childCount()):
            self._warning_node.removeChild(self._warning_node.child(index))
        for index in range(self._ok_node.childCount()):
            self._ok_node.removeChild(self._ok_node.child(index))
        self._update_root_labels()

    # Diagnostics callbacks (subscriber thread)
    def _diagnostics_callback(self, message):
        with self._mutex:
            self._messages.append(message)

    # Update display of messages from main thread
    def _update_messages(self):
        with self._mutex:
            messages = self._messages[:]
            self._messages = []

        had_errors = False
        for message in messages:
            for status in message.status:
                was_selected = False
                if (self._name_to_item.has_key(status.name)):
                    item = self._name_to_item[status.name]
                    if self.tree_widget.isItemSelected(item.tree_node):
                        was_selected = True
                    if (item.status.level == DiagnosticStatus.ERROR
                            and status.level != DiagnosticStatus.ERROR):
                        had_errors = True
                    self._update_item(item, status, was_selected)
                else:
                    self._create_item(status, was_selected, True)
                    if (status.level == DiagnosticStatus.ERROR):
                        had_errors = True

        if (had_errors and self._new_errors_callback != None):
            self._new_errors_callback()

        self._update_root_labels()
        self.update()
        self._refresh_selection()

    def _update_item(self, item, status, was_selected):
        change_parent = False
        if (item.status.level != status.level):
            change_parent = True
        if (change_parent):
            if (item.status.level == DiagnosticStatus.OK):
                self._ok_node.removeChild(item.tree_node)
            elif (item.status.level == DiagnosticStatus.WARN):
                self._warning_node.removeChild(item.tree_node)
            elif (item.status.level == -1) or (item.status.level == 3):
                self._stale_node.removeChild(item.tree_node)
            else:  # ERROR
                self._error_node.removeChild(item.tree_node)

            if (status.level == DiagnosticStatus.OK):
                parent_node = self._ok_node
            elif (status.level == DiagnosticStatus.WARN):
                parent_node = self._warning_node
            elif (status.level == -1) or (status.level == 3):
                parent_node = self._stale_node
            else:  # ERROR
                parent_node = self._error_node

            item.tree_node.setText(0, status.name + ": " + status.message)
            item.tree_node.setData(0, Qt.UserRole, item)
            parent_node.addChild(item.tree_node)

            # expand errors automatically
            if (status.level > 1 or status.level == -1):
                parent_node.setExpanded(True)

            parent_node.sortChildren(0, Qt.AscendingOrder)

            if (was_selected):
                self.tree_widget.setCurrentItem(item.tree_node)

        else:
            item.tree_node.setText(0, status.name + ": " + status.message)

        item.status = status

        if (was_selected):
            self._fillout_info(item.tree_node)

        item.mark = True

    def _create_item(self, status, select, expand_if_error):
        if (status.level == DiagnosticStatus.OK):
            parent_node = self._ok_node
        elif (status.level == DiagnosticStatus.WARN):
            parent_node = self._warning_node
        elif (status.level == -1) or (status.level == 3):
            parent_node = self._stale_node
        else:  # ERROR
            parent_node = self._error_node

        item = TreeItem(
            status,
            QTreeWidgetItem(parent_node,
                            [status.name + ": " + status.message]))
        item.tree_node.setData(0, Qt.UserRole, item)
        parent_node.addChild(item.tree_node)

        self._name_to_item[status.name] = item

        parent_node.sortChildren(0, Qt.AscendingOrder)

        if (select):
            item.tree_node.setSelected(True)

        if (expand_if_error and (status.level > 1 or status.level == -1)):
            parent_node.setExpanded(True)

        item.mark = True

        return item

    def _fillout_info(self, node):
        item = node.data(0, Qt.UserRole)
        if not item:
            return

        scroll_value = self.html_browser.verticalScrollBar().value()
        status = item.status

        s = cStringIO.StringIO()

        s.write("<html><body>")
        s.write("<b>Component</b>: %s<br>\n" % (status.name))
        s.write("<b>Message</b>: %s<br>\n" % (status.message))
        s.write("<b>Hardware ID</b>: %s<br><br>\n\n" % (status.hardware_id))

        s.write('<table border="1" cellpadding="2" cellspacing="0">')
        for value in status.values:
            value.value = value.value.replace("\n", "<br>")
            s.write("<tr><td><b>%s</b></td> <td>%s</td></tr>\n" %
                    (value.key, value.value))

        s.write("</table></body></html>")

        self.html_browser.setHtml(s.getvalue())
        if self.html_browser.verticalScrollBar().maximum() < scroll_value:
            scroll_value = self.html_browser.verticalScrollBar().maximum()
        self.html_browser.verticalScrollBar().setValue(scroll_value)

    def _refresh_selection(self):
        current_item = self.tree_widget.selectedItems()
        if current_item:
            self._fillout_info(current_item[0])

    def _on_key_press(self, event):
        key = event.key()
        if key == Qt.Key_Delete:
            nodes = self.tree_widget.selectedItems()
            if (nodes != []
                    and nodes[0] not in (self._ok_node, self._warning_node,
                                         self._stale_node, self._error_node)):
                item = nodes[0].data(0, Qt.UserRole)
                if (item.status.level == 0):
                    self._ok_node.removeChild(item.tree_node)
                elif (item.status.level == 1):
                    self._warning_node.removeChild(item.tree_node)
                elif (item.status.level == -1) or (item.status.level == 3):
                    self._stale_node.removeChild(item.tree_node)
                else:
                    self._error_node.removeChild(item.tree_node)
                del self._name_to_item[item.status.name]
            self._update_root_labels()
            self.update()
            event.accept()
        else:
            event.ignore()

    def _on_timer(self):
        if self._previous_ros_time + rospy.Duration(5) > rospy.Time.now():
            return
        self._previous_ros_time = rospy.Time.now()
        for name, item in self._name_to_item.iteritems():
            node = item.tree_node
            if (item != None):
                if (not item.mark):
                    was_selected = False
                    selected = self.tree_widget.selectedItems()
                    if selected != [] and selected[0] == node:
                        was_selected = True

                    new_status = copy.deepcopy(item.status)
                    new_status.level = -1  # mark stale
                    self._update_item(item, new_status, was_selected)
                item.mark = False
        self._update_root_labels()
        self.update()

    def set_new_errors_callback(self, callback):
        self._new_errors_callback = callback

    def _update_root_labels(self):
        self._stale_node.setText(
            0, "Stale (%s)" % (self._stale_node.childCount()))
        self._error_node.setText(
            0, "Errors (%s)" % (self._error_node.childCount()))
        self._warning_node.setText(
            0, "Warnings (%s)" % (self._warning_node.childCount()))
        self._ok_node.setText(0, "Ok (%s)" % (self._ok_node.childCount()))
示例#26
0
    def _add_msg_object(self, parent, path, name, obj, obj_type):
        label = name

        if hasattr(obj, '__slots__'):
            subobjs = [(slot, getattr(obj, slot)) for slot in obj.__slots__]
        elif type(obj) in [list, tuple]:
            len_obj = len(obj)
            if len_obj == 0:
                subobjs = []
            else:
                w = int(math.ceil(math.log10(len_obj)))
                subobjs = [('[%*d]' % (w, i), subobj) for (i, subobj) in enumerate(obj)]
        else:
            subobjs = []

        plotitem=False
        if type(obj) in [int, long, float]:
            plotitem=True
            if type(obj) == float:
                obj_repr = '%.6f' % obj
            else:
                obj_repr = str(obj)

            if obj_repr[0] == '-':
                label += ': %s' % obj_repr
            else:
                label += ':  %s' % obj_repr

        elif type(obj) in [str, bool, int, long, float, complex, rospy.Time]:
            # Ignore any binary data
            obj_repr = codecs.utf_8_decode(str(obj), 'ignore')[0]

            # Truncate long representations
            if len(obj_repr) >= 50:
                obj_repr = obj_repr[:50] + '...'

            label += ': ' + obj_repr
        item = QTreeWidgetItem([label])
        if name == '':
            pass
        elif path.find('.') == -1 and path.find('[') == -1:
            self.addTopLevelItem(item)
        else:
            parent.addChild(item)
        if plotitem == True:
            if path.replace(' ', '') in self._checked_states:
                item.setCheckState (0, Qt.Checked)
            else:
                item.setCheckState (0, Qt.Unchecked)
        item.setData(0, Qt.UserRole, (path, obj_type))


        for subobj_name, subobj in subobjs:
            if subobj is None:
                continue

            if path == '':
                subpath = subobj_name  # root field
            elif subobj_name.startswith('['):
                subpath = '%s%s' % (path, subobj_name)  # list, dict, or tuple
            else:
                subpath = '%s.%s' % (path, subobj_name)  # attribute (prefix with '.')

            if hasattr(subobj, '_type'):
                subobj_type = subobj._type
            else:
                subobj_type = type(subobj).__name__

            self._add_msg_object(item, subpath, subobj_name, subobj, subobj_type)
    def loadLocation(self):
        self.startTrajectoryButton.setEnabled(False)
        self.startButton.setEnabled(False)
        self.addButton.setEnabled(False)
        self.openHandButton.setEnabled(False)
        self.closeHandButton.setEnabled(False)
        self.endButton.setEnabled(False)

        location = self.demoLocation.text()
        if os.path.isdir(location):
            locations = [os.path.join(location, f) for f in os.listdir(location) if os.path.isfile(os.path.join(location, f)) and f.split(".")[-1] == "bag"]
        else:
            locations = [location]

        if len(locations) == 0 or len(locations[0]) == 0:
            return
        
        self.keyframeCount.setText("")
        self.playbackTree.clear()
        self.zeroMarker.clear()
        self._showStatus("Parsing...")
        
        totalFrames = 0
        for location in sorted(locations):
            try:
                self.keyframeBagInterface = KeyframeBagInterface()
                parsedData = self.keyframeBagInterface.parse(location)
                objectsInScene = self.keyframeBagInterface.parseContainedObjects(location)
            except (rosbag.bag.ROSBagException, ParseException) as err:
                self._showStatus(str(err))
                rospy.logwarn("[%s] %s", location, str(err))
                self.playbackTree.clear()
                return
            totalFrames += len(parsedData)

            objectLabels = []
            for item in objectsInScene:
                label = item.label
                if objectLabels.count(label) > 0:
                    label = "{} #{}".format(label, objectLabels.count(label) + 1)
                objectLabels.append(item.label)

                if len(locations) > 1:
                    self.zeroMarker.addItem(u"{} → {}".format(label, os.path.basename(location)))
                else:
                    self.zeroMarker.addItem(label)

            items = []
            for i, keyframe in enumerate(parsedData):
                item = QTreeWidgetItem()
                title = "(#{}) ".format(i) + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(keyframe["time"]))
                item.setText(0, title)
                # Add children
                for topic in sorted(keyframe["data"]):
                    data = keyframe["data"][topic]
                    topicItem = QTreeWidgetItem()
                    topicItem.setText(0, topic)
                    for attribute in sorted(data):
                        attributeValueItem = QTreeWidgetItem()
                        attributeValueItem.setText(0, attribute)
                        attributeValueItem.setText(1, str(data[attribute]))
                        topicItem.addChild(attributeValueItem)
                    item.addChild(topicItem)
                items.append(item)
            if len(locations) == 1:
                self.playbackTree.addTopLevelItems(items)
            else:
                item = QTreeWidgetItem()
                item.setText(0, location)
                item.addChildren(items)
                self.playbackTree.addTopLevelItem(item)
        
        if len(locations) == 1:
            self.demoName.setText(os.path.basename(locations[0]))
            self.keyframeCount.setText("{} keyframe(s) loaded".format(totalFrames))
        else:
            self.demoName.setText(os.path.basename(self.demoLocation.text()) + os.path.sep)
            self.keyframeCount.setText("{} keyframe(s) loaded from {} files".format(totalFrames, len(locations)))
        self._showStatus("Parsed {} keyframe(s).".format(totalFrames))
        self.playDemoButton.setEnabled(True)
        if self.locateObjectsBox.isChecked():
            self.zeroMarker.setEnabled(True)
示例#28
0
 def disp_err(self, msg):
     i = QTreeWidgetItem()
     i.setText(0, msg)
     self.err.addTopLevelItem(i)
示例#29
0
 def disp_warn(self,msg):
     i = QTreeWidgetItem()
     i.setText(0, msg)
     self.warn.addTopLevelItem(i)
示例#30
0
 def on_show_details(self):
     '''
     Shows the subsystem in a new dialog as tree view.
     '''
     twc = self._detailed_dialog.treewidget_components
     twc.clear()
     client_info = "OCU client: ---"
     if self._ocu_client is not None:
         add_info = ''
         if self.ocu_client.subsystem_restricted == self.subsystem_id:
             if self.ocu_client.only_monitor:
                 add_info = ' [restricted, only monitor]'
             else:
                 add_info = ' [restricted]'
         client_info = "OCU client: %s%s" % (self.ocu_client.address,
                                             add_info)
     self._detailed_dialog.label_info.setText(client_info)
     if self.name == self._subsystem.ident.name:
         for node in self._subsystem.nodes:
             node_item = QTreeWidgetItem(twc)
             node_name = node.ident.name if node.ident.name else "NODE"
             node_item.setText(
                 0, "%s [id: %d]" % (node_name, node.ident.address.node_id))
             for comp in node.components:
                 cmp_item = QTreeWidgetItem(node_item)
                 cmp_name = self._get_component_name(comp.address)
                 cmp_item.setText(
                     0, "%s [%d.%d.%d]" %
                     (cmp_name, comp.address.subsystem_id,
                      comp.address.node_id, comp.address.component_id))
                 twc.expandItem(node_item)
                 for srv in comp.services:
                     srv_item = QTreeWidgetItem(cmp_item)
                     srv_item.setText(
                         0, "%s v%d.%d" %
                         (srv.uri, srv.major_version, srv.minor_version))
     if self._detailed_dialog.isVisible():
         self._detailed_dialog.setFocus(Qt.ActiveWindowFocusReason)
     else:
         self._detailed_dialog.show()
 def refresh_tree(self):
     self.select_tree.itemChanged.disconnect()
     self.select_tree.clear()
     for joint_name in self.joint_names:
         item = QTreeWidgetItem(self.select_tree)
         item.setText(0, joint_name)
         item.setCheckState(0, Qt.Unchecked)
         item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
         for traj_name in ['position', 'velocity', 'acceleration', 'effort']:
             sub_item = QTreeWidgetItem(item)
             sub_item.setText(0, traj_name)
             sub_item.setCheckState(0, Qt.Unchecked)
             sub_item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
     self.select_tree.itemChanged.connect(self.update_checkbox)
class RuntimeMonitorWidget(QWidget):
    def __init__(self, topic="/diagnostics"):
        super(RuntimeMonitorWidget, self).__init__()
        ui_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'runtime_monitor_widget.ui')
        loadUi(ui_file, self)
        self.setObjectName('RuntimeMonitorWidget')

        self._mutex = threading.Lock()
    
        self._error_icon = QIcon.fromTheme('dialog-error')
        self._warning_icon = QIcon.fromTheme('dialog-warning')
        self._ok_icon = QIcon.fromTheme('dialog-information')

        self._stale_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Stale (0)'])
        self._stale_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._stale_node)

        self._error_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Errors (0)'])
        self._error_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._error_node)

        self._warning_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Warnings (0)'])
        self._warning_node.setIcon(0, self._warning_icon)
        self.tree_widget.addTopLevelItem(self._warning_node)

        self._ok_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Ok (0)'])
        self._ok_node.setIcon(0, self._ok_icon)
        self.tree_widget.addTopLevelItem(self._ok_node)
        self.tree_widget.itemSelectionChanged.connect(self._on_item_selected)
        self.keyPressEvent = self._on_key_press

        self._name_to_item = {}
        self._new_errors_callback = None

        self._subscriber = rospy.Subscriber(topic, DiagnosticArray, self._diagnostics_callback)
        self._timer = QTimer()
        self._timer.timeout.connect(self._on_timer)
        self._timer.start(5000)

        self._messages = []
        self._used_items = 0

    def __del__(self):
        if self._subscriber is not None:
            self._subscriber.unregister()
            self._subscriber = None

    def shutdown(self):
        """
        Unregisters diagnostics subscriber for clean shutdown
        """
        if rospy.is_shutdown():
            return

        if self._subscriber is not None:
            self._subscriber.unregister()
            self._subscriber = None

    def change_diagnostic_topic(self, topic):
        """
        Changes diagnostics topic name. Must be of type diagnostic_msgs/DiagnosticArray
        """
        if len(topic) == 0:
            self.reset_monitor()
            return

        if self._subscriber is not None:
            self._subscriber.unregister()
            self._subscriber = rospy.Subscriber(str(topic), DiagnosticArray, self._diagnostics_callback)
        self.reset_monitor()

    def reset_monitor(self):
        """
        Removes all values from monitor display, resets buffers
        """
        self._name_to_item = {} # Reset all stale topics
        self._messages = []
        self._clear_tree()

    def _clear_tree(self):
        for index in range(self._stale_node.childCount()):
            self._stale_node.removeChild(self._stale_node.child(index))
        for index in range(self._error_node.childCount()):
            self._error_node.removeChild(self._error_node.child(index))
        for index in range(self._warning_node.childCount()):
            self._warning_node.removeChild(self._warning_node.child(index))
        for index in range(self._ok_node.childCount()):
            self._ok_node.removeChild(self._ok_node.child(index))
        self._update_root_labels()

    def _diagnostics_callback(self, message):
        with self._mutex:
            self._messages.append(message)
        
        self.new_message(rospy.get_rostime())

    def new_message(self, stamp = None):
        with self._mutex:
            had_errors = False
    
            for message in self._messages:
                for status in message.status:
                    was_selected = False
                    had_item = False
                    if (self._name_to_item.has_key(status.name)):
                        item = self._name_to_item[status.name]
                        had_item = True
                        if self.tree_widget.selectedItems() != [] and self.tree_widget.selectedItems()[0] == item:
                            was_selected = True
                        if (item.status.level == 2 and status.level != 2):
                            had_errors = True
                        self._update_item(item, status, was_selected, stamp)
                    else:
                        self._create_item(status, was_selected, True, stamp)
                        if (status.level == 2):
                            had_errors = True
            self._messages = []
    
        if (had_errors and self._new_errors_callback != None):
            self._new_errors_callback()

        self._update_root_labels()
        self.update()
      
    def _update_item(self, item, status, was_selected, stamp):
        change_parent = False
        if (item.status.level != status.level):
            change_parent = True
        if (change_parent):
            if (item.status.level == 0):
                self._ok_node.removeChild(item.tree_node)
            elif (item.status.level == 1):
                self._warning_node.removeChild(item.tree_node)
            elif (item.status.level == -1):
                self._stale_node.removeChild(item.tree_node)
            else:
                self._error_node.removeChild(item.tree_node)

            if (status.level == 0):
                parent_node = self._ok_node
            elif (status.level == 1):
                parent_node = self._warning_node
            elif (status.level == -1):
                parent_node = self._stale_node
            else:
                parent_node = self._error_node
            
            item.tree_node.setText(0, status.name + ": " + status.message)
            item.stamp = stamp
            item.tree_node.setData(0, Qt.UserRole, item)
            parent_node.addChild(item.tree_node)

            if (status.level > 1 or status.level == -1):
                parent_node.setExpanded(True)
      
            parent_node.sortChildren(0, Qt.AscendingOrder)
        
            if (was_selected):
                item.tree_node.setSelected(True)
      
        else:
            item.tree_node.setText(0, status.name + ": " + status.message)
      
        item.status = status
    
        if (was_selected):
            self._fillout_info(item.tree_node)
      
        item.mark = True
    
    def _create_item(self, status, select, expand_if_error, stamp):
        if (status.level == 0):
            parent_node = self._ok_node
        elif (status.level == 1):
            parent_node = self._warning_node
        elif (status.level == -1):
            parent_node = self._stale_node
        else:
            parent_node = self._error_node
        
        item = TreeItem(status, QTreeWidgetItem(parent_node, [status.name + ": " + status.message]), stamp)
        item.tree_node.setData(0, Qt.UserRole, item)
        parent_node.addChild(item.tree_node)
    
        self._name_to_item[status.name] = item
    
        parent_node.sortChildren(0, Qt.AscendingOrder)
    
        if (select):
            item.tree_node.setSelected(True)
        
        if (expand_if_error and (status.level > 1 or status.level == -1)):
            parent_node.setExpanded(True)
        
        item.mark = True
    
        return item
          
    def _fillout_info(self, node):
        item = node.data(0, Qt.UserRole)
        if (item == None):
            return
      
        status = item.status
    
        s = cStringIO.StringIO()
    
        s.write("<html><body>")
        s.write("<b>Component</b>: %s<br>\n" % (status.name))
        s.write("<b>Message</b>: %s<br>\n" % (status.message))
        s.write("<b>Hardware ID</b>: %s<br><br>\n\n" % (status.hardware_id)) 
    
        s.write('<table border="1" cellpadding="2" cellspacing="0">')
        for value in status.values:
            value.value = value.value.replace("\n", "<br>")
            s.write("<tr><td><b>%s</b></td> <td>%s</td></tr>\n" % (value.key, value.value))
        
        s.write("</table></body></html>")
        
        self.html_browser.setHtml(s.getvalue())
          
    def _on_item_selected(self):
        current_item = self.tree_widget.selectedItems()
        if current_item is not None:
            self._fillout_info(current_item[0])

    def _on_key_press(self, event):
        key = event.key()
        if key == Qt.Key_Delete:
            nodes = self.tree_widget.selectedItems()
            if (nodes != [] and nodes[0] not in (self._ok_node, self._warning_node, self._stale_node, self._error_node)):
                item = nodes[0].data(0, Qt.UserRole)
                if (item.status.level == 0):
                    self._ok_node.removeChild(item.tree_node)
                elif (item.status.level == 1):
                    self._warning_node.removeChild(item.tree_node)
                elif (item.status.level == -1):
                    self._stale_node.removeChild(item.tree_node)
                else:
                    self._error_node.removeChild(item.tree_node)
                del self._name_to_item[item.status.name]
        else:
            event.Skip()
        self._update_root_labels()    
        self.update()


    def _on_timer(self ):
        for name, item in self._name_to_item.iteritems():
            node = item.tree_node
            if (item != None):
                if (not item.mark):
                    was_selected = False
                    selected = self.tree_widget.selectedItems()
                    if selected != [] and selected[0] == node:
                        was_selected = True
      
                    new_status = copy.deepcopy(item.status)
                    new_status.level = -1
                    self._update_item(item, new_status, was_selected, item.stamp)
                item.mark = False
        self._update_root_labels()
        self.update()
      
    def set_new_errors_callback(self, callback):
        self._new_errors_callback = callback

    def get_num_errors(self):
        return self._error_node.childCount() + self._stale_node.childCount()
  
    def get_num_warnings(self):
        return self._warning_node.childCount()
  
    def get_num_ok(self):
        return self._ok_node.childCount()

    def _update_root_labels(self):
        self._stale_node.setText(0, "Stale (%s)" % (self._stale_node.childCount()))
        self._error_node.setText(0, "Errors (%s)" % (self._error_node.childCount()))
        self._warning_node.setText(0, "Warnings (%s)" % (self._warning_node.childCount()))
        self._ok_node.setText(0, "Ok (%s)" % (self._ok_node.childCount()))
    def loadLocation(self):
        self.startTrajectoryButton.setEnabled(False)
        self.startButton.setEnabled(False)
        self.addButton.setEnabled(False)
        self.openHandButton.setEnabled(False)
        self.closeHandButton.setEnabled(False)
        self.endButton.setEnabled(False)

        location = self.demoLocation.text()
        if os.path.isdir(location):
            locations = [
                os.path.join(location, f) for f in os.listdir(location)
                if os.path.isfile(os.path.join(location, f))
                and f.split(".")[-1] == "bag"
            ]
        else:
            locations = [location]

        if len(locations) == 0 or len(locations[0]) == 0:
            return

        self.keyframeCount.setText("")
        self.playbackTree.clear()
        self.zeroMarker.clear()
        self._showStatus("Parsing...")

        totalFrames = 0
        for location in sorted(locations):
            try:
                self.keyframeBagInterface = KeyframeBagInterface()
                parsedData = self.keyframeBagInterface.parse(location)
                objectsInScene = self.keyframeBagInterface.parseContainedObjects(
                    location)
            except (rosbag.bag.ROSBagException, ParseException) as err:
                self._showStatus(str(err))
                rospy.logwarn("[%s] %s", location, str(err))
                self.playbackTree.clear()
                return
            totalFrames += len(parsedData)

            objectLabels = []
            for item in objectsInScene:
                label = item.label
                if objectLabels.count(label) > 0:
                    label = "{} #{}".format(label,
                                            objectLabels.count(label) + 1)
                objectLabels.append(item.label)

                if len(locations) > 1:
                    self.zeroMarker.addItem(u"{} → {}".format(
                        label, os.path.basename(location)))
                else:
                    self.zeroMarker.addItem(label)

            items = []
            for i, keyframe in enumerate(parsedData):
                item = QTreeWidgetItem()
                title = "(#{}) ".format(i) + time.strftime(
                    '%Y-%m-%d %H:%M:%S', time.localtime(keyframe["time"]))
                item.setText(0, title)
                # Add children
                for topic in sorted(keyframe["data"]):
                    data = keyframe["data"][topic]
                    topicItem = QTreeWidgetItem()
                    topicItem.setText(0, topic)
                    for attribute in sorted(data):
                        attributeValueItem = QTreeWidgetItem()
                        attributeValueItem.setText(0, attribute)
                        attributeValueItem.setText(1, str(data[attribute]))
                        topicItem.addChild(attributeValueItem)
                    item.addChild(topicItem)
                items.append(item)
            if len(locations) == 1:
                self.playbackTree.addTopLevelItems(items)
            else:
                item = QTreeWidgetItem()
                item.setText(0, location)
                item.addChildren(items)
                self.playbackTree.addTopLevelItem(item)

        if len(locations) == 1:
            self.demoName.setText(os.path.basename(locations[0]))
            self.keyframeCount.setText(
                "{} keyframe(s) loaded".format(totalFrames))
        else:
            self.demoName.setText(
                os.path.basename(self.demoLocation.text()) + os.path.sep)
            self.keyframeCount.setText(
                "{} keyframe(s) loaded from {} files".format(
                    totalFrames, len(locations)))
        self._showStatus("Parsed {} keyframe(s).".format(totalFrames))
        self.playDemoButton.setEnabled(True)
        if self.locateObjectsBox.isChecked():
            self.zeroMarker.setEnabled(True)
    def _recursive_create_widget_items(self, parent, topic_name, type_name, message, is_editable=True):
        item = QTreeWidgetItem(parent)
        if is_editable:
            item.setFlags(item.flags() | Qt.ItemIsEditable)
        else:
            item.setFlags(item.flags() & (~Qt.ItemIsEditable))

        if parent is None:
            # show full topic name with preceding namespace on toplevel item
            topic_text = topic_name
        else:
            topic_text = topic_name.split('/')[-1]

        item.setText(self._column_index['service'], topic_text)
        item.setText(self._column_index['type'], type_name)

        item.setData(0, Qt.UserRole, topic_name)

        if hasattr(message, '__slots__') and hasattr(message, '_slot_types'):
            for slot_name, type_name in zip(message.__slots__, message._slot_types):
                self._recursive_create_widget_items(item, topic_name + '/' + slot_name, type_name, getattr(message, slot_name), is_editable)

        elif type(message) in (list, tuple) and (len(message) > 0) and hasattr(message[0], '__slots__'):
            type_name = type_name.split('[', 1)[0]
            for index, slot in enumerate(message):
                self._recursive_create_widget_items(item, topic_name + '[%d]' % index, type_name, slot, is_editable)

        else:
            item.setText(self._column_index['expression'], repr(message))

        return item
示例#35
0
    def _add_msg_object(self, parent, path, name, obj, obj_type):
        label = name

        if hasattr(obj, '__slots__'):
            subobjs = [(slot, getattr(obj, slot)) for slot in obj.__slots__]
        elif type(obj) in [list, tuple]:
            len_obj = len(obj)
            if len_obj == 0:
                subobjs = []
            else:
                w = int(math.ceil(math.log10(len_obj)))
                subobjs = [('[%*d]' % (w, i), subobj)
                           for (i, subobj) in enumerate(obj)]
        else:
            subobjs = []

        if type(obj) in [int, long, float]:
            if type(obj) == float:
                obj_repr = '%.6f' % obj
            else:
                obj_repr = str(obj)

            if obj_repr[0] == '-':
                label += ': %s' % obj_repr
            else:
                label += ':  %s' % obj_repr

        elif type(obj) in [str, bool, int, long, float, complex, rospy.Time]:
            # Ignore any binary data
            obj_repr = codecs.utf_8_decode(str(obj), 'ignore')[0]

            # Truncate long representations
            if len(obj_repr) >= 50:
                obj_repr = obj_repr[:50] + '...'

            label += ': ' + obj_repr
        item = QTreeWidgetItem([label])
        if name == 'msg':
            pass
        elif path.find('.') == -1 and path.find('[') == -1:
            self.addTopLevelItem(item)
        else:
            parent.addChild(item)
        item.setData(0, Qt.UserRole, (path, obj_type))

        for subobj_name, subobj in subobjs:
            if subobj is None:
                continue

            if path == '':
                subpath = subobj_name  # root field
            elif subobj_name.startswith('['):
                subpath = '%s%s' % (path, subobj_name)  # list, dict, or tuple
            else:
                subpath = '%s.%s' % (path, subobj_name
                                     )  # attribute (prefix with '.')

            if hasattr(subobj, '_type'):
                subobj_type = subobj._type
            else:
                subobj_type = type(subobj).__name__

            self._add_msg_object(item, subpath, subobj_name, subobj,
                                 subobj_type)
class RuntimeMonitorWidget(QWidget):
    def __init__(self, topic="diagnostics"):
        super(RuntimeMonitorWidget, self).__init__()
        rp = rospkg.RosPack()
        ui_file = os.path.join(rp.get_path('rqt_runtime_monitor'), 'resource', 'runtime_monitor_widget.ui')
        loadUi(ui_file, self)
        self.setObjectName('RuntimeMonitorWidget')

        self._mutex = threading.Lock()

        self._error_icon = QIcon.fromTheme('dialog-error')
        self._warning_icon = QIcon.fromTheme('dialog-warning')
        self._ok_icon = QIcon.fromTheme('dialog-information')

        self._stale_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Stale (0)'])
        self._stale_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._stale_node)

        self._error_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Errors (0)'])
        self._error_node.setIcon(0, self._error_icon)
        self.tree_widget.addTopLevelItem(self._error_node)

        self._warning_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Warnings (0)'])
        self._warning_node.setIcon(0, self._warning_icon)
        self.tree_widget.addTopLevelItem(self._warning_node)

        self._ok_node = QTreeWidgetItem(self.tree_widget.invisibleRootItem(), ['Ok (0)'])
        self._ok_node.setIcon(0, self._ok_icon)
        self.tree_widget.addTopLevelItem(self._ok_node)
        self.tree_widget.itemSelectionChanged.connect(self._refresh_selection)
        self.keyPressEvent = self._on_key_press

        self._name_to_item = {}
        self._new_errors_callback = None

        self._subscriber = rospy.Subscriber(topic, DiagnosticArray, self._diagnostics_callback)

        self._previous_ros_time = rospy.Time.now()
        self._timer = QTimer()
        self._timer.timeout.connect(self._on_timer)
        self._timer.start(1000)

        self._msg_timer = QTimer()
        self._msg_timer.timeout.connect(self._update_messages)
        self._msg_timer.start(100)

        self._messages = []
        self._used_items = 0

    def __del__(self):
        self.shutdown()
 
    def shutdown(self):
        """
        Unregisters subscriber and stops timers
        """
        self._msg_timer.stop()
        self._timer.stop()

        if rospy.is_shutdown():
            return

        if self._subscriber:
            self._subscriber.unregister()
            self._subscriber = None

    def change_diagnostic_topic(self, topic):
        """
        Changes diagnostics topic name. Must be of type diagnostic_msgs/DiagnosticArray
        """
        if not topic:
            self.reset_monitor()
            return

        if self._subscriber:
            self._subscriber.unregister()
            self._subscriber = rospy.Subscriber(str(topic), DiagnosticArray, self._diagnostics_callback)
        self.reset_monitor()

    def reset_monitor(self):
        """
        Removes all values from monitor display, resets buffers
        """
        self._name_to_item = {}  # Reset all stale topics
        self._messages = []
        self._clear_tree()

    def _clear_tree(self):
        for index in range(self._stale_node.childCount()):
            self._stale_node.removeChild(self._stale_node.child(index))
        for index in range(self._error_node.childCount()):
            self._error_node.removeChild(self._error_node.child(index))
        for index in range(self._warning_node.childCount()):
            self._warning_node.removeChild(self._warning_node.child(index))
        for index in range(self._ok_node.childCount()):
            self._ok_node.removeChild(self._ok_node.child(index))
        self._update_root_labels()

    # Diagnostics callbacks (subscriber thread)
    def _diagnostics_callback(self, message):
        with self._mutex:
            self._messages.append(message)

    # Update display of messages from main thread
    def _update_messages(self):
        with self._mutex:
            messages = self._messages[:]
            self._messages = []

        had_errors = False
        for message in messages:
            for status in message.status:
                was_selected = False
                if (self._name_to_item.has_key(status.name)):
                    item = self._name_to_item[status.name]
                    if self.tree_widget.isItemSelected(item.tree_node):
                        was_selected = True
                    if (item.status.level == DiagnosticStatus.ERROR and status.level != DiagnosticStatus.ERROR):
                        had_errors = True
                    self._update_item(item, status, was_selected)
                else:
                    self._create_item(status, was_selected, True)
                    if (status.level == DiagnosticStatus.ERROR):
                        had_errors = True

        if (had_errors and self._new_errors_callback != None):
            self._new_errors_callback()

        self._update_root_labels()
        self.update()
        self._refresh_selection()

    def _update_item(self, item, status, was_selected):
        change_parent = False
        if (item.status.level != status.level):
            change_parent = True
        if (change_parent):
            if (item.status.level == DiagnosticStatus.OK):
                self._ok_node.removeChild(item.tree_node)
            elif (item.status.level == DiagnosticStatus.WARN):
                self._warning_node.removeChild(item.tree_node)
            elif (item.status.level == -1) or (item.status.level == DiagnosticStatus.STALE):
                self._stale_node.removeChild(item.tree_node)
            else: # ERROR
                self._error_node.removeChild(item.tree_node)

            if (status.level == DiagnosticStatus.OK):
                parent_node = self._ok_node
            elif (status.level == DiagnosticStatus.WARN):
                parent_node = self._warning_node
            elif (status.level == -1) or (status.level == DiagnosticStatus.STALE):
                parent_node = self._stale_node
            else: # ERROR
                parent_node = self._error_node

            item.tree_node.setText(0, status.name + ": " + status.message)
            item.tree_node.setData(0, Qt.UserRole, item)
            parent_node.addChild(item.tree_node)

            # expand errors automatically
            if (status.level > 1 or status.level == -1):
                parent_node.setExpanded(True)

            parent_node.sortChildren(0, Qt.AscendingOrder)

            if (was_selected):
                self.tree_widget.setCurrentItem(item.tree_node)

        else:
            item.tree_node.setText(0, status.name + ": " + status.message)

        item.status = status

        if (was_selected):
            self._fillout_info(item.tree_node)

        item.mark = True

    def _create_item(self, status, select, expand_if_error):
        if (status.level == DiagnosticStatus.OK):
            parent_node = self._ok_node
        elif (status.level == DiagnosticStatus.WARN):
            parent_node = self._warning_node
        elif (status.level == -1) or (status.level == DiagnosticStatus.STALE):
            parent_node = self._stale_node
        else: # ERROR
            parent_node = self._error_node

        item = TreeItem(status, QTreeWidgetItem(parent_node, [status.name + ": " + status.message]))
        item.tree_node.setData(0, Qt.UserRole, item)
        parent_node.addChild(item.tree_node)

        self._name_to_item[status.name] = item

        parent_node.sortChildren(0, Qt.AscendingOrder)

        if (select):
            item.tree_node.setSelected(True)

        if (expand_if_error and (status.level > 1 or status.level == -1)):
            parent_node.setExpanded(True)

        item.mark = True

        return item

    def _fillout_info(self, node):
        item = node.data(0, Qt.UserRole)
        if not item:
            return

        scroll_value = self.html_browser.verticalScrollBar().value()
        status = item.status

        s = cStringIO.StringIO()

        s.write("<html><body>")
        s.write("<b>Component</b>: %s<br>\n" % (status.name))
        s.write("<b>Message</b>: %s<br>\n" % (status.message))
        s.write("<b>Hardware ID</b>: %s<br><br>\n\n" % (status.hardware_id))

        s.write('<table border="1" cellpadding="2" cellspacing="0">')
        for value in status.values:
            value.value = value.value.replace("\n", "<br>")
            s.write("<tr><td><b>%s</b></td> <td>%s</td></tr>\n" % (value.key, value.value))

        s.write("</table></body></html>")

        self.html_browser.setHtml(s.getvalue())
        if self.html_browser.verticalScrollBar().maximum() < scroll_value:
            scroll_value = self.html_browser.verticalScrollBar().maximum()
        self.html_browser.verticalScrollBar().setValue(scroll_value)

    def _refresh_selection(self):
        current_item = self.tree_widget.selectedItems()
        if current_item:
            self._fillout_info(current_item[0])

    def _on_key_press(self, event):
        key = event.key()
        if key == Qt.Key_Delete:
            nodes = self.tree_widget.selectedItems()
            if (nodes != [] and nodes[0] not in (self._ok_node, self._warning_node, self._stale_node, self._error_node)):
                item = nodes[0].data(0, Qt.UserRole)
                if (item.status.level == 0):
                    self._ok_node.removeChild(item.tree_node)
                elif (item.status.level == 1):
                    self._warning_node.removeChild(item.tree_node)
                elif (item.status.level == -1) or (item.status.level == DiagnosticStatus.STALE):
                    self._stale_node.removeChild(item.tree_node)
                else:
                    self._error_node.removeChild(item.tree_node)
                del self._name_to_item[item.status.name]
            self._update_root_labels()
            self.update()
            event.accept()
        else:
            event.ignore()

    def _on_timer(self):
        if self._previous_ros_time + rospy.Duration(5) > rospy.Time.now():
            return
        self._previous_ros_time = rospy.Time.now()
        for name, item in self._name_to_item.iteritems():
            node = item.tree_node
            if (item != None):
                if (not item.mark):
                    was_selected = False
                    selected = self.tree_widget.selectedItems()
                    if selected != [] and selected[0] == node:
                        was_selected = True

                    new_status = copy.deepcopy(item.status)
                    new_status.level = -1 # mark stale
                    self._update_item(item, new_status, was_selected)
                item.mark = False
        self._update_root_labels()
        self.update()

    def set_new_errors_callback(self, callback):
        self._new_errors_callback = callback

    def _update_root_labels(self):
        self._stale_node.setText(0, "Stale (%s)" % (self._stale_node.childCount()))
        self._error_node.setText(0, "Errors (%s)" % (self._error_node.childCount()))
        self._warning_node.setText(0, "Warnings (%s)" % (self._warning_node.childCount()))
        self._ok_node.setText(0, "Ok (%s)" % (self._ok_node.childCount()))
 def on_search_result(self, search_text, found, path, index, linenr, line):
     '''
     Slot to handle the signals for search result. This signals are forwarded used
     search_result_signal.
     '''
     if found and search_text == self.current_search_text:
         id = "%d:%s" % (index, path)
         self.search_results_fileset.add(path)
         item = (search_text, found, path, index)
         if item not in self.search_results:
             self.search_results.append(
                 (id, search_text, found, path, index, linenr, line))
         if self._wait_for_result:
             self._search_result_index += 1
             if index >= self._tabwidget.currentWidget().textCursor(
             ).position() or self._tabwidget.currentWidget(
             ).filename != path:
                 self._wait_for_result = False
                 self.search_result_signal.emit(search_text, found, path,
                                                index)
                 self.replace_button.setEnabled(True)
         pkg, rpath = package_name(os.path.dirname(path))
         itemstr = '%s [%s]' % (os.path.basename(path), pkg)
         if not self.found_files_list.findItems(itemstr, Qt.MatchExactly):
             list_item = QTreeWidgetItem(self.found_files_list)
             list_item.setText(0, itemstr)
             list_item.setToolTip(0, path)
             self.found_files_list.insertTopLevelItem(0, list_item)
             self.found_files_list.expandAll()
         for i in range(self.found_files_list.topLevelItemCount()):
             top_item = self.found_files_list.topLevelItem(i)
             if top_item.text(0) == itemstr:
                 sub_item_str = "%d: %s" % (linenr, line)
                 list_item2 = QTreeWidgetItem()
                 list_item2.setText(0, sub_item_str)
                 list_item2.setWhatsThis(0, id)
                 top_item.addChild(list_item2)
             #self.found_files_list.setVisible(len(self.search_results_fileset) > 0)
     self._update_label()
示例#38
0
    def _recursive_create_widget_items(self,
                                       parent,
                                       topic_name,
                                       type_name,
                                       message,
                                       is_editable=True):
        item = QTreeWidgetItem(parent)
        if is_editable:
            item.setFlags(item.flags() | Qt.ItemIsEditable)
        else:
            item.setFlags(item.flags() & (~Qt.ItemIsEditable))

        if parent is None:
            # show full topic name with preceding namespace on toplevel item
            topic_text = topic_name
        else:
            topic_text = topic_name.split('/')[-1]

        item.setText(self._column_index['service'], topic_text)
        item.setText(self._column_index['type'], type_name)

        item.setData(0, Qt.UserRole, topic_name)

        if hasattr(message, '__slots__') and hasattr(message, '_slot_types'):
            for slot_name, type_name in zip(message.__slots__,
                                            message._slot_types):
                self._recursive_create_widget_items(
                    item, topic_name + '/' + slot_name, type_name,
                    getattr(message, slot_name), is_editable)

        elif type(message) in (list, tuple) and (len(message) > 0) and hasattr(
                message[0], '__slots__'):
            type_name = type_name.split('[', 1)[0]
            for index, slot in enumerate(message):
                self._recursive_create_widget_items(
                    item, topic_name + '[%d]' % index, type_name, slot,
                    is_editable)

        else:
            item.setText(self._column_index['expression'], repr(message))

        return item
示例#39
0
 def refresh_plan(self):
     expanded_list = []
     root = self.planView.invisibleRootItem()
     child_count = root.childCount()
     for i in range(child_count):
         item = root.child(i)
         if item.isExpanded():
             expanded_list.append(item.text(
                 self._column_index['action_id']))
     self.planView.clear()
     for action in self._action_list:
         item = QTreeWidgetItem(self.planView)
         item.setText(self._column_index['action_id'],
                      str(action.action_id))
         item.setText(self._column_index['dispatch_time'],
                      str(action.dispatch_time))
         item.setText(self._column_index['duration'], str(action.duration))
         item.setText(self._column_index['status'],
                      self._status_list.get(str(action.action_id), "-"))
         action_name = '(' + action.name
         for keyval in action.parameters:
             param = QTreeWidgetItem(item)
             param.setText(self._column_index['action_id'], '')
             param.setText(self._column_index['action_name'],
                           '- ' + keyval.key + ': ' + keyval.value)
             param.setText(self._column_index['dispatch_time'], '')
             param.setText(self._column_index['duration'], '')
             param.setText(self._column_index['status'], '')
             action_name = action_name + ' ' + keyval.value
         item.setText(self._column_index['action_name'], action_name + ')')
         if str(action.action_id) in expanded_list:
             item.setExpanded(True)
 def refresh_tree(self):
     self.select_tree.itemChanged.disconnect()
     self.select_tree.clear()
     for joint_name in self.joint_names:
         item = QTreeWidgetItem(self.select_tree)
         item.setText(0, joint_name)
         item.setCheckState(0, Qt.Unchecked)
         item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
         for traj_name in [
                 'position', 'velocity', 'acceleration', 'effort'
         ]:
             sub_item = QTreeWidgetItem(item)
             sub_item.setText(0, traj_name)
             sub_item.setCheckState(0, Qt.Unchecked)
             sub_item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
     self.select_tree.itemChanged.connect(self.update_checkbox)