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()
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()
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)
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")
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)
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)
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)
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)
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)
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
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)
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)
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]
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)
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)
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)