コード例 #1
0
    def add_item_to_conversation_view(self, msg, type=0):
        label_msg = QLabel(msg)
        label_msg.setWordWrap(True)
        label_msg.setStyleSheet('font-size:10pt;')

        inner_text_layout = QHBoxLayout()
        horizonalSpacer1 = QSpacerItem(0, 0, QSizePolicy.MinimumExpanding,
                                       QSizePolicy.MinimumExpanding)
        if type == 0:
            inner_text_layout.addWidget(label_msg)
            inner_text_layout.addItem(horizonalSpacer1)
        elif type == 1:
            inner_text_layout.addItem(horizonalSpacer1)
            inner_text_layout.addWidget(label_msg)

        inner_layout = QVBoxLayout()
        time_msg = QLabel(str(time.asctime(time.localtime(time.time()))))
        time_msg.setStyleSheet('font-size:8pt;')

        inner_layout.addItem(inner_text_layout)
        inner_layout.addWidget(time_msg)
        inner_layout.setSizeConstraint(QLayout.SetFixedSize)

        outer_layout = QHBoxLayout()
        horizonalSpacer2 = QSpacerItem(0, 0, QSizePolicy.MinimumExpanding,
                                       QSizePolicy.MinimumExpanding)
        if type == 0:
            label_msg.setStyleSheet(
                'background: #e5e5ea; padding: 6px; border-radius: 8px;')
            time_msg.setAlignment(Qt.AlignLeft)
            outer_layout.addItem(inner_layout)
            outer_layout.addItem(horizonalSpacer2)
        elif type == 1:
            label_msg.setStyleSheet(
                'background: #1d86f4; padding: 6px; border-radius: 8px; color:#fff;'
            )
            time_msg.setAlignment(Qt.AlignRight)
            outer_layout.addItem(horizonalSpacer2)
            outer_layout.addItem(inner_layout)
        outer_layout.setSizeConstraint(QLayout.SetMinimumSize)

        widget = QWidget()
        widget.setLayout(outer_layout)
        widget.resize(widget.sizeHint())

        item = QListWidgetItem()
        item.setSizeHint(widget.sizeHint())

        self._widget.listWidget.addItem(item)
        self._widget.listWidget.setItemWidget(item, widget)
        self._widget.listWidget.scrollToBottom()
コード例 #2
0
    def __init__(self, params, id_radio):
        super(inputDialog, self).__init__()

        self.id_radio = id_radio
        self.center()
        layout = QFormLayout()

        self.label_items = []
        self.label_comment = dict()
        self.client_answers_items = []
        self.greather_conditions = []
        self.button_clicked = False
        # print params
        for item in params:
            param = item[0]
            label = item[1]
            cond = item[2]
            if not label == "":
                label = " (%s)" % label
            self.greather_conditions.append((param, cond))
            label_item = QLabel(param + label, self)
            # self.label_items[param] = QLabel(param + label, self)
            label_item.setAlignment(Qt.AlignCenter)
            self.label_items.append(param)
            client_answers = QLineEdit()
            self.client_answers_items.append(client_answers)
            # self.label_comment[label] = QLabel(label, self)
            # self.label_comment[label].setAlignment(Qt.AlignCenter)
            # layout.addWidget(self.label_comment[label])
            layout.addRow(label_item, client_answers)

        self.ok_button = QPushButton("ok", self)
        self.ok_button.clicked.connect(self.onButtonClicked)

        layout.addWidget(self.ok_button)

        self.setLayout(layout)
        self.setWindowTitle("Update Parameters")

        self.show()
コード例 #3
0
ファイル: param_groups.py プロジェクト: Dieptranivsr/Ros_Diep
class GroupWidget(QWidget):
    """
    (Isaac's guess as of 12/13/2012)
    This class bonds multiple Editor instances that are associated with
    a single node as a group.
    """

    # public signal
    sig_node_disabled_selected = Signal(str)
    sig_node_state_change = Signal(bool)

    def __init__(self, updater, config, nodename):
        """
        :param config:
        :type config: Dictionary? defined in dynamic_reconfigure.client.Client
        :type nodename: str
        """
        super(GroupWidget, self).__init__()
        self.state = config['state']
        self.param_name = config['name']
        self._toplevel_treenode_name = nodename

        # TODO: .ui file needs to be back into usage in later phase.
        #        ui_file = os.path.join(rp.get_path('rqt_reconfigure'),
        #                               'resource', 'singlenode_parameditor.ui')
        #        loadUi(ui_file, self)

        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(QMargins(0, 0, 0, 0))

        _widget_nodeheader = QWidget()
        _h_layout_nodeheader = QHBoxLayout(_widget_nodeheader)
        _h_layout_nodeheader.setContentsMargins(QMargins(0, 0, 0, 0))

        self.nodename_qlabel = QLabel(self)
        font = QFont('Trebuchet MS, Bold')
        font.setUnderline(True)
        font.setBold(True)

        # Button to close a node.
        _icon_disable_node = QIcon.fromTheme('window-close')
        _bt_disable_node = QPushButton(_icon_disable_node, '', self)
        _bt_disable_node.setToolTip('Hide this node')
        _bt_disable_node_size = QSize(36, 24)
        _bt_disable_node.setFixedSize(_bt_disable_node_size)
        _bt_disable_node.pressed.connect(self._node_disable_bt_clicked)

        _h_layout_nodeheader.addWidget(self.nodename_qlabel)
        _h_layout_nodeheader.addWidget(_bt_disable_node)

        self.nodename_qlabel.setAlignment(Qt.AlignCenter)
        font.setPointSize(10)
        self.nodename_qlabel.setFont(font)
        grid_widget = QWidget(self)
        self.grid = QFormLayout(grid_widget)
        verticalLayout.addWidget(_widget_nodeheader)
        verticalLayout.addWidget(grid_widget, 1)
        # Again, these UI operation above needs to happen in .ui file.

        self.tab_bar = None  # Every group can have one tab bar
        self.tab_bar_shown = False

        self.updater = updater

        self.editor_widgets = []
        self._param_names = []

        self._create_node_widgets(config)

        logging.debug('Groups node name={}'.format(nodename))
        self.nodename_qlabel.setText(nodename)

        # Labels should not stretch
        # self.grid.setColumnStretch(1, 1)
        # self.setLayout(self.grid)

    def collect_paramnames(self, config):
        pass

    def _create_node_widgets(self, config):
        """
        :type config: Dict?
        """
        i_debug = 0
        for param in config['parameters']:
            begin = time.time() * 1000
            editor_type = '(none)'

            if param['edit_method']:
                widget = EnumEditor(self.updater, param)
            elif param['type'] in EDITOR_TYPES:
                logging.debug('GroupWidget i_debug={} param type ={}'.format(
                    i_debug, param['type']))
                editor_type = EDITOR_TYPES[param['type']]
                widget = eval(editor_type)(self.updater, param)

            self.editor_widgets.append(widget)
            self._param_names.append(param['name'])

            logging.debug(
                'groups._create_node_widgets num editors={}'.format(i_debug))

            end = time.time() * 1000
            time_elap = end - begin
            logging.debug('ParamG editor={} loop=#{} Time={}msec'.format(
                editor_type, i_debug, time_elap))
            i_debug += 1

        for name, group in sorted(config['groups'].items()):
            if group['type'] == 'tab':
                widget = TabGroup(self, self.updater, group,
                                  self._toplevel_treenode_name)
            elif group['type'] in _GROUP_TYPES.keys():
                widget = eval(_GROUP_TYPES[group['type']])(
                    self.updater, group, self._toplevel_treenode_name)
            else:
                widget = eval(_GROUP_TYPES[''])(self.updater, group,
                                                self._toplevel_treenode_name)

            self.editor_widgets.append(widget)
            logging.debug('groups._create_node_widgets name={}'.format(name))

        for i, ed in enumerate(self.editor_widgets):
            ed.display(self.grid)

        logging.debug('GroupWdgt._create_node_widgets'
                      ' len(editor_widgets)={}'.format(len(
                          self.editor_widgets)))

    def display(self, grid):
        grid.addRow(self)

    def update_group(self, config):
        if 'state' in config:
            old_state = self.state
            self.state = config['state']
            if self.state != old_state:
                self.sig_node_state_change.emit(self.state)

        names = [name for name in config.keys()]

        for widget in self.editor_widgets:
            if isinstance(widget, EditorWidget):
                if widget.param_name in names:
                    widget.update_value(config[widget.param_name])
            elif isinstance(widget, GroupWidget):
                cfg = find_cfg(config, widget.param_name) or config
                widget.update_group(cfg)

    def close(self):
        for w in self.editor_widgets:
            w.close()

    def get_treenode_names(self):
        """
        :rtype: str[]
        """
        return self._param_names

    def _node_disable_bt_clicked(self):
        logging.debug('param_gs _node_disable_bt_clicked')
        self.sig_node_disabled_selected.emit(self._toplevel_treenode_name)
コード例 #4
0
ファイル: bag_parser.py プロジェクト: matansar/rqt_mlp
class BagParser(QWidget):
    def __init__(self, bag_files, listtopics, duration):
        super(BagParser, self).__init__()

        # window title
        self.setWindowTitle("Making csv file")
        # size of window
        self.resize(960, 720)
        #self.showFullScreen()
        #self.setWindowState(Qt.WindowMaximized)

        # print listtopics
        # print E.get_general_features_options()
        # print E.get_specific_features_options()

        self.topics_items = dict()
        self.topics_items["0"] = listtopics
        self.topics_items["1"] = E.get_general_features_options()
        self.topics_items["2"] = E.get_specific_features_options()

        print self.topics_items

        #path to bag file
        self.bag_files = bag_files

        self.selected_bag_topics = []
        self.selected_specific_features = []
        self.selected_general_features = []

        self.items_list_topics = []

        self.area = QScrollArea(self)
        self.areagen = QScrollArea(self)
        self.areaspec = QScrollArea(self)
        self.main_widget = QWidget(self.area)
        self.main_widget1 = QWidget(self.areagen)
        self.main_widget2 = QWidget(self.areaspec)
        self.ok_button = QPushButton("Export To CSV", self)
        #self.ok_button.setFixedSize(150, 30)
        self.ok_button.clicked.connect(self.onButtonClicked)

        self.clear_button = QPushButton("Clear Selection", self)
        # self.clear_button.resize(self.clear_button.sizeHint())
        self.clear_button.clicked.connect(self.onClearClicked)

        self.choose_button = QPushButton("Get Last Export Choose", self)
        self.choose_button.clicked.connect(self.onButtonChooseCliked)
        self.ok_button.setEnabled(False)

        self.label1 = QLabel("Select topic from bag(s)", self)
        self.label1.setAlignment(Qt.AlignCenter)

        self.label2 = QLabel("Statistics Features", self)
        self.label2.setAlignment(Qt.AlignCenter)

        self.label3 = QLabel("Specific Features", self)
        self.label3.setAlignment(Qt.AlignCenter)

        self.duration = duration

        self.label5 = QLabel("Duration Time: " + str("%.1f" % duration), self)
        self.label5.setAlignment(Qt.AlignCenter)

        self.main_vlayout = QVBoxLayout(self)
        # self.main_vlayout = QGridLayout(self)
        self.main_vlayout.addWidget(self.label1)
        self.main_vlayout.addWidget(self.area)
        self.main_vlayout.addWidget(self.label2)
        self.main_vlayout.addWidget(self.areagen)
        self.main_vlayout.addWidget(self.label3)
        self.main_vlayout.addWidget(self.areaspec)

        self.label4 = QLabel("Window time", self)
        self.label4.setAlignment(Qt.AlignCenter)

        # self.main_vlayout.addWidget(self.label4)

        self.window = QLineEdit(self)
        # self.main_vlayout.addWidget(self.window)
        self.window.setText("1")

        self.windows_time_3 = QHBoxLayout(self)

        self.windows_time_3.addWidget(self.label4)

        self.windows_time_3.addWidget(self.window)

        self.windows_time_3.addWidget(self.label5)

        self.main_vlayout.addLayout(self.windows_time_3)

        # self.window = QLineEdit(self)
        # self.window.setText("1")

        # self.box = QVBoxLayout()
        # self.box.addStretch(1)
        # self.box.addWidget(self.clear_button)
        # self.box.addWidget(self.choose_button)
        # self.box.addWidget(self.label4)
        # self.box.addWidget(self.window)
        # self.box.addWidget(self.label5)
        # self.box.addWidget(self.ok_button)

        #self.main_vlayout.addWidget(self.from_nodes_button)

        # self.main_vlayout.addLayout(self.box)

        self.two_buttons = QHBoxLayout(self)

        self.two_buttons.addWidget(self.choose_button)

        self.two_buttons.addWidget(self.clear_button)

        self.main_vlayout.addLayout(self.two_buttons)

        self.main_vlayout.addWidget(self.ok_button)

        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)
        self.item_all = MyQCheckBox("All", self, self.selection_vlayout, None)
        self.item_all.stateChanged.connect(
            lambda x: self.updateList(x, self.item_all, None))
        self.selection_vlayout.addWidget(self.item_all)
        topic_data_list = listtopics
        topic_data_list.sort()
        for topic in topic_data_list:
            self.addCheckBox(topic, self.selection_vlayout,
                             self.selected_bag_topics)

        self.selection_vlayout1 = QVBoxLayout(self)
        self.item_all1 = MyQCheckBox("All", self, self.selection_vlayout1,
                                     None)
        self.item_all1.stateChanged.connect(
            lambda x: self.updateList(x, self.item_all1, None))
        self.selection_vlayout1.addWidget(self.item_all1)
        topic_data_list1 = E.get_general_features_options()
        topic_data_list1.sort()
        for topic in topic_data_list1:
            self.addCheckBox(topic, self.selection_vlayout1,
                             self.selected_general_features)

        self.selection_vlayout2 = QVBoxLayout(self)
        self.item_all2 = MyQCheckBox("All", self, self.selection_vlayout2,
                                     None)
        self.item_all2.stateChanged.connect(
            lambda x: self.updateList(x, self.item_all2, None))
        self.selection_vlayout2.addWidget(self.item_all2)
        topic_data_list2 = E.get_specific_features_options()
        topic_data_list2.sort()
        for topic in topic_data_list2:
            self.addCheckBox(topic, self.selection_vlayout2,
                             self.selected_specific_features)

        self.main_widget.setLayout(self.selection_vlayout)
        self.main_widget1.setLayout(self.selection_vlayout1)
        self.main_widget2.setLayout(self.selection_vlayout2)

        self.area.setWidget(self.main_widget)
        self.areagen.setWidget(self.main_widget1)
        self.areaspec.setWidget(self.main_widget2)
        self.show()

    def onClearClicked(self):
        self.clearTopicCheckState()

    def clearTopicCheckState(self):
        for item in self.items_list_topics:
            item.setCheckState(False)
        self.item_all.setCheckState(False)
        self.item_all1.setCheckState(False)
        self.item_all2.setCheckState(False)

    def addCheckBox(self, topic, selection_vlayout, selected_list):
        item = MyQCheckBox(topic, self, selection_vlayout, selected_list)
        item.stateChanged.connect(lambda x: self.updateList(x, item, topic))
        self.items_list_topics.append(item)
        selection_vlayout.addWidget(item)

    def changeTopicCheckState(self, topic, state):
        for item in self.items_list_topics:
            if item.text() == topic:
                item.setCheckState(state)
                return

    def updateList(self,
                   state,
                   item_clicked,
                   topic=None,
                   force_update_state=False):
        if topic is None:  # The "All" checkbox was checked / unchecked
            # print "if topic is None"
            if state == Qt.Checked:
                self.item_all.setTristate(False)
                for item in self.items_list_topics:
                    if item.checkState() == Qt.Unchecked and \
                            item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                self.item_all.setTristate(False)
                for item in self.items_list_topics:
                    if item.checkState() == Qt.Checked and \
                            item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Unchecked)
        else:
            # print "else:"
            if state == Qt.Checked:
                item_clicked.selected_list.append(topic)
                print item_clicked.selected_list
            else:
                item_clicked.selected_list.remove(topic)
                #if self.item_all.checkState() == Qt.Checked:
                #    self.item_all.setCheckState(Qt.PartiallyChecked)

        if self.selected_specific_features != []:
            if self.selected_general_features != [] and self.selected_bag_topics != []:
                self.ok_button.setEnabled(True)
            elif self.selected_general_features == [] and self.selected_bag_topics == []:
                self.ok_button.setEnabled(True)
            else:
                self.ok_button.setEnabled(False)
        else:
            if self.selected_general_features != [] and self.selected_bag_topics != []:
                self.ok_button.setEnabled(True)
            else:
                self.ok_button.setEnabled(False)

        # if self.selected_bag_topics != []:
        #     if self.selected_specific_features == [] and self.selected_general_features == []:
        #         self.ok_button.setEnabled(False)
        #     else:
        #         self.ok_button.setEnabled(True)
        #     # elif self.selected_specific_features != [] and self.selected_general_features == []:
        #     #     self.ok_button.setEnabled(True)
        #     # elif self.selected_specific_features == [] and self.selected_general_features != []:
        #     #     self.ok_button.setEnabled(True)
        # else:
        #     self.ok_button.setEnabled(False)

        # if self.selected_specific_features != []:
        #     if self.selected_bag_topics == [] and self.selected_general_features == []:
        #         self.ok_button.setEnabled(True)
        #     elif self.selected_bag_topics != [] and self.selected_general_features != []:
        #         self.ok_button.setEnabled(True)
        #     else:
        #         self.ok_button.setEnabled(False)
        # else:
        #     if self.selected_bag_topics == [] or self.selected_general_features == []:
        #         self.ok_button.setEnabled(False)
        #     else:
        #         self.ok_button.setEnabled(True)

    def onButtonChooseCliked(self):
        for checkbox in self.items_list_topics:
            checkbox.setCheckState(Qt.Unchecked)
        with open(get_path() + "logger.log", 'r') as f:
            topics = f.read().splitlines()
        for checkbox in self.items_list_topics:
            if checkbox.text() in topics:
                checkbox.setCheckState(Qt.Checked)

    def get_current_opened_directory(self, filepath):
        import os
        direc = "/"
        if os.path.isfile(filepath):
            with open(filepath, 'r') as f:
                direc = f.read()
        return direc

    def onButtonClicked(self):
        import inspect, os
        filepath = os.path.dirname(
            os.path.abspath(inspect.getfile(
                inspect.currentframe()))) + "/log/save_csv.log"
        current_directory = self.get_current_opened_directory(filepath)
        window = self.window.text()
        try:
            val = float(window)
        except ValueError:
            QMessageBox.about(self, "Error in Window Time",
                              "That's not a number!")
            return
        if val >= self.duration:
            QMessageBox.about(
                self, "Error in Window Time",
                "time need to be smaller than: " + str(self.duration))
            return
        # filename = QFileDialog.getSaveFileName(self, self.tr('csv File'), current_directory, self.tr('csv (*.csv)'))
        saved_dir = str(
            QFileDialog.getExistingDirectory(self, "Select Directory",
                                             current_directory))
        # if filename[0] != '':
        #     with open(filepath, "w") as f:
        #         f.write(filename[0])
        if saved_dir != '':
            with open(filepath, "w") as f:
                f.write(saved_dir)
            topics = self.selected_bag_topics
            specific_features_selection = self.selected_specific_features
            general_features_selection = self.selected_general_features
            with open(get_path() + 'logger.log', "w") as f:
                for topic in topics:
                    f.write(topic + "\n")
                for topic1 in specific_features_selection:
                    f.write(topic1 + "\n")
                for topic2 in general_features_selection:
                    f.write(topic2 + "\n")
            ef = E.ExtractFeatures(topics, float(window),
                                   specific_features_selection,
                                   general_features_selection)
            counter = 0
            for bag_file in self.bag_files:
                df = ef.generate_features(bag_file)
                if len(self.bag_files) == 1:
                    counter = -1
                # temp = filename + "/" +
                # temp = get_corrent_file_name(filename[0], ".csv", counter)
                csv_path = generate_csv_from_bag(saved_dir, bag_file)
                # temp = "%s_%s%s" % (filename[0],counter,".csv")
                E.write_to_csv(csv_path, df)
                counter = counter + 1
            QMessageBox.about(self, "csv export",
                              "csv was exported successfuly")
コード例 #5
0
ファイル: qt.py プロジェクト: zaxrok/py_trees_ros
class Dashboard(QWidget):

    _scan_button_led = Signal(bool)
    _cancel_button_led = Signal(bool)

    def __init__(self):
        super(Dashboard, self).__init__()

        not_latched = False
        # latched = True
        self.publishers = py_trees_ros.utilities.Publishers([
            ('scan', "~scan", std_msgs.Empty, not_latched, 1),
            ('cancel', "~cancel", std_msgs.Empty, not_latched, 1),
        ])

        self.scan_push_button = QPushButton("Scan")
        self.scan_push_button.setStyleSheet("QPushButton { font-size: 30pt; }")
        self.scan_push_button.setSizePolicy(QSizePolicy.Expanding,
                                            QSizePolicy.Expanding)
        self.scan_push_button.pressed.connect(
            functools.partial(self.publish_button_message,
                              self.publishers.scan))

        self.cancel_push_button = QPushButton("Cancel")
        self.cancel_push_button.setStyleSheet(
            "QPushButton { font-size: 30pt; }")
        self.cancel_push_button.setSizePolicy(QSizePolicy.Expanding,
                                              QSizePolicy.Expanding)
        self.cancel_push_button.pressed.connect(
            functools.partial(self.publish_button_message,
                              self.publishers.cancel))

        self.led_strip_flashing = False
        self.led_strip_on_count = 1
        self.led_strip_colour = "grey"

        self.led_strip_lock = threading.Lock()
        self.led_strip_timer = QTimer()
        self.led_strip_timer.timeout.connect(self.led_strip_timer_callback)
        self.led_strip_label = QLabel("LED Strip")
        self.led_strip_label.setAlignment(Qt.AlignCenter)
        self.led_strip_label.setSizePolicy(QSizePolicy.Expanding,
                                           QSizePolicy.Expanding)
        self.led_strip_label.setStyleSheet(
            "background-color: %s; font-size: 30pt;" % self.led_strip_colour)

        self.hbox_layout = QGridLayout(self)
        self.hbox_layout.addWidget(self.scan_push_button)
        self.hbox_layout.addWidget(self.cancel_push_button)
        self.hbox_layout.addWidget(self.led_strip_label)

        self.subscribers = py_trees_ros.utilities.Subscribers([
            ("report", "/tree/report", std_msgs.String,
             self.reality_report_callback),
            ("led_strip", "/led_strip/display", std_msgs.String,
             self.led_strip_display_callback)
        ])
        self.led_strip_timer.start(500)  # ms

    def publish_button_message(self, publisher):
        publisher.publish(std_msgs.Empty())

    def reality_report_callback(self, msg):
        if msg.data == "cancelling":
            self.set_scanning_colour(False)
            self.set_cancelling_colour(True)
            self.cancel_push_button.setEnabled(True)
        elif msg.data == "scanning":
            self.set_scanning_colour(True)
            self.set_cancelling_colour(False)
            self.cancel_push_button.setEnabled(True)
        else:
            self.set_scanning_colour(False)
            self.set_cancelling_colour(False)
            self.cancel_push_button.setEnabled(False)

    def set_cancelling_colour(self, val):
        if val:
            self.cancel_push_button.setStyleSheet(
                "QPushButton { font-size: 30pt; background-color: red}")
        else:
            self.cancel_push_button.setStyleSheet(
                "QPushButton { font-size: 30pt; }")

    def set_scanning_colour(self, val):
        if val:
            self.scan_push_button.setStyleSheet(
                "QPushButton { font-size: 30pt; background-color: green}")
        else:
            self.scan_push_button.setStyleSheet(
                "QPushButton { font-size: 30pt; }")

    def led_strip_display_callback(self, msg):
        with self.led_strip_lock:
            if not msg.data:
                self.led_strip_colour = "grey"
                self.led_strip_flashing = False
            else:
                self.led_strip_flashing = True
                self.led_strip_colour = None
                for colour in ["blue", "red", "green"]:
                    if colour in msg.data:
                        self.led_strip_colour = colour
                        break
                if not self.led_strip_colour:
                    self.led_strip_colour = "pink"
                    rospy.loginfo(
                        "Dashboard: received unknown LED colour {0}, setting 'pink'"
                        .format(msg.data))

    @Slot()
    def led_strip_timer_callback(self):
        with self.led_strip_lock:
            if self.led_strip_flashing:
                if self.led_strip_on_count > 0:
                    self.led_strip_on_count = 0
                    self.led_strip_label.setStyleSheet(
                        "background-color: none; font-size: 30pt;")
                else:
                    self.led_strip_on_count += 1
                    self.led_strip_label.setStyleSheet(
                        "background-color: %s; font-size: 30pt;" %
                        self.led_strip_colour)
            else:  # solid
                self.led_strip_on_count = 1
                self.led_strip_label.setStyleSheet(
                    "background-color: %s; font-size: 30pt;" %
                    self.led_strip_colour)
コード例 #6
0
class HistorySelection(QWidget):
    def __init__(self):
        super(HistorySelection, self).__init__()
        self.setWindowTitle("Extracting Window Features")
        self.resize(550, 440)

        per_title, pre = TS.get_time_series_pre_feature_options()
        glob_title, glob = TS.get_global_time_series_features_options()

        self.history_items = dict()
        self.history_items[per_title] = pre
        self.history_items[glob_title] = glob

        self.saved_dir = []

        self.group_selected_items = dict()
        self.group_areas = dict()
        self.group_main_widget = dict()
        self.group_selection_vlayout = dict()
        self.group_item_all = dict()
        self.main_vlayout = QVBoxLayout(self)
        self.group_label = dict()

        self.items_list = []
        self.selected_topics = []
        self.files = []

        # layout = QFormLayout()

        self.select_path = QLineEdit()
        self.save_path = QLineEdit()

        self.select_path.setEnabled(False)
        self.save_path.setEnabled(False)

        self.ok_button = QPushButton("Select CSV...", self)
        self.ok_button.clicked.connect(self.onButtonClicked)

        self.two_buttons1 = QHBoxLayout(self)

        self.two_buttons1.addWidget(self.ok_button)

        self.two_buttons1.addWidget(self.select_path)

        self.main_vlayout.addLayout(self.two_buttons1)

        # self.main_vlayout.addRow(self.ok_button, self.client_answers)

        # self.main_vlayout.addWidget(self.ok_button)

        # self.main_vlayout.addWidget(self.ok_button)

        for group_name in self.history_items:
            self.group_selected_items[group_name] = []
            self.group_areas[group_name] = QScrollArea(self)
            self.group_main_widget[group_name] = QWidget(
                self.group_areas[group_name])
            self.group_label[group_name] = QLabel(group_name, self)
            self.group_label[group_name].setAlignment(Qt.AlignCenter)
            self.main_vlayout.addWidget(self.group_label[group_name])
            self.main_vlayout.addWidget(self.group_areas[group_name])
            self.group_selection_vlayout[group_name] = QVBoxLayout(self)
            self.group_item_all[group_name] = MyQCheckBox(
                "All", self, self.group_selection_vlayout[group_name], None)
            self.MakeCheckBoxList(self.group_selection_vlayout[group_name],
                                  self.group_selected_items[group_name],
                                  self.history_items[group_name],
                                  self.group_item_all[group_name])
            self.group_main_widget[group_name].setLayout(
                self.group_selection_vlayout[group_name])
            self.group_areas[group_name].setWidget(
                self.group_main_widget[group_name])

        self.clear_button = QPushButton("Clear Selection", self)
        self.clear_button.clicked.connect(self.onClearClicked)

        self.choose_button = QPushButton("Get Last Export Choose", self)
        self.choose_button.clicked.connect(self.onButtonChooseCliked)

        # self.main_vlayout.addWidget(self.choose_button)

        self.label4 = QLabel("Window time", self)
        self.label4.setAlignment(Qt.AlignCenter)

        # self.main_vlayout.addWidget(self.label4)

        self.window = QLineEdit(self)
        # self.main_vlayout.addWidget(self.window)
        self.window.setText("3")

        self.label5 = QLabel("Duration Time:", self)
        self.label5.setAlignment(Qt.AlignCenter)

        self.label6 = QLabel("Step:", self)
        self.label6.setAlignment(Qt.AlignCenter)

        self.step = QLineEdit(self)
        self.step.setText("1")

        self.windows_time_3 = QHBoxLayout(self)

        self.windows_time_3.addWidget(self.label4)

        self.windows_time_3.addWidget(self.window)

        self.windows_time_3.addWidget(self.label5)

        self.main_vlayout.addLayout(self.windows_time_3)

        self.step_2 = QHBoxLayout(self)

        self.step_2.addWidget(self.label6)

        self.step_2.addWidget(self.step)

        self.main_vlayout.addLayout(self.step_2)

        # self.main_vlayout.addRow(self.label4, self.window)

        self.two_buttons = QHBoxLayout(self)

        self.two_buttons.addWidget(self.choose_button)

        self.two_buttons.addWidget(self.clear_button)

        self.main_vlayout.addLayout(self.two_buttons)

        # self.main_vlayout.addRow(self.clear_button, self.choose_button)

        # self.label5 = QLabel("Load CSV", self)
        # self.label5.setAlignment(Qt.AlignCenter)
        #
        # self.main_vlayout.addWidget(self.label5)

        # self.label6 = QLabel("output", self)
        # self.label6.setAlignment(Qt.AlignCenter)
        #
        # self.main_vlayout.addWidget(self.label6)

        self.save_button = QPushButton("Save CSV...", self)
        self.save_button.clicked.connect(self.onSaveClicked)

        self.submit_button = QPushButton("Sumbit", self)
        self.submit_button.clicked.connect(self.onSumbitClicked)

        # self.main_vlayout.addWidget(self.save_button)

        self.two_buttons2 = QHBoxLayout(self)

        self.two_buttons2.addWidget(self.save_button)

        self.two_buttons2.addWidget(self.save_path)

        self.main_vlayout.addLayout(self.two_buttons2)

        # self.main_vlayout.addRow(self.save_button, self.client_answers1)

        self.main_vlayout.addWidget(self.submit_button)

        self.show()

    def get_min_rows_csv(self, csv_files):
        import pandas as pd
        dfs = map(lambda x: pd.read_csv(x, header=0), csv_files)
        number = dfs[0].shape[0]
        number = reduce(lambda acc, curr: min(acc, curr.shape[0]), dfs, number)
        self.label5.setText("Duration Time: %s" % number)

    def onClearClicked(self):
        self.clearTopicCheckState()

    def clearTopicCheckState(self):
        for item in self.items_list:
            item.setCheckState(False)
        for item in self.group_item_all.values():
            item.setCheckState(False)

    def MakeCheckBoxList(self, selection_vlayout, selected, topics_Keys,
                         item_all):
        item_all.stateChanged.connect(
            lambda x: self.updateList(x, item_all, None))
        selection_vlayout.addWidget(item_all)
        topic_data_list = topics_Keys
        topic_data_list.sort()
        for topic in topic_data_list:
            self.addCheckBox(topic, selection_vlayout, selected)

    def addCheckBox(self, topic, selection_vlayout, selected_list):
        item = MyQCheckBox(topic, self, selection_vlayout, selected_list)
        item.stateChanged.connect(lambda x: self.updateList(x, item, topic))
        self.items_list.append(item)
        selection_vlayout.addWidget(item)

    def updateList(self,
                   state,
                   item_clicked,
                   topic=None,
                   force_update_state=False):
        if type(item_clicked) is str:
            item_clicked = self.get_item_by_name(item_clicked)
            if item_clicked is None:
                return
        if topic is None:  # The "All" checkbox was checked / unchecked
            # print "if topic is None"
            if state == Qt.Checked:
                # self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Unchecked and \
                                    item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                # self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Checked and \
                                    item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Unchecked)
        else:
            if state == Qt.Checked:
                item_clicked.selected_list.append(topic)
                # print item_clicked.selected_list
            else:
                item_clicked.selected_list.remove(topic)
                # if self.item_all.checkState() == Qt.Checked:
                #    self.item_all.setCheckState(Qt.PartiallyChecked)

    def get_current_opened_directory(self, filepath):
        import os
        direc = "/"
        if os.path.isfile(filepath):
            with open(filepath, 'r') as f:
                direc = f.read()
        return direc

    def onButtonClicked(self):
        import inspect, os
        filepath = os.path.dirname(
            os.path.abspath(inspect.getfile(
                inspect.currentframe()))) + "/log/select_history.log"
        fd = QFileDialog(self)
        wc = "Csv files {.csv} (*.csv)"
        self.files = []
        current_directory = self.get_current_opened_directory(filepath)
        tmp_pathes, filter = fd.getOpenFileNamesAndFilter(
            filter=wc, initialFilter=('*.csv'), directory=current_directory)
        for path in tmp_pathes:
            self.files.append(path.encode("utf-8"))
        # print self.files
        if len(self.files) != 0:
            self.get_min_rows_csv(tmp_pathes)
            self.select_path.setText(self.files[0])
            with open(filepath, "w") as f:
                f.write(self.files[0])

                # handler = logging.FileHandler(filepath, mode='w')
                # logger_topic.addHandler(handler)
                # logger_topic.info(self.files[0])
        else:
            self.select_path.setText("")

    def check_int(self, number, condition, title, message_body):
        try:
            # print type(number)
            val = int(number)
            if val <= condition:
                QMessageBox.about(self, title,
                                  "The number should > %s" % condition)
                return False
        except ValueError:
            QMessageBox.about(self, title, message_body)
            return False
        return True

    def check_choose(self):
        flag = True
        temp = []
        for item in self.group_selected_items.values():
            if item:
                for i in item:
                    temp.append(i)
        if len(temp) == 0:
            QMessageBox.about(self, "Features",
                              "One feature at least should be chosen")
            flag = False
        return flag

    def check_files_amount(self):
        flag = True
        if len(self.files) <= 0:
            QMessageBox.about(self, "Load CSV",
                              "One file at least should be chosen")
            flag = False
        return flag

    def check_validation(self):
        flag = self.check_files_amount()
        flag = flag & self.check_choose()
        flag = flag & self.check_int(self.window.text(), 2,
                                     "Error in Window Time",
                                     "That's not a number!")
        flag = flag & self.check_int(self.step.text(), 0, "Error in Step",
                                     "That's not a integer!")
        # TODO selected topic not empty

        if self.saved_dir == []:
            QMessageBox.about(self, "Save CSV", "Select path for saving")
            flag = False
        return flag

    def onSumbitClicked(self):
        if not self.check_validation():
            return
        self.selected_topics = []
        for item in self.group_selected_items.values():
            if item:
                for i in item:
                    self.selected_topics.append(i)
        # Defined Logging
        # handler = logging.FileHandler('/var/tmp/logger_history.log', mode='a')
        # logger_topic.addHandler(handler)
        topics = self.selected_topics
        with open(get_path() + 'logger_history.log', "w") as f:
            for topic in topics:
                f.write(topic + "\n")
        self.createTimeSeriesFeatures(self.files, self.saved_dir,
                                      int(self.window.text()),
                                      self.group_selected_items,
                                      int(self.step.text()))

    def onSaveClicked(self):
        import inspect, os
        filepath = os.path.dirname(
            os.path.abspath(inspect.getfile(
                inspect.currentframe()))) + "/log/save_history.log"
        # print self.files
        # print self.window.text()
        # print self.group_selected_items.values()

        # print self.group_selected_items
        current_directory = self.get_current_opened_directory(filepath)
        # print current_directory
        # self._to_save_filename = QFileDialog.getSaveFileName(self, self.tr('csv File'), current_directory,
        #                                                      self.tr('csv (*.csv)'))
        self.saved_dir = str(
            QFileDialog.getExistingDirectory(self, "Select Directory",
                                             current_directory))
        # if self._to_save_filename[0] != "":
        #     with open(filepath, "w") as f:
        #         f.write(self._to_save_filename[0])
        if self.saved_dir != "":
            with open(filepath, "w") as f:
                f.write(self.saved_dir)

                # handler = logging.FileHandler(filepath, mode='w')
                # logger_topic.addHandler(handler)
                # print self._to_save_filename[0]
                # logger_topic.info()
        # self.save_path.setText(get_corrent_file_name(self._to_save_filename[0], ".csv"))
        self.save_path.setText(self.saved_dir)

    def createTimeSeriesFeatures(self, files, saved_dir, window,
                                 group_selected_items, step):
        import TimeSeriesFeatures as TS
        # saved_dir = saved_dir[0].encode('utf-8')
        for input_path in files:
            output_path = generate_csv_from_bag(saved_dir, input_path)
            print "++++++++++++++++++++++++++ ", output_path
            print "in = %s out = %s " % (input_path, output_path)
            print "step = %s" % step
            ts = TS.TimeSeries(input_path, output_path, window,
                               group_selected_items, step)
            ts.generate_time_series_features()
        QMessageBox.about(self, "csv save", "csv was saved successfuly")

    def onButtonChooseCliked(self):
        for checkbox in self.items_list:
            checkbox.setCheckState(Qt.Unchecked)
        with open(get_path() + "logger_history.log", 'r') as f:
            topics = f.read().splitlines()
        for checkbox in self.items_list:
            if checkbox.text() in topics:
                checkbox.setCheckState(Qt.Checked)
コード例 #7
0
    def init_sliders(self):
        sliderbox = self._widget.findChild(QLayout, 'Sliders')

        graph_button = QPushButton()
        graph_button.setCheckable(True)
        graph_button.setText("Graph Off")
        graph_button.toggle()
        graph_button.clicked.connect(self.set_graph_state)
        self.graph_button = graph_button

        firstCol = QVBoxLayout()
        firstCol.addWidget(graph_button)

        sliderbox.addLayout(firstCol)

        self.sliders = []

        all_rows_layout = QVBoxLayout()
        chan_idx = 0
        for num_channels_row in self.settings['num_channels']:
            row_layout = QHBoxLayout()
            for i in range(num_channels_row):
                idx = chan_idx * 1

                slider_group = {
                    'slider_p': None,
                    'number_p': None,
                    'slider_v': None,
                    'number_v': None,
                    'on_off': None
                }

                layout_cluster = QVBoxLayout()
                slider_cluster = QHBoxLayout()
                label = QLabel()
                label.setText("Chan. %d" % (idx + 1))
                label.setAlignment(Qt.AlignCenter)
                layout_cluster.addWidget(label)
                for j in range(2):
                    layout = QVBoxLayout()
                    layout.setAlignment(Qt.AlignHCenter)

                    slider = QSlider(Qt.Vertical)
                    slider.setMinimum(0)
                    slider.setMaximum(255)
                    slider.setValue(
                        self.settings['valve_offsets'][chan_idx][j])
                    slider.setTickPosition(QSlider.TicksRight)
                    slider.setTickInterval(5)

                    spinbox = QSpinBox()
                    spinbox.setRange(0, 255)
                    spinbox.setValue(
                        self.settings['valve_offsets'][chan_idx][j])

                    slider.valueChanged.connect(spinbox.setValue)
                    spinbox.valueChanged.connect(slider.setValue)

                    cb_function_curr = lambda value, idx=idx: self.send_slider_value(
                        idx, value)
                    slider.valueChanged.connect(cb_function_curr)

                    label = QLabel()
                    label.setAlignment(Qt.AlignCenter)

                    if j == 0:
                        slider_group['slider_p'] = slider
                        slider_group['number_p'] = spinbox
                        label.setText("P")
                    else:
                        slider_group['slider_v'] = slider
                        slider_group['number_v'] = spinbox
                        label.setText("V")

                    labelmax = QLabel()
                    labelmax.setAlignment(Qt.AlignCenter)
                    labelmax.setText("255")

                    labelmin = QLabel()
                    labelmin.setAlignment(Qt.AlignCenter)
                    labelmin.setText("0")

                    layout.addWidget(label)
                    layout.addWidget(labelmax)
                    layout.addWidget(slider, Qt.AlignHCenter)
                    layout.addWidget(labelmin)
                    layout.addWidget(spinbox, Qt.AlignHCenter)
                    layout.setAlignment(slider, Qt.AlignHCenter)
                    layout.setAlignment(spinbox, Qt.AlignHCenter)

                    slider_cluster.addLayout(layout)

                on_button = QPushButton()
                on_button.setCheckable(True)
                on_button.setText("Off")

                if self.settings['channel_states'][chan_idx]:
                    on_button.toggle()
                    on_button.setText("On")

                on_button.clicked.connect(
                    lambda state, idx=idx: self.send_channel_state(idx, state))

                slider_group['on_off'] = on_button

                layout_cluster.addLayout(slider_cluster)
                layout_cluster.addWidget(on_button)

                row_layout.addLayout(layout_cluster)
                row_layout.addSpacing(20)

                self.sliders.append(slider_group)
                chan_idx += 1

            all_rows_layout.addLayout(row_layout)
        sliderbox.addLayout(all_rows_layout)
コード例 #8
0
class GroupWidget(QWidget):
    '''
    (Isaac's guess as of 12/13/2012)
    This class bonds multiple Editor instances that are associated with
    a single node as a group.
    '''

    # public signal
    sig_node_disabled_selected = Signal(str)
    sig_node_state_change = Signal(bool)

    def __init__(self, updater, config, nodename):
        '''
        :param config:
        :type config: Dictionary? defined in dynamic_reconfigure.client.Client
        :type nodename: str
        '''

        super(GroupWidget, self).__init__()
        self.state = config['state']
        self.param_name = config['name']
        self._toplevel_treenode_name = nodename

        # TODO: .ui file needs to be back into usage in later phase.
#        ui_file = os.path.join(rp.get_path('rqt_reconfigure'),
#                               'resource', 'singlenode_parameditor.ui')
#        loadUi(ui_file, self)

        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(QMargins(0, 0, 0, 0))

        _widget_nodeheader = QWidget()
        _h_layout_nodeheader = QHBoxLayout(_widget_nodeheader)
        _h_layout_nodeheader.setContentsMargins(QMargins(0, 0, 0, 0))

        self.nodename_qlabel = QLabel(self)
        font = QFont('Trebuchet MS, Bold')
        font.setUnderline(True)
        font.setBold(True)

        # Button to close a node.
        _icon_disable_node = QIcon.fromTheme('window-close')
        _bt_disable_node = QPushButton(_icon_disable_node, '', self)
        _bt_disable_node.setToolTip('Hide this node')
        _bt_disable_node_size = QSize(36, 24)
        _bt_disable_node.setFixedSize(_bt_disable_node_size)
        _bt_disable_node.pressed.connect(self._node_disable_bt_clicked)

        _h_layout_nodeheader.addWidget(self.nodename_qlabel)
        _h_layout_nodeheader.addWidget(_bt_disable_node)

        self.nodename_qlabel.setAlignment(Qt.AlignCenter)
        font.setPointSize(10)
        self.nodename_qlabel.setFont(font)
        grid_widget = QWidget(self)
        self.grid = QFormLayout(grid_widget)
        verticalLayout.addWidget(_widget_nodeheader)
        verticalLayout.addWidget(grid_widget, 1)
        # Again, these UI operation above needs to happen in .ui file.

        self.tab_bar = None  # Every group can have one tab bar
        self.tab_bar_shown = False

        self.updater = updater

        self.editor_widgets = []
        self._param_names = []

        self._create_node_widgets(config)

        rospy.logdebug('Groups node name={}'.format(nodename))
        self.nodename_qlabel.setText(nodename)

        # Labels should not stretch
        #self.grid.setColumnStretch(1, 1)
        #self.setLayout(self.grid)

    def collect_paramnames(self, config):
        pass

    def _create_node_widgets(self, config):
        '''
        :type config: Dict?
        '''
        i_debug = 0
        for param in config['parameters']:
            begin = time.time() * 1000
            editor_type = '(none)'

            if param['edit_method']:
                widget = EnumEditor(self.updater, param)
            elif param['type'] in EDITOR_TYPES:
                rospy.logdebug('GroupWidget i_debug=%d param type =%s',
                               i_debug,
                               param['type'])
                editor_type = EDITOR_TYPES[param['type']]
                widget = eval(editor_type)(self.updater, param)

            self.editor_widgets.append(widget)
            self._param_names.append(param['name'])

            rospy.logdebug('groups._create_node_widgets num editors=%d',
                           i_debug)

            end = time.time() * 1000
            time_elap = end - begin
            rospy.logdebug('ParamG editor={} loop=#{} Time={}msec'.format(
                                              editor_type, i_debug, time_elap))
            i_debug += 1

        for name, group in config['groups'].items():
            if group['type'] == 'tab':
                widget = TabGroup(self, self.updater, group, self._toplevel_treenode_name)
            elif group['type'] in _GROUP_TYPES.keys():
                widget = eval(_GROUP_TYPES[group['type']])(self.updater, group, self._toplevel_treenode_name)
            else:
                widget = eval(_GROUP_TYPES[''])(self.updater, group, self._toplevel_treenode_name)

            self.editor_widgets.append(widget)
            rospy.logdebug('groups._create_node_widgets ' +
                           'name=%s',
                           name)

        for i, ed in enumerate(self.editor_widgets):
            ed.display(self.grid)

        rospy.logdebug('GroupWdgt._create_node_widgets len(editor_widgets)=%d',
                       len(self.editor_widgets))

    def display(self, grid):
        grid.addRow(self)

    def update_group(self, config):
        if 'state' in config:
            old_state = self.state
            self.state = config['state']
            if self.state != old_state:
                self.sig_node_state_change.emit(self.state)

        names = [name for name in config.keys()]

        for widget in self.editor_widgets:
            if isinstance(widget, EditorWidget):
                if widget.param_name in names:
                    widget.update_value(config[widget.param_name])
            elif isinstance(widget, GroupWidget):
                cfg = find_cfg(config, widget.param_name)
                widget.update_group(cfg)

    def close(self):
        for w in self.editor_widgets:
            w.close()

    def get_treenode_names(self):
        '''
        :rtype: str[]
        '''
        return self._param_names

    def _node_disable_bt_clicked(self):
        rospy.logdebug('param_gs _node_disable_bt_clicked')
        self.sig_node_disabled_selected.emit(self._toplevel_treenode_name)
コード例 #9
0
    def init_sliders(self):
        sliderbox = self._widget.findChild(QLayout, 'Sliders')

        firstCol = QVBoxLayout()
        graph_button = QPushButton()
        graph_button.setCheckable(True)
        graph_button.setText("Graph Off")
        graph_button.toggle()
        graph_button.clicked.connect(self.set_graph_state)

        reset_button = QPushButton()
        reset_button.setCheckable(False)
        reset_button.setText("Reset")
        reset_button.clicked.connect(self.set_reset)

        self.graph_button = graph_button
        self.reset_button = reset_button

        firstCol.addWidget(graph_button)
        firstCol.addWidget(reset_button)

        firstCol.setAlignment(graph_button, Qt.AlignVCenter)
        firstCol.setAlignment(reset_button, Qt.AlignVCenter)

        zero_button = QPushButton()
        zero_button.setCheckable(False)
        zero_button.setText("Set All Zero")
        zero_button.clicked.connect(self.set_pressure_zero)
        self.zero_button = zero_button
        firstCol.addWidget(zero_button)
        firstCol.setAlignment(zero_button, Qt.AlignVCenter)

        transition_box = QVBoxLayout()
        label = QLabel()
        label.setAlignment(Qt.AlignCenter)
        label.setText("Transition Time")

        spinbox = QDoubleSpinBox()
        spinbox.setMinimum(0)
        spinbox.setMaximum(10)
        spinbox.setValue(self.settings['transitions'])
        spinbox.setDecimals(1)
        spinbox.setSingleStep(0.1)
        spinbox.setSuffix(" sec")

        spinbox.valueChanged.connect(self.set_transition_value)

        transition_box.addWidget(label)
        transition_box.addWidget(spinbox)
        transition_box.setAlignment(label, Qt.AlignBottom)
        transition_box.setAlignment(spinbox, Qt.AlignTop)
        firstCol.addLayout(transition_box)

        self.sliders = []
        sliderbox.addLayout(firstCol)

        all_rows_layout = QVBoxLayout()

        chan_idx = 0
        for num_channels_row in self.settings['num_channels']:
            row_layout = QHBoxLayout()
            for i in range(num_channels_row):
                idx = chan_idx * 1

                slider_group = {'slider': None, 'number': None, 'on_off': None}
                layout_cluster = QVBoxLayout()

                layout = QVBoxLayout()
                layout.setAlignment(Qt.AlignHCenter)

                slider = QSlider(Qt.Vertical)
                slider.setMinimum(self.settings['min_pressure'][idx] * 10.0)
                slider.setMaximum(self.settings['max_pressure'][idx] * 10.0)
                slider.setValue(0)
                slider.setTickPosition(QSlider.TicksRight)
                slider.setTickInterval(20)

                spinbox = QDoubleSpinBox()
                spinbox.setMinimum(self.settings['min_pressure'][idx])
                spinbox.setMaximum(self.settings['max_pressure'][idx])
                spinbox.setValue(0)
                spinbox.setDecimals(1)
                spinbox.setSingleStep(0.1)

                cb_function_curr = lambda value, idx=idx, slider=False: self.send_slider_value(
                    idx, value, slider)
                cb_function_curr2 = lambda value, idx=idx, slider=True: self.send_slider_value(
                    idx, value, slider)
                slider.valueChanged.connect(cb_function_curr2)
                spinbox.valueChanged.connect(cb_function_curr)

                labelmax = QLabel()
                labelmax.setAlignment(Qt.AlignCenter)
                labelmax.setText("%0.1f" %
                                 (self.settings['max_pressure'][idx]))

                labelmin = QLabel()
                labelmin.setAlignment(Qt.AlignCenter)
                labelmin.setText("%0.1f" %
                                 (self.settings['min_pressure'][idx]))

                layout.addWidget(labelmax)
                layout.addWidget(slider)
                layout.addWidget(labelmin)
                layout.addWidget(spinbox)

                layout.setAlignment(slider, Qt.AlignHCenter)
                layout.setAlignment(spinbox, Qt.AlignHCenter)

                label = QLabel()
                label.setText("Chan. %d" % (chan_idx + 1))
                label.setAlignment(Qt.AlignCenter)
                layout_cluster.addWidget(label)
                layout_cluster.addLayout(layout)

                slider_group['slider'] = slider
                slider_group['number'] = spinbox

                on_button = QPushButton()
                on_button.setCheckable(True)
                on_button.setText("Off")

                if self.settings['channel_states'][idx]:
                    on_button.toggle()
                    on_button.setText("On")

                on_button.clicked.connect(
                    lambda state, idx=idx: self.send_channel_state(idx, state))

                slider_group['on_off'] = on_button

                layout_cluster.addWidget(on_button)

                row_layout.addLayout(layout_cluster)
                row_layout.addSpacing(20)

                self.sliders.append(slider_group)

                chan_idx += 1

            all_rows_layout.addLayout(row_layout)

        sliderbox.addLayout(all_rows_layout)
コード例 #10
0
class HandEyeCalibration(Plugin):
    PLUGIN_TITLE = ' Intel OTC Robotics: Hand-Eye Calibration'

    def __init__(self, context):
        super(HandEyeCalibration, self).__init__(context)
        self.context = context
        self.node = context.node
        self.widget = QWidget()
        self.widget.setObjectName(self.PLUGIN_TITLE)
        self.widget.setWindowTitle(self.PLUGIN_TITLE)

        # Data
        self.Tsamples = []

        # Toolbar
        _, path_pkg = get_resource('packages', 'handeye_dashboard')
        print("{}".format(path_pkg))

        self.snapshot_action = QAction(QIcon.fromTheme('camera-photo'),
                                       'Take a snapshot', self.widget)
        path = path_pkg + '/share/handeye_dashboard/images/capture.png'
        self.calibrate_action = QAction(QIcon(QPixmap.fromImage(QImage(path))),
                                        'Get the camera/robot transform',
                                        self.widget)
        self.clear_action = QAction(QIcon.fromTheme('edit-clear'),
                                    'Clear the record data.', self.widget)
        path = path_pkg + '/share/handeye_dashboard/images/UR5.png'
        self.execut_action = QAction(QIcon(QPixmap.fromImage(QImage(path))),
                                     'EStart the publishing the TF.',
                                     self.widget)
        self.toolbar = QToolBar()
        self.toolbar.addAction(self.snapshot_action)
        self.toolbar.addAction(self.calibrate_action)
        self.toolbar.addAction(self.clear_action)
        self.toolbar.addAction(self.execut_action)

        # Toolbar0
        self.l0 = QLabel(self.widget)
        self.l0.setText("Camera-Mount-Type: ")
        self.l0.setFixedWidth(150)
        self.l0.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.combobox = QComboBox(self.widget)
        self.combobox.addItem('attached on robot')
        self.combobox.addItem('fixed beside robot')
        self.toolbar0 = QToolBar()
        self.toolbar0.addWidget(self.l0)
        self.toolbar0.addWidget(self.combobox)

        # Toolbar1
        self.l1 = QLabel(self.widget)
        self.l1.setText("Camera-Frame: ")
        self.l1.setFixedWidth(150)
        self.l1.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.camera_frame = QLineEdit(self.widget)
        self.camera_frame.setText("camera_link")
        self.toolbar1 = QToolBar()
        self.toolbar1.addWidget(self.l1)
        self.toolbar1.addWidget(self.camera_frame)

        # Toolbar2
        self.l2 = QLabel(self.widget)
        self.l2.setText("Object-Frame: ")
        self.l2.setFixedWidth(150)
        self.l2.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.object_frame = QLineEdit(self.widget)
        self.object_frame.setText("calib_board")
        self.toolbar2 = QToolBar()
        self.toolbar2.addWidget(self.l2)
        self.toolbar2.addWidget(self.object_frame)

        # Toolbar3
        self.l3 = QLabel(self.widget)
        self.l3.setText("Robot-Base-Frame: ")
        self.l3.setFixedWidth(150)
        self.l3.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.base_frame = QLineEdit(self.widget)
        self.base_frame.setText("base")
        self.toolbar3 = QToolBar()
        self.toolbar3.addWidget(self.l3)
        self.toolbar3.addWidget(self.base_frame)

        # Toolbar4
        self.l4 = QLabel(self.widget)
        self.l4.setText("End-Effector-Frame: ")
        self.l4.setFixedWidth(150)
        self.l4.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.endeffector_frame = QLineEdit(self.widget)
        self.endeffector_frame.setText("tool0")
        self.toolbar4 = QToolBar()
        self.toolbar4.addWidget(self.l4)
        self.toolbar4.addWidget(self.endeffector_frame)

        # Toolbar5
        self.l5 = QLabel(self.widget)
        self.l5.setText("Sample-Number: ")
        self.l5.setFixedWidth(150)
        self.l5.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.le5 = QLineEdit(self.widget)
        self.le5.setValidator(QIntValidator())
        self.le5.setText('10')
        self.le5.setReadOnly(True)
        self.toolbar5 = QToolBar()
        self.toolbar5.addWidget(self.l5)
        self.toolbar5.addWidget(self.le5)

        # TreeView
        self.treeview = QTreeView()
        self.treeview.setAlternatingRowColors(True)
        self.model = QStandardItemModel(self.treeview)
        self.treeview.setModel(self.model)
        self.treeview.setHeaderHidden(True)

        # TextEdit
        self.textedit = QTextEdit(self.widget)
        self.textedit.setReadOnly(True)

        # Layout
        self.layout = QVBoxLayout()
        self.layout.addWidget(self.toolbar0)
        self.layout.addWidget(self.toolbar1)
        self.layout.addWidget(self.toolbar2)
        self.layout.addWidget(self.toolbar3)
        self.layout.addWidget(self.toolbar4)
        self.layout.addWidget(self.toolbar5)
        self.layout.addWidget(self.toolbar)
        self.layoutH = QHBoxLayout()
        self.layoutH.addWidget(self.treeview)
        self.layoutH.addWidget(self.textedit)
        self.layout.addLayout(self.layoutH)
        self.widget.setLayout(self.layout)
        # Add the widget to the user interface
        if context.serial_number() > 1:
            self.widget.setWindowTitle(self.widget.windowTitle() +
                                       (' (%d)' % context.serial_number()))
        context.add_widget(self.widget)
        # Make the connections
        self.snapshot_action.triggered.connect(self.take_snapshot)
        self.calibrate_action.triggered.connect(self.calibration)
        self.clear_action.triggered.connect(self.clear)
        self.execut_action.triggered.connect(self.execution)

        # Package path
        self.path_pkg = path_pkg

        # Set up TF
        self.cli = self.node.create_client(HandeyeTF, 'handeye_tf_service')
        while not self.cli.wait_for_service(timeout_sec=1.0):
            self.node.get_logger().info(
                'service not available, waiting again...')
        self.req = HandeyeTF.Request()

    def clear(self):
        # >>> Clear the recorded samples
        self.textedit.append('Clearing the recorded data ...')
        self.textedit.clear()
        self.Tsamples = []
        self.model.clear()

    def get_tf_transform(self, frame_id, child_frame_id):
        self.req.transform.header.frame_id = frame_id
        self.req.transform.child_frame_id = child_frame_id
        self.req.publish.data = False

        future = self.cli.call_async(self.req)
        rclpy.spin_until_future_complete(self.node, future)

        transform = TransformStamped()

        try:
            result = future.result()
        except Exception as e:
            self.node.get_logger().info('Service call failed %r' % (e, ))
        else:
            transform = result.tf_lookup_result

        return transform

    def publish_tf_transform(self, transform_to_publish):
        self.req.publish.data = True
        self.req.transform = transform_to_publish

        future = self.cli.call_async(self.req)
        rclpy.spin_until_future_complete(self.node, future)

        try:
            future.result()
        except Exception as e:
            self.node.get_logger().info('Service call failed %r' % (e, ))
        else:
            self.node.get_logger().info(
                'Send the camera-robot transform :\n\tfrom `{}` to `{}`.'.
                format(self.req.transform.header.frame_id,
                       self.req.transform.child_frame_id))

    def take_snapshot(self):
        # >>> Take the snapshot
        self.textedit.append('Taking snapshot ...')

        # Get the transform from `tool0` to `base_link`
        T = self.get_tf_transform(self.base_frame.text(),
                                  self.endeffector_frame.text())
        bTe = np.zeros((4, 4))
        q = [
            T.transform.rotation.w, T.transform.rotation.x,
            T.transform.rotation.y, T.transform.rotation.z
        ]
        bTe = br.quaternion.to_transform(q)
        bTe[:3, 3] = np.array([
            T.transform.translation.x, T.transform.translation.y,
            T.transform.translation.z
        ])
        self.textedit.append('Lookup transform: from `{}` to `{}`.'.format(
            self.base_frame.text(), self.endeffector_frame.text()))
        self.node.get_logger().info(bcolors.OKGREEN + 'bTe:' + bcolors.ENDC +
                                    '\n{}'.format(bTe))

        # Get the transform from `calib_board` to `camera_link`
        T = self.get_tf_transform(self.camera_frame.text(),
                                  self.object_frame.text())
        cTo = np.zeros((4, 4))
        q = [
            T.transform.rotation.w, T.transform.rotation.x,
            T.transform.rotation.y, T.transform.rotation.z
        ]
        cTo = br.quaternion.to_transform(q)
        cTo[:3, 3] = np.array([
            T.transform.translation.x, T.transform.translation.y,
            T.transform.translation.z
        ])
        self.textedit.append('Lookup transform: from `{}` to `{}`.'.format(
            self.camera_frame.text(), self.object_frame.text()))
        self.node.get_logger().info(bcolors.OKGREEN + 'cTo:' + bcolors.ENDC +
                                    '\n{}'.format(cTo))

        parent = QStandardItem('Snapshot {}'.format(len(self.Tsamples)))
        child_1 = QStandardItem('bTe:\n{}\n{}\n{}\n{}'.format(
            bTe[0, :], bTe[1, :], bTe[2, :], bTe[3, :]))
        child_2 = QStandardItem('cTo:\n{}\n{}\n{}\n{}'.format(
            cTo[0, :], cTo[1, :], cTo[2, :], cTo[3, :]))
        parent.appendRow(child_1)
        parent.appendRow(child_2)
        self.model.appendRow(parent)
        self.Tsamples.append((bTe, cTo))
        self.le5.setText(str(len(self.Tsamples)))

    def calibration(self):
        # >>> Compute the calibration
        self.textedit.append('Making the calibration ...')
        if len(self.Tsamples) == 0:
            self.textedit.append(
                'No transform recorded, please take snapshots.')
            return
        # save samples to `dataset.json` file
        save_samples_to_file(self.Tsamples)
        import handeye
        if self.combobox.currentIndex() == 0:
            solver_cri = handeye.calibrator.HandEyeCalibrator(setup='Moving')
        if self.combobox.currentIndex() == 1:
            solver_cri = handeye.calibrator.HandEyeCalibrator(setup='Fixed')
        for sample in self.Tsamples:
            solver_cri.add_sample(sample[0], sample[1])
        try:
            bTc = solver_cri.solve(method=handeye.solver.Daniilidis1999)
            # save the calibration result to 'camera-robot.json' file
            file_output = '/tmp/' + 'camera-robot.json'
            with open(file_output, 'w') as f:
                json.dump(bTc.tolist(), f)
        except Exception:
            self.textedit.append("Failed to solve the hand-eye calibration.")

    def execution(self):
        # >>> Publish the camera-robot transform
        self.textedit.append('Publishing the camera TF ...')
        file_input = '/tmp/' + 'camera-robot.json'
        with open(file_input, 'r') as f:
            datastore = json.load(f)

        to_frame = self.camera_frame.text()
        if self.combobox.currentIndex() == 0:
            from_frame = self.endeffector_frame.text()
        if self.combobox.currentIndex() == 1:
            from_frame = self.base_frame.text()

        bTc = np.array(datastore)
        static_transformStamped = TransformStamped()
        static_transformStamped.header.stamp = ROSClock().now().to_msg()
        static_transformStamped.header.frame_id = from_frame
        static_transformStamped.child_frame_id = to_frame

        static_transformStamped.transform.translation.x = bTc[0, 3]
        static_transformStamped.transform.translation.y = bTc[1, 3]
        static_transformStamped.transform.translation.z = bTc[2, 3]

        q = br.transform.to_quaternion(bTc)
        static_transformStamped.transform.rotation.x = q[1]
        static_transformStamped.transform.rotation.y = q[2]
        static_transformStamped.transform.rotation.z = q[3]
        static_transformStamped.transform.rotation.w = q[0]

        self.publish_tf_transform(static_transformStamped)

        output_string = "camera-robot pose:\n"
        output_string += "  Translation: [{}, {}, {}]\n".format(
            bTc[0, 3], bTc[1, 3], bTc[2, 3])
        output_string += "  Rotation: in Quaternion [{}, {}, {}, {}]".format(
            q[0], q[1], q[2], q[3])
        file_path = '/tmp/' + 'camera-robot.txt'
        with open(file_path, 'w') as f:
            f.write(output_string)

    def shutdown_plugin(self):
        """
    Unregister subscribers when the plugin shutdown
    """
        pass

    def save_settings(self, plugin_settings, instance_settings):
        # Nothing to be done here
        pass

    def restore_settings(self, plugin_settings, instance_settings):
        # Nothing to be done here
        pass
コード例 #11
0
    def init_sliders(self):
        sliderbox = self._widget.findChild(QLayout, 'Sliders')

        graph_button = QPushButton()
        graph_button.setCheckable(True)
        graph_button.setText("Graph Off")
        graph_button.toggle()
        graph_button.clicked.connect(self.set_graph_state)
        self.graph_button = graph_button

        firstCol = QVBoxLayout()
        firstCol.addWidget(graph_button)

        sliderbox.addLayout(firstCol)

        self.sliders = []

        all_rows_layout = QVBoxLayout()
        chan_idx = 0
        for num_channels_row in self.settings['num_channels']:
            row_layout = QHBoxLayout()
            for i in range(num_channels_row):
                idx = chan_idx * 1

                slider_group = {
                    'slider_p': None,
                    'number_p': None,
                    'slider_i': None,
                    'number_i': None,
                    'slider_d': None,
                    'number_d': None,
                    'on_off': None
                }

                layout_cluster = QVBoxLayout()
                slider_cluster = QHBoxLayout()
                label = QLabel()
                label.setText("Chan. %d" % (idx + 1))
                label.setAlignment(Qt.AlignCenter)
                layout_cluster.addWidget(label)
                for j in range(3):
                    layout = QVBoxLayout()
                    layout.setAlignment(Qt.AlignHCenter)

                    if j == 0:
                        maxrange = 1.0
                    elif j == 1:
                        maxrange = 10
                    elif j == 2:
                        maxrange = 10

                    slider = QSlider(Qt.Vertical)
                    slider.setMinimum(0)
                    slider.setMaximum(maxrange * 100)
                    slider.setValue(self.settings['pid_gains'][chan_idx][j] *
                                    100)
                    slider.setTickPosition(QSlider.TicksRight)
                    slider.setTickInterval(maxrange / 100.0)

                    spinbox = QDoubleSpinBox()
                    spinbox.setMinimum(0)
                    spinbox.setMaximum(maxrange)
                    spinbox.setValue(self.settings['pid_gains'][chan_idx][j])
                    spinbox.setDecimals(2)
                    spinbox.setSingleStep(maxrange / 100.0)

                    cb_function_number = lambda value, idx=idx, gain_idx=j, slider=False: self.send_slider_value(
                        idx, gain_idx, value, slider)
                    cb_function_slider = lambda value, idx=idx, gain_idx=j, slider=True: self.send_slider_value(
                        idx, gain_idx, value, slider)

                    slider.valueChanged.connect(cb_function_slider)
                    spinbox.valueChanged.connect(cb_function_number)

                    label = QLabel()
                    label.setAlignment(Qt.AlignCenter)

                    if j == 0:
                        slider_group['slider_p'] = slider
                        slider_group['number_p'] = spinbox
                        label.setText("P")
                    elif j == 1:
                        slider_group['slider_i'] = slider
                        slider_group['number_i'] = spinbox
                        label.setText("I")
                    elif j == 2:
                        slider_group['slider_d'] = slider
                        slider_group['number_d'] = spinbox
                        label.setText("D")

                    labelmax = QLabel()
                    labelmax.setAlignment(Qt.AlignCenter)
                    labelmax.setText("%0.1f" % (maxrange))

                    labelmin = QLabel()
                    labelmin.setAlignment(Qt.AlignCenter)
                    labelmin.setText("0")

                    layout.addWidget(label)
                    layout.addWidget(labelmax)
                    layout.addWidget(slider, Qt.AlignHCenter)
                    layout.addWidget(labelmin)
                    layout.addWidget(spinbox, Qt.AlignHCenter)
                    layout.setAlignment(slider, Qt.AlignHCenter)
                    layout.setAlignment(spinbox, Qt.AlignHCenter)

                    slider_cluster.addLayout(layout)

                on_button = QPushButton()
                on_button.setCheckable(True)
                on_button.setText("Off")

                if self.settings['channel_states'][chan_idx]:
                    on_button.toggle()
                    on_button.setText("On")

                on_button.clicked.connect(
                    lambda state, idx=idx: self.send_channel_state(idx, state))

                slider_group['on_off'] = on_button

                layout_cluster.addLayout(slider_cluster)
                layout_cluster.addWidget(on_button)

                row_layout.addLayout(layout_cluster)
                row_layout.addSpacing(20)

                self.sliders.append(slider_group)
                chan_idx += 1

            all_rows_layout.addLayout(row_layout)
        sliderbox.addLayout(all_rows_layout)
コード例 #12
0
    def __init__(self, context, node_name):
        """
        Initializaze things.

        :type node_name: str
        """
        super(ParamClientWidget, self).__init__()
        self._node_grn = node_name
        self._toplevel_treenode_name = node_name

        self._editor_widgets = {}

        self._param_client = create_param_client(
            context.node, node_name, self._handle_param_event
        )

        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(QMargins(0, 0, 0, 0))

        widget_nodeheader = QWidget()
        h_layout_nodeheader = QHBoxLayout(widget_nodeheader)
        h_layout_nodeheader.setContentsMargins(QMargins(0, 0, 0, 0))

        nodename_qlabel = QLabel(self)
        font = QFont('Trebuchet MS, Bold')
        font.setUnderline(True)
        font.setBold(True)
        font.setPointSize(10)
        nodename_qlabel.setFont(font)
        nodename_qlabel.setAlignment(Qt.AlignCenter)
        nodename_qlabel.setText(node_name)
        h_layout_nodeheader.addWidget(nodename_qlabel)

        # Button to close a node.
        icon_disable_node = QIcon.fromTheme('window-close')
        bt_disable_node = QPushButton(icon_disable_node, '', self)
        bt_disable_node.setToolTip('Hide this node')
        bt_disable_node_size = QSize(36, 24)
        bt_disable_node.setFixedSize(bt_disable_node_size)
        bt_disable_node.pressed.connect(self._node_disable_bt_clicked)
        h_layout_nodeheader.addWidget(bt_disable_node)

        grid_widget = QWidget(self)
        self.grid = QFormLayout(grid_widget)
        verticalLayout.addWidget(widget_nodeheader)
        verticalLayout.addWidget(grid_widget, 1)
        # Again, these UI operation above needs to happen in .ui file.
        param_names = self._param_client.list_parameters()
        self.add_editor_widgets(
            self._param_client.get_parameters(param_names),
            self._param_client.describe_parameters(param_names)
        )

        # Save and load buttons
        button_widget = QWidget(self)
        button_header = QHBoxLayout(button_widget)
        button_header.setContentsMargins(QMargins(0, 0, 0, 0))

        load_button = QPushButton()
        save_button = QPushButton()

        load_button.setIcon(QIcon.fromTheme('document-open'))
        save_button.setIcon(QIcon.fromTheme('document-save'))

        load_button.clicked[bool].connect(self._handle_load_clicked)
        save_button.clicked[bool].connect(self._handle_save_clicked)

        button_header.addWidget(save_button)
        button_header.addWidget(load_button)

        self.setMinimumWidth(150)
コード例 #13
0
class TopicSelection(QWidget):
    recordSettingsSelected = Signal(bool, list, dict)

    def __init__(self):
        super(TopicSelection, self).__init__()
        master = rosgraph.Master('rqt_bag_recorder')
        self.setWindowTitle("Record a Simulation")
        self.resize(650, 720)

        pre = TS.get_time_series_pre_feature_options()
        glob = TS.get_global_time_series_features_options()
        # print pre
        # print glob
        all_topics = S.get_topics_options()
        keys = all_topics.keys()
        # print all_topics.keys()[0]
        self.plp_filename = ""
        self.group_selected_items = dict()
        self.group_areas = dict()
        self.group_main_widget = dict()
        self.group_selection_vlayout = dict()
        self.group_item_all = dict()
        # self.main_vlayout = QVBoxLayout(self)
        self.main_vlayout = QVBoxLayout(self)

        self.group_label = dict()

        self.selected_topics = []
        self.items_list = []

        for group_name in all_topics:
            self.group_selected_items[group_name] = []
            self.group_areas[group_name] = QScrollArea(self)
            self.group_main_widget[group_name] = QWidget(
                self.group_areas[group_name])
            self.group_label[group_name] = QLabel(group_name, self)
            self.group_label[group_name].setAlignment(Qt.AlignCenter)
            self.main_vlayout.addWidget(self.group_label[group_name])
            self.main_vlayout.addWidget(self.group_areas[group_name])
            self.group_selection_vlayout[group_name] = QVBoxLayout(self)
            self.group_item_all[group_name] = MyQCheckBox(
                "All", self, self.group_selection_vlayout[group_name], None)
            self.MakeCheckBoxList(self.group_selection_vlayout[group_name],
                                  self.group_selected_items[group_name],
                                  all_topics[group_name],
                                  self.group_item_all[group_name])
            self.group_main_widget[group_name].setLayout(
                self.group_selection_vlayout[group_name])
            self.group_areas[group_name].setWidget(
                self.group_main_widget[group_name])

        self.label1 = QLabel("Scenarios", self)
        self.label1.setAlignment(Qt.AlignCenter)

        self.main_vlayout.addWidget(self.label1)

        scanarios = S.get_scenarios_options()
        self.scanarios_answer = scanarios
        self.map_answer = dict()
        # print scanarios
        keys1 = scanarios.keys()

        # print keys1[0]
        # print scanarios[keys1[0]]["name"]
        # print scanarios[keys1[0]]["params"]
        #
        # for item in scanarios[keys1[0]]["params"]:
        #     print item

        self.radio_items = dict()
        self.number_group = QButtonGroup(self)

        for id_radio in scanarios:
            self.radio_items[id_radio] = QRadioButton(
                scanarios[id_radio]["name"])
            self.number_group.addButton(self.radio_items[id_radio])
            self.main_vlayout.addWidget(self.radio_items[id_radio])
            self.radio_items[id_radio].setChecked(False)
            self.radio_items[id_radio].clicked.connect(
                partial(self.callConsult, scanarios[id_radio]["params"],
                        id_radio))

        self.select_path = QLineEdit()
        self.save_path = QLineEdit()

        self.select_path.setEnabled(False)
        self.save_path.setEnabled(False)

        self.plp_button = QPushButton("Select PLP Python File...", self)
        self.plp_button.clicked.connect(self.onPlpClicked)

        self.two_buttons1 = QHBoxLayout(self)

        self.two_buttons1.addWidget(self.plp_button)

        self.two_buttons1.addWidget(self.select_path)

        self.main_vlayout.addLayout(self.two_buttons1)

        # self.label = QLabel("live Topics", self)
        # self.label.setAlignment(Qt.AlignCenter)
        #
        # self.main_vlayout.addWidget(self.label)

        # self.area = QScrollArea(self)
        # self.main_widget = QWidget(self.area)

        self.ok_button = QPushButton("Record", self)
        self.ok_button.clicked.connect(self.onButtonClicked)
        self.ok_button.setEnabled(False)
        self.choose_button = QPushButton("Get Last Export Choose", self)
        self.choose_button.clicked.connect(self.onButtonChooseCliked)

        self.clear_button = QPushButton("Clear Selection", self)
        self.clear_button.clicked.connect(self.onClearClicked)

        self.choose_clear_buttons = QHBoxLayout(self)

        self.choose_clear_buttons.addWidget(self.choose_button)

        self.choose_clear_buttons.addWidget(self.clear_button)

        self.main_vlayout.addLayout(self.choose_clear_buttons)

        # self.main_vlayout.addRow(self.choose_button, self.clear_button)

        # self.from_nodes_button = QPushButton("From Nodes", self)
        # self.from_nodes_button.clicked.connect(self.onFromNodesButtonClicked)

        # self.main_vlayout.addWidget(self.area)
        # self.main_vlayout.addWidget(self.choose_button)
        self.main_vlayout.addWidget(self.ok_button)
        # self.main_vlayout.addWidget(self.from_nodes_button)
        self.setLayout(self.main_vlayout)

        self.selection_vlayout = QVBoxLayout(self)

        # self.item_all = MyQCheckBox("All", self, self.selection_vlayout, None)
        # self.item_all.stateChanged.connect(lambda x: self.updateList(x, self.item_all, None))
        # self.selection_vlayout.addWidget(self.item_all)
        # topic_data_list4 = map(lambda l: l[0], master.getPublishedTopics(''))
        # topic_data_list4.sort()
        # for topic in topic_data_list4:
        #     self.addCheckBox(topic, self.selection_vlayout, self.selected_topics)

        # self.main_widget.setLayout(self.selection_vlayout)

        # self.area.setWidget(self.main_widget)

        # print S.get_scenarios_options()

        self.show()

    def onClearClicked(self):
        self.clearTopicCheckState()

    def clearTopicCheckState(self):
        for item in self.items_list:
            item.setCheckState(False)
        for item in self.group_item_all.values():
            item.setCheckState(False)

    def onButtonChooseCliked(self):
        for checkbox in self.items_list:
            checkbox.setCheckState(Qt.Unchecked)
        with open(get_path() + "logger_topic.log", 'r') as f:
            topics = f.read().splitlines()
        for checkbox in self.items_list:
            if checkbox.text() in topics:
                checkbox.setCheckState(Qt.Checked)

    def callConsult(self, params, id_radio):
        self.input_dialog = inputDialog(params, id_radio)
        self.input_dialog.ParamsSelected.connect(self.params_answer)
        # item, ok = QInputDialog.getItem(self, "select parameter",
        #                                 "list of parameters", params, 0, False)
        # if ok and item:
        #     self.gettext(item)

    def params_answer(self, params, label_items, id_radio):
        if id_radio == 0:
            # print "------" + str(id_radio)
            self.number_group.setExclusive(False)
            # print self.radio_items
            for item in self.radio_items:
                # print self.radio_items[item]
                self.radio_items[item].setChecked(False)
            self.number_group.setExclusive(True)
            self.enable_record()
        else:
            # print id_radio
            # print params
            # print params.values()
            a = {}
            # print label_items
            for item, name in zip(params, label_items):
                # value = params[item].text()
                a[name] = item.text().encode("utf-8")
            # print a
            self.map_answer = {"id": id_radio, "params": a}
            self.enable_record()
            return self.map_answer

        # for item in params.values():
        #     print item.text()
        # pass

    # def gettext(self, item):
    #     text, ok = QInputDialog.getText(self, 'Text Input Dialog', item)
    #
    #     if ok:
    #        print self.multipleReplace(str(text), item)
    #
    #
    # def multipleReplace(self, text, item):
    #     for key in self.scanarios_answer:
    #         #
    #         print self.scanarios_answer[key]["params"]
    #         for id, par in enumerate(self.scanarios_answer[key]["params"]):
    #             if par == item:
    #                 self.scanarios_answer[key]["params"][id] = text
    #     for id_radio in self.radio_items.keys():
    #         if self.radio_items[id_radio].isChecked():
    #             self.map_answer = {"id" : id_radio, "params" : self.scanarios_answer[id_radio]["params"]}
    #     return self.map_answer

    def MakeCheckBoxList(self, selection_vlayout, selected, topics_Keys,
                         item_all):
        item_all.stateChanged.connect(
            lambda x: self.updateList(x, item_all, None))
        selection_vlayout.addWidget(item_all)
        topic_data_list = topics_Keys
        topic_data_list.sort()
        for topic in topic_data_list:
            self.addCheckBox(topic, selection_vlayout, selected)

    def get_item_by_name(self, item_name):
        for item in self.items_linputDialogist:
            if item.text() == item_name:
                return item
        return None

    def addCheckBox(self, topic, selection_vlayout, selected_list):
        item = MyQCheckBox(topic, self, selection_vlayout, selected_list)
        item.stateChanged.connect(lambda x: self.updateList(x, item, topic))
        self.items_list.append(item)
        selection_vlayout.addWidget(item)

    def changeTopicCheckState(self, topic, state):
        for item in self.items_list:
            if item.text() == topic:
                item.setCheckState(state)
                return

    # def updateList(self, state, topic=None, force_update_state=False):
    #     if topic is None:  # The "All" checkbox was checked / unchecked
    #         if state == Qt.Checked:
    #             self.item_all.setTristate(False)
    #             for item in self.items_list:
    #                 if item.checkState() == Qt.Unchecked:
    #                     item.setCheckState(Qt.Checked)
    #         elif state == Qt.Unchecked:
    #             self.item_all.setTristate(False)
    #             for item in self.items_list:
    #                 if item.checkState() == Qt.Checked:
    #                     item.setCheckState(Qt.Unchecked)
    #     else:
    #         if state == Qt.Checked:
    #             self.selected_topics.append(topic)
    #         else:
    #             self.selected_topics.remove(topic)
    #             if self.item_all.checkState() == Qt.Checked:
    #                 self.item_all.setCheckState(Qt.PartiallyChecked)
    #
    #     if self.selected_topics == []:
    #         self.ok_button.setEnabled(False)
    #     else:
    #         self.ok_button.setEnabled(True)

    def updateList(self,
                   state,
                   item_clicked,
                   topic=None,
                   force_update_state=False):
        if type(item_clicked) is str:
            item_clicked = self.get_item_by_name(item_clicked)
            if item_clicked is None:
                return
        if topic is None:  # The "All" checkbox was checked / unchecked
            #print "if topic is None"
            if state == Qt.Checked:
                # self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Unchecked and \
                            item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Checked)
            elif state == Qt.Unchecked:
                # self.item_all.setTristate(False)
                for item in self.items_list:
                    if item.checkState() == Qt.Checked and \
                            item.selection_vlayout == item_clicked.selection_vlayout:
                        item.setCheckState(Qt.Unchecked)
        else:
            if state == Qt.Checked:
                item_clicked.selected_list.append(topic)
                #print item_clicked.selected_list
            else:
                item_clicked.selected_list.remove(topic)
        #if self.item_all.checkState() == Qt.Checked:
        #    self.item_all.setCheckState(Qt.PartiallyChecked)

        self.enable_record()

    def enable_record(self):
        temp_selected_topics = []
        for item in self.group_selected_items.values():
            if item:
                for i in item:
                    temp_selected_topics.append(i)

        flag = False
        for item in self.radio_items:
            if self.radio_items[item].isChecked():
                flag = True
                break
            # print self.radio_items[item]

        # flag = reduce(lambda acc, curr: acc or , self.radio_items, False)
        # print "------+++++-" + str(flag)
        if len(temp_selected_topics) > 0 or len(self.selected_topics) > 0:
            self.ok_button.setEnabled(flag)
        else:
            self.ok_button.setEnabled(False)

    def onButtonClicked(self):
        # print self.group_selected_items
        for item in self.group_selected_items.values():
            if item:
                for i in item:
                    self.selected_topics.append(i)
        topics = self.selected_topics
        with open(get_path() + 'logger_topic.log', "w") as f:
            for topic in topics:
                f.write(topic + "\n")
        self.close()
        # TBD - runing plp on shell on itself
        # if self.plp_filename != "":
        #     from .plp import Plp
        #     Plp(self.plp_filename)
        self.recordSettingsSelected.emit(False, self.selected_topics,
                                         self.map_answer)

    def get_current_opened_directory(self, filepath):
        import os
        direc = "/"
        if os.path.isfile(filepath):
            with open(filepath, 'r') as f:
                pathes = f.read()
                direc = pathes.rsplit('/', 1)[0]
        return direc

    def onPlpClicked(self):
        import inspect, os
        filepath = os.path.dirname(
            os.path.abspath(inspect.getfile(
                inspect.currentframe()))) + "/log/save_plp.log"
        current_directory = self.get_current_opened_directory(filepath)
        fd = QFileDialog(self)
        wc = "Csv files {.py} (*.py)"
        # print current_directory
        filename, filter = fd.getOpenFileNamesAndFilter(
            filter=wc, initialFilter=('*.py'), directory=current_directory)
        if len(filename):
            self.plp_filename = filename[0]
            with open(filepath, "w") as f:
                f.write(self.plp_filename)
            self.select_path.setText(self.plp_filename)
            # print self.plp_filename[0]

    def onFromNodesButtonClicked(self):
        self.node_selection = NodeSelection(self)

    def getTopicsByName(self, name):
        arr = S.get_topics_options()
        return arr[name]
コード例 #14
0
    def init_sliders(self):
        sliderbox = self._widget.findChild(QLayout,'Sliders')

        firstCol = QVBoxLayout()
        graph_button=QPushButton()
        graph_button.setCheckable(True)
        graph_button.setText("Graph Off")
        graph_button.toggle()
        graph_button.clicked.connect(self.set_graph_state)
        self.graph_button = graph_button

        reset_button=QPushButton()
        reset_button.setCheckable(False)
        reset_button.setText("Reset")
        reset_button.clicked.connect(self.set_reset)

        self.graph_button = graph_button
        self.reset_button = reset_button

        firstCol.addWidget(graph_button)
        firstCol.addWidget(reset_button)


        firstCol.addWidget(graph_button)
        firstCol.setAlignment(graph_button,Qt.AlignVCenter)

        zero_button=QPushButton()
        zero_button.setCheckable(False)
        zero_button.setText("Set All Zero")
        zero_button.clicked.connect(self.set_pressure_zero)
        self.zero_button = zero_button
        firstCol.addWidget(zero_button)
        firstCol.setAlignment(zero_button,Qt.AlignVCenter)



        transition_box = QVBoxLayout()
        label = QLabel()
        label.setAlignment(Qt.AlignCenter)
        label.setText("Transition Time")

        spinbox = QDoubleSpinBox()
        spinbox.setMinimum(0)
        spinbox.setMaximum(10)
        spinbox.setValue(self.settings['transitions'])
        spinbox.setDecimals(1)
        spinbox.setSingleStep(0.1)
        spinbox.setSuffix(" sec")

        spinbox.valueChanged.connect(self.set_transition_value)

        transition_box.addWidget(label)
        transition_box.addWidget(spinbox)
        transition_box.setAlignment(label,Qt.AlignBottom)
        transition_box.setAlignment(spinbox,Qt.AlignTop)
        firstCol.addLayout(transition_box)

        self.sliders = []
        sliderbox.addLayout(firstCol)

        all_rows_layout = QVBoxLayout()

        g_idx = 0

        for row in self.settings['gui_config']:
            num_groups_row = len(row)
            row_layout = QHBoxLayout()
            for gr_idx, s_group in enumerate(row): 
                g_channels = s_group['channels']
                g_layout = s_group['layout']

                if 'horiz' in g_layout:
                    group_layout = QHBoxLayout()
                else:
                    group_layout = QVBoxLayout()

                control_group = {'sliders': [], 'on_off': None}

                label = QLabel()
                label.setText("Group. %d"%(g_idx+1))
                label.setAlignment(Qt.AlignCenter)
                group_layout.addWidget(label)

                for c_idx, s_idx in enumerate(g_channels):
                    idx = s_idx*1
                    
                    slider_group={'slider':None, 'number':None}
                    
                    layout_cluster = QVBoxLayout()

                    labelfirst = QLabel()
                    labelfirst.setAlignment(Qt.AlignCenter)

                    labellast = QLabel()
                    labellast.setAlignment(Qt.AlignCenter)

                    layout = QVBoxLayout()

                    if 'diff' in g_layout and c_idx == 0:

                        sublayout=QHBoxLayout()

                        layout.setAlignment(Qt.AlignVCenter)

                        slider = QSlider(Qt.Horizontal)
                        slider.setMinimum(-100)
                        slider.setMaximum(100)
                        slider.setValue(0)
                        slider.setTickPosition(QSlider.TicksRight)
                        slider.setTickInterval(20)

                        spinbox = QDoubleSpinBox()
                        spinbox.setMinimum(-10)
                        spinbox.setMaximum(10)
                        spinbox.setValue(0)
                        spinbox.setDecimals(1)
                        spinbox.setSingleStep(0.1)

                        labellast.setText("%0.1f"%(10)) # These are flipped becasue of order
                        labelfirst.setText("%0.1f"%(-10))

                        max_label = labellast
                        min_label = labelfirst

                    else:
                        layout.setAlignment(Qt.AlignHCenter)

                        slider = QSlider(Qt.Vertical)
                        slider.setMinimum(self.settings['min_pressure'][idx]*10.0)
                        slider.setMaximum(self.settings['max_pressure'][idx]*10.0)
                        slider.setValue(0)
                        slider.setTickPosition(QSlider.TicksRight)
                        slider.setTickInterval(20)

                        spinbox = QDoubleSpinBox()
                        spinbox.setMinimum(self.settings['min_pressure'][idx])
                        spinbox.setMaximum(self.settings['max_pressure'][idx])
                        spinbox.setValue(0)
                        spinbox.setDecimals(1)
                        spinbox.setSingleStep(0.1)

                        labelfirst.setText("%0.1f"%(self.settings['max_pressure'][idx]))
                        labellast.setText("%0.1f"%(self.settings['min_pressure'][idx]))

                        max_label = labelfirst
                        min_label = labellast

                    
                    cb_function_number = lambda value, g_idx=g_idx, s_idx=c_idx, slider=False: self.send_slider_value(g_idx,s_idx,value,slider)
                    cb_function_slider = lambda value, g_idx=g_idx, s_idx=c_idx, slider=True: self.send_slider_value(g_idx,s_idx,value,slider)
                    slider.valueChanged.connect(cb_function_slider)
                    spinbox.valueChanged.connect(cb_function_number)
               

                    if 'diff' in g_layout and c_idx == 0:

                        sublayout.addWidget(labelfirst)
                        sublayout.addWidget(slider)
                        sublayout.addWidget(labellast)
                        layout.addWidget(spinbox)
                        layout.addLayout(sublayout)
                    else:
                        layout.addWidget(labelfirst)
                        layout.addWidget(slider)
                        layout.addWidget(labellast)
                        layout.addWidget(spinbox)

                    layout.setAlignment(slider, Qt.AlignHCenter)
                    layout.setAlignment(spinbox, Qt.AlignHCenter)

                    layout_cluster.addLayout(layout)

                    slider_group['slider'] = slider
                    slider_group['number'] = spinbox
                    slider_group['max_label'] = max_label
                    slider_group['min_label'] = min_label
                    control_group['sliders'].append(slider_group)

                    group_layout.addLayout(layout_cluster)

                on_button=QPushButton()
                on_button.setCheckable(True)
                on_button.setText("Off")

                if self.settings['channel_states'][idx]:
                    on_button.toggle()
                    on_button.setText("On")

                on_button.clicked.connect(lambda state, g_idx=g_idx: self.send_channel_state(g_idx,state))

                group_layout.addWidget(on_button)

                row_layout.addLayout(group_layout)
                row_layout.addSpacing(20)

                control_group['on_off'] = on_button
                self.sliders.append(control_group)

                g_idx+=1

            all_rows_layout.addLayout(row_layout)

        sliderbox.addLayout(all_rows_layout)
コード例 #15
0
ファイル: label.py プロジェクト: sundermann/jsk_visualization
class StringLabelWidget(QWidget):
    def __init__(self):
        super(StringLabelWidget, self).__init__()
        self.lock = Lock()
        vbox = QVBoxLayout(self)
        self.label = QLabel()
        self.label.setAlignment(Qt.AlignLeft)
        self.label.setSizePolicy(
            QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored))
        font = QFont("Helvetica", 14)
        self.label.setFont(font)
        self.label.setWordWrap(True)
        vbox.addWidget(self.label)
        self.string_sub = None
        self._string_topics = []
        self._update_topic_timer = QTimer(self)
        self._update_topic_timer.timeout.connect(self.updateTopics)
        self._update_topic_timer.start(1000)
        self._active_topic = None
        # to update label visualization
        self._dialog = LineEditDialog()
        self._rosdata = None
        self._start_time = rospy.get_time()
        self._update_label_timer = QTimer(self)
        self._update_label_timer.timeout.connect(self.updateLabel)
        self._update_label_timer.start(40)

    def trigger_configuration(self):
        self._dialog.exec_()
        self.setupSubscriber(self._dialog.value)

    def updateLabel(self):
        if not self._rosdata:
            return
        try:
            _, data_y = self._rosdata.next()
        except rqt_plot.rosplot.RosPlotException as e:
            self._rosdata = None
            return
        if len(data_y) == 0:
            return
        latest = data_y[-1]  # get latest data
        # supports std_msgs/String as well as string data nested in rosmsg
        if type(latest) == String:
            self.string = latest.data
        else:
            self.string = latest
        try:
            self.label.setText(self.string)
        except TypeError as e:
            rospy.logwarn(e)

    def updateTopics(self):
        need_to_update = False
        for (topic, topic_type) in rospy.get_published_topics():
            msg = roslib.message.get_message_class(topic_type)
            field_names = get_slot_type_field_names(msg, slot_type='string')
            for field in field_names:
                string_topic = topic + field
                if string_topic not in self._string_topics:
                    self._string_topics.append(string_topic)
                    need_to_update = True
        if need_to_update:
            self._string_topics = sorted(self._string_topics)
            self._dialog.combo_box.clear()
            for topic in self._string_topics:
                self._dialog.combo_box.addItem(topic)
            if self._active_topic:
                if self._active_topic not in self._string_topics:
                    self._string_topics.append(self._active_topic)
                    self._dialog.combo_box.addItem(self._active_topic)
                self._dialog.combo_box.setCurrentIndex(
                    self._string_topics.index(self._active_topic))

    def setupSubscriber(self, topic):
        if not self._rosdata:
            self._rosdata = ROSData(topic, self._start_time)
        else:
            if self._rosdata != topic:
                self._rosdata.close()
                self._rosdata = ROSData(topic, self._start_time)
            else:
                rospy.logwarn("%s is already subscribed", topic)
        self._active_topic = topic

    def onActivated(self, number):
        self.setupSubscriber(self._string_topics[number])

    def save_settings(self, plugin_settings, instance_settings):
        if self._active_topic:
            instance_settings.set_value("active_topic", self._active_topic)

    def restore_settings(self, plugin_settings, instance_settings):
        if instance_settings.value("active_topic"):
            topic = instance_settings.value("active_topic")
            self._dialog.combo_box.addItem(topic)
            self.setupSubscriber(topic)
コード例 #16
0
class GroupWidget(QWidget):
    '''
    (Isaac's guess as of 12/13/2012)
    This class bonds multiple Editor instances that are associated with
    a single node as a group.
    '''

    # public signal
    sig_node_disabled_selected = Signal(str)

    def __init__(self, updater, config, nodename):
        '''
        :param config:
        :type config: Dictionary? defined in dynamic_reconfigure.client.Client
        :type nodename: str
        '''

        #TODO figure out what data type 'config' is. It is afterall returned
        #     from dynamic_reconfigure.client.get_parameter_descriptions()
        # ros.org/doc/api/dynamic_reconfigure/html/dynamic_reconfigure.client-pysrc.html#Client

        super(GroupWidget, self).__init__()
        self.state = config['state']
        self.name = config['name']
        self._toplevel_treenode_name = nodename

        # TODO: .ui file needs to be back into usage in later phase.
#        ui_file = os.path.join(rp.get_path('rqt_reconfigure'),
#                               'resource', 'singlenode_parameditor.ui')
#        loadUi(ui_file, self)

        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(QMargins(0, 0, 0, 0))

        _widget_nodeheader = QWidget()
        _h_layout_nodeheader = QHBoxLayout(_widget_nodeheader)
        _h_layout_nodeheader.setContentsMargins(QMargins(0, 0, 0, 0))

        self.nodename_qlabel = QLabel(self)
        font = QFont('Trebuchet MS, Bold')
        font.setUnderline(True)
        font.setBold(True)

        # Button to close a node.
        _icon_disable_node = QIcon.fromTheme('window-close')
        _bt_disable_node = QPushButton(_icon_disable_node, '', self)
        _bt_disable_node.setToolTip('Hide this node')
        _bt_disable_node_size = QSize(36, 24)
        _bt_disable_node.setFixedSize(_bt_disable_node_size)
        _bt_disable_node.pressed.connect(self._node_disable_bt_clicked)

        _h_layout_nodeheader.addWidget(self.nodename_qlabel)
        _h_layout_nodeheader.addWidget(_bt_disable_node)

        self.nodename_qlabel.setAlignment(Qt.AlignCenter)
        font.setPointSize(10)
        self.nodename_qlabel.setFont(font)
        grid_widget = QWidget(self)
        self.grid = QFormLayout(grid_widget)
        verticalLayout.addWidget(_widget_nodeheader)
        verticalLayout.addWidget(grid_widget, 1)
        # Again, these UI operation above needs to happen in .ui file.

        self.tab_bar = None  # Every group can have one tab bar
        self.tab_bar_shown = False

        self.updater = updater

        self.editor_widgets = []
        self._param_names = []

        self._create_node_widgets(config)

        rospy.logdebug('Groups node name={}'.format(nodename))
        self.nodename_qlabel.setText(nodename)

        # Labels should not stretch
        #self.grid.setColumnStretch(1, 1)
        #self.setLayout(self.grid)

    def collect_paramnames(self, config):
        pass

    def _create_node_widgets(self, config):
        '''
        :type config: Dict?
        '''
        i_debug = 0
        for param in config['parameters']:
            begin = time.time() * 1000
            editor_type = '(none)'

            if param['edit_method']:
                widget = EnumEditor(self.updater, param)
            elif param['type'] in EDITOR_TYPES:
                rospy.logdebug('GroupWidget i_debug=%d param type =%s',
                              i_debug,
                              param['type'])
                editor_type = EDITOR_TYPES[param['type']]
                widget = eval(editor_type)(self.updater, param)

            self.editor_widgets.append(widget)
            self._param_names.append(param['name'])

            rospy.logdebug('groups._create_node_widgets num editors=%d',
                           i_debug)

            end = time.time() * 1000
            time_elap = end - begin
            rospy.logdebug('ParamG editor={} loop=#{} Time={}msec'.format(
                                              editor_type, i_debug, time_elap))
            i_debug += 1

        for name, group in config['groups'].items():
            if group['type'] == 'tab':
                widget = TabGroup(self, self.updater, group)
            elif group['type'] in _GROUP_TYPES.keys():
                widget = eval(_GROUP_TYPES[group['type']])(self.updater, group)

            self.editor_widgets.append(widget)
            rospy.logdebug('groups._create_node_widgets ' +
                          #'num groups=%d' +
                          'name=%s',
                          name)

        for i, ed in enumerate(self.editor_widgets):
            ed.display(self.grid)

        rospy.logdebug('GroupWdgt._create_node_widgets len(editor_widgets)=%d',
                      len(self.editor_widgets))

    def display(self, grid, row):
        # groups span across all columns
        grid.addWidget(self, row, 0, 1, -1)

    def update_group(self, config):
        self.state = config['state']

        # TODO: should use config.keys but this method doesnt exist
        names = [name for name in config.items()]

        for widget in self.editor_widgets:
            if isinstance(widget, EditorWidget):
                if widget.name in names:
                    widget.update_value(config[widget.name])
            elif isinstance(widget, GroupWidget):
                cfg = find_cfg(config, widget.name)
                widget.update_group(cfg)

    def close(self):
        for w in self.editor_widgets:
            w.close()

    def get_treenode_names(self):
        '''
        :rtype: str[]
        '''
        return self._param_names

    def _node_disable_bt_clicked(self):
        rospy.logdebug('param_gs _node_disable_bt_clicked')
        self.sig_node_disabled_selected.emit(self._toplevel_treenode_name)