def add_config(self, title, choices, single_choice=True): ''' create a UI element for selecting options for one variation and put it in a scrollArea ''' scroll = QScrollArea() group_box = QGroupBox(title) group_box.setFlat(True) layout = QVBoxLayout() if len(choices) > 5 and single_choice: combo_box = QComboBox(group_box) for obj in choices: combo_box.addItem(obj) layout.addWidget(combo_box) else: for obj in choices: if single_choice: layout.addWidget(QRadioButton(obj, group_box)) else: layout.addWidget(QCheckBox(obj, group_box)) layout.addStretch(1) group_box.setLayout(layout) scroll.setWidget(group_box) scroll.setWidgetResizable(True) return group_box, scroll
class JointStatePublisherGui(QWidget): sliderUpdateTrigger = Signal() def __init__(self, title, jsp, num_rows=0): super(JointStatePublisherGui, self).__init__() self.jsp = jsp self.joint_map = {} self.vlayout = QVBoxLayout(self) self.scrollable = QWidget() self.gridlayout = QGridLayout() self.scroll = QScrollArea() self.scroll.setWidgetResizable(True) font = QFont("Helvetica", 9, QFont.Bold) ### Generate sliders ### sliders = [] for name in self.jsp.joint_list: if name not in self.jsp.free_joints: continue joint = self.jsp.free_joints[name] if joint['min'] == joint['max']: continue joint_layout = QVBoxLayout() row_layout = QHBoxLayout() label = QLabel(name) label.setFont(font) row_layout.addWidget(label) display = QLineEdit("0.00") display.setAlignment(Qt.AlignRight) display.setFont(font) display.setReadOnly(True) row_layout.addWidget(display) joint_layout.addLayout(row_layout) slider = QSlider(Qt.Horizontal) slider.setFont(font) slider.setRange(0, RANGE) slider.setValue(RANGE / 2) joint_layout.addWidget(slider) self.joint_map[name] = { 'slidervalue': 0, 'display': display, 'slider': slider, 'joint': joint } # Connect to the signal provided by QSignal slider.valueChanged.connect( lambda event, name=name: self.onValueChangedOne(name)) sliders.append(joint_layout) # Determine number of rows to be used in grid self.num_rows = num_rows # if desired num of rows wasn't set, default behaviour is a vertical layout if self.num_rows == 0: self.num_rows = len(sliders) # equals VBoxLayout # Generate positions in grid and place sliders there self.positions = self.generate_grid_positions(len(sliders), self.num_rows) for item, pos in zip(sliders, self.positions): self.gridlayout.addLayout(item, *pos) # Set zero positions read from parameters self.center() # Synchronize slider and displayed value self.sliderUpdate(None) # Set up a signal for updating the sliders based on external joint info self.sliderUpdateTrigger.connect(self.updateSliders) self.scrollable.setLayout(self.gridlayout) self.scroll.setWidget(self.scrollable) self.vlayout.addWidget(self.scroll) # Buttons for randomizing and centering sliders and # Spinbox for on-the-fly selecting number of rows self.randbutton = QPushButton('Randomize', self) self.randbutton.clicked.connect(self.randomize_event) self.vlayout.addWidget(self.randbutton) self.ctrbutton = QPushButton('Center', self) self.ctrbutton.clicked.connect(self.center_event) self.vlayout.addWidget(self.ctrbutton) self.maxrowsupdown = QSpinBox() self.maxrowsupdown.setMinimum(1) self.maxrowsupdown.setMaximum(len(sliders)) self.maxrowsupdown.setValue(self.num_rows) self.maxrowsupdown.valueChanged.connect(self.reorggrid_event) self.vlayout.addWidget(self.maxrowsupdown) self.setLayout(self.vlayout) def onValueChangedOne(self, name): # A slider value was changed, but we need to change the joint_info metadata. joint_info = self.joint_map[name] joint_info['slidervalue'] = joint_info['slider'].value() joint = joint_info['joint'] joint['position'] = self.sliderToValue(joint_info['slidervalue'], joint) joint_info['display'].setText("%.2f" % joint['position']) @pyqtSlot() def updateSliders(self): self.update_sliders() def update_sliders(self): for name, joint_info in self.joint_map.items(): joint = joint_info['joint'] joint_info['slidervalue'] = self.valueToSlider( joint['position'], joint) joint_info['slider'].setValue(joint_info['slidervalue']) def center_event(self, event): self.center() def center(self): rospy.loginfo("Centering") for name, joint_info in self.joint_map.items(): joint = joint_info['joint'] joint_info['slider'].setValue( self.valueToSlider(joint['zero'], joint)) def reorggrid_event(self, event): self.reorganize_grid(event) def reorganize_grid(self, number_of_rows): self.num_rows = number_of_rows # Remove items from layout (won't destroy them!) items = [] for pos in self.positions: item = self.gridlayout.itemAtPosition(*pos) items.append(item) self.gridlayout.removeItem(item) # Generate new positions for sliders and place them in their new spots self.positions = self.generate_grid_positions(len(items), self.num_rows) for item, pos in zip(items, self.positions): self.gridlayout.addLayout(item, *pos) def generate_grid_positions(self, num_items, num_rows): if num_rows == 0: return [] positions = [ (y, x) for x in range(int((math.ceil(float(num_items) / num_rows)))) for y in range(num_rows) ] positions = positions[:num_items] return positions def randomize_event(self, event): self.randomize() def randomize(self): rospy.loginfo("Randomizing") for name, joint_info in self.joint_map.items(): joint = joint_info['joint'] joint_info['slider'].setValue( self.valueToSlider(random.uniform(joint['min'], joint['max']), joint)) def sliderUpdate(self, event): for name, joint_info in self.joint_map.items(): joint_info['slidervalue'] = joint_info['slider'].value() self.update_sliders() def valueToSlider(self, value, joint): return (value - joint['min']) * float(RANGE) / (joint['max'] - joint['min']) def sliderToValue(self, slider, joint): pctvalue = slider / float(RANGE) return joint['min'] + (joint['max'] - joint['min']) * pctvalue
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 TopicSelection(QWidget): recordSettingsSelected = Signal(bool, list) def __init__(self): super(TopicSelection, self).__init__() master = rosgraph.Master('rqt_bag_recorder') self.setWindowTitle("Select the topics you want to record") self.resize(500, 700) self.topic_list = [] self.selected_topics = [] self.items_list = [] 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.from_nodes_button = QPushButton("From Nodes", self) self.from_nodes_button.clicked.connect(self.onFromNodesButtonClicked) self.main_vlayout = QVBoxLayout(self) self.main_vlayout.addWidget(self.area) 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 = QCheckBox("All", self) self.item_monitor = QCheckBox("Monitor", self) self.item_monAge = QCheckBox("Monitor + Agents", self) self.item_all.stateChanged.connect(self.updateList) self.item_monitor.stateChanged.connect(lambda x: self.updateList(x, "Monitor")) self.item_monAge.stateChanged.connect(lambda x: self.updateList(x, "Monitor+")) self.selection_vlayout.addWidget(self.item_all) self.selection_vlayout.addWidget(self.item_monitor) self.selection_vlayout.addWidget(self.item_monAge) topic_data_list = master.getPublishedTopics('') topic_data_list.sort() for topic, datatype in topic_data_list: self.addCheckBox(topic) self.main_widget.setLayout(self.selection_vlayout) self.area.setWidget(self.main_widget) self.show() def addCheckBox(self, topic): self.topic_list.append(topic) item = QCheckBox(topic, self) item.stateChanged.connect(lambda x: self.updateList(x, topic)) self.items_list.append(item) self.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) elif topic == "Monitor" or topic == "Monitor+": if state == Qt.Checked: self.item_monitor.setTristate(False) self.selected_topics.append("/world_model") self.selected_topics.append("/draws") self.selected_topics.append("/debugs") self.selected_topics.append("/referee") for item in self.items_list: if item.text() == "/world_model" \ or item.text() == "/debugs" \ or item.text() == "/draws" \ or item.text() =="/referee": item.setCheckState(Qt.Checked) elif state == Qt.Unchecked: self.item_all.setTristate(False) self.selected_topics.remove("/world_model") self.selected_topics.remove("/draws") self.selected_topics.remove("/debugs") self.selected_topics.remove("/referee") for item in self.items_list: if item.text() == "/world_model" \ or item.text() =="/referee" \ or item.text() =="/debugs" \ or item.text()=="/draws": item.setCheckState(Qt.Unchecked) if topic == "Monitor+": if state == Qt.Checked: for item in self.items_list: if item.text().find("agent") >-1: self.selected_topics.append(item) item.setCheckState(Qt.Checked) elif state == Qt.Unchecked: for item in self.items_list: if item.text().find("agent") >-1: self.selected_topics.remove(item) 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 onButtonClicked(self): self.close() self.recordSettingsSelected.emit( self.item_all.checkState() == Qt.Checked, self.selected_topics) def onFromNodesButtonClicked(self): self.node_selection = NodeSelection(self)
class pyqtTraverse(Traverser.Traverser): def __init__(self): self.parent = None self.nesting_stack = [] def beginGui(self,obj): self.parent = QScrollArea() self.frame = QFrame(self.parent) if obj.layout == "vertical": self.tl = QVBoxLayout() else: self.tl = QHBoxLayout() self.__increase_nesting_level(self.frame,self.tl) def endGui(self,obj): parent,layout = self.__get_immediate_parent() self.frame.setLayout(layout) self.parent.setWidget(self.frame) self.parent.show() def beginGroup(self,obj): parent,layout = self.__get_immediate_parent() panel = QGroupBox(obj.name,parent) if obj.layout == "grid": l = QGridLayout() elif obj.layout == "vertical": l = QVBoxLayout() else: l = QHBoxLayout() self.__increase_nesting_level(panel, l) def endGroup(self,obj): parent,layout = self.__get_immediate_parent() parent.setLayout(layout) self.__decrease_nesting_level() p1,l1 = self.__get_immediate_parent() l1.addWidget(parent) def beginRosLabel(self,obj): pm,lm = self.__get_immediate_parent() fr = QFrame(pm) layout = QGridLayout() nlb = QLabel(obj.label_name + ":",fr) nlb.setToolTip(obj.topic_name) layout.addWidget(nlb,1,1) layout.addWidget(RosLabel(fr,obj.label_name,obj.topic_name,obj.topic_type,obj.topic_field),1,2) fr.setLayout(layout) lm.addWidget(fr) def endRosLabel(self,obj): pass def beginRosToggleButton(self,obj): pm,lm = self.__get_immediate_parent() btn = RosToggleButton(pm, obj.btn_name, obj.topic_name, obj.topic_type, obj.topic_field, obj.toggle_dict) lm.addWidget(btn) pass def endRosToggleButton(self,obj): pass def beginRosSlider(self,obj): pm,lm = self.__get_immediate_parent() slider = RosSlider(pm,obj.label_name, obj.topic_name, obj.topic_type, obj.topic_field, obj.min_max_tuple, obj.default ) lm.addWidget(slider) pass def endRosSlider(self,obj): pass def beginRosPlot(self,obj): pm,lm = self.__get_immediate_parent() plot = RosPlot(pm,obj.label_name, obj.topic_name, obj.topic_type, obj.topic_field, obj.buffer_size ) lm.addWidget(plot) def endRosPlot(self,obj): pass def beginRosMsgView(self,obj): pm,lm = self.__get_immediate_parent() fr = RosMsgView(pm, obj.grp_name, obj.topic_name, obj.topic_type, obj.topic_fields) lm.addWidget(fr) pass def endRosMsgView(self,obj): pass def __get_immediate_parent(self): l = len(self.nesting_stack) return self.nesting_stack[l-1] def __increase_nesting_level(self,parent,container): self.nesting_stack.append((parent,container)) def __decrease_nesting_level(self): self.nesting_stack.pop()
class TopicSelection(QWidget): recordSettingsSelected = Signal(bool, list) def __init__(self): super(TopicSelection, self).__init__() master = rosgraph.Master('rqt_bag_recorder') self.setWindowTitle("Select the topics you want to record") self.resize(500, 700) self.topic_list = [] self.selected_topics = [] self.items_list = [] 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.main_vlayout = QVBoxLayout(self) self.main_vlayout.addWidget(self.area) self.main_vlayout.addWidget(self.ok_button) self.setLayout(self.main_vlayout) self.selection_vlayout = QVBoxLayout(self) self.item_all = QCheckBox("All", self) self.item_all.stateChanged.connect(self.updateList) self.selection_vlayout.addWidget(self.item_all) topic_data_list = master.getPublishedTopics('') topic_data_list.sort() for topic, datatype in topic_data_list: self.addCheckBox(topic) self.main_widget.setLayout(self.selection_vlayout) self.area.setWidget(self.main_widget) self.show() def addCheckBox(self, topic): self.topic_list.append(topic) item = QCheckBox(topic, self) item.stateChanged.connect(lambda x: self.updateList(x,topic)) self.items_list.append(item) self.selection_vlayout.addWidget(item) def updateList(self, state, topic = None): 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 onButtonClicked(self): self.close() self.recordSettingsSelected.emit((self.item_all.checkState() == Qt.Checked), self.selected_topics)
class TopicSelection(QWidget): recordSettingsSelected = Signal(bool, list) def __init__(self): super(TopicSelection, self).__init__() master = rosgraph.Master('rqt_bag_recorder') self.setWindowTitle("Select the topics you want to record") self.resize(500, 700) self.topic_list = [] self.selected_topics = [] self.items_list = [] 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.main_vlayout = QVBoxLayout(self) self.main_vlayout.addWidget(self.area) self.main_vlayout.addWidget(self.ok_button) self.setLayout(self.main_vlayout) self.selection_vlayout = QVBoxLayout(self) self.item_all = QCheckBox("All", self) self.item_all.stateChanged.connect(self.updateList) self.selection_vlayout.addWidget(self.item_all) topic_data_list = master.getPublishedTopics('') topic_data_list.sort() for topic, datatype in topic_data_list: self.addCheckBox(topic) self.main_widget.setLayout(self.selection_vlayout) self.area.setWidget(self.main_widget) self.show() def addCheckBox(self, topic): self.topic_list.append(topic) item = QCheckBox(topic, self) item.stateChanged.connect(lambda x: self.updateList(x, topic)) self.items_list.append(item) self.selection_vlayout.addWidget(item) def updateList(self, state, topic=None): 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 onButtonClicked(self): self.close() self.recordSettingsSelected.emit( (self.item_all.checkState() == Qt.Checked), self.selected_topics)
class NodeSelection(QWidget): def __init__(self, parent): super(NodeSelection, self).__init__() self.parent_widget = parent self.selected_nodes = [] self.setWindowTitle("Select the nodes you want to record") self.resize(300, 300) self.area = QScrollArea(self) self.main_widget = QWidget(self.area) self.ok_button = QPushButton("Done", self) self.ok_button.clicked.connect(self.onButtonClicked) self.ok_button.setEnabled(False) self.main_vlayout = QVBoxLayout(self) self.main_vlayout.addWidget(self.area) self.main_vlayout.addWidget(self.ok_button) self.setLayout(self.main_vlayout) self.selection_vlayout = QVBoxLayout(self) self.node_list = rosnode.get_node_names() self.node_list.sort() for node in self.node_list: # add planner node by choosing agent number if "planner" not in node: self.addCheckBox(node) self.main_widget.setLayout(self.selection_vlayout) self.area.setWidget(self.main_widget) self.show() def addCheckBox(self, node): item = QCheckBox(node, self) item.stateChanged.connect(lambda x: self.updateNode(x, node)) self.selection_vlayout.addWidget(item) def updateNode(self, state, node): if state == Qt.Checked: self.selected_nodes.append(node) if "planner" + "_" + node.split("_")[1] in self.node_list: self.selected_nodes.append("planner" + "_" + node.split("_")[1]) else: self.selected_nodes.remove(node) if "planner" + "_" + node.split("_")[1] in self.node_list: self.selected_nodes.remove("planner" + "_" + node.split("_")[1]) if len(self.selected_nodes) > 0: self.ok_button.setEnabled(True) else: self.ok_button.setEnabled(False) def onButtonClicked(self): master = rosgraph.Master('rqt_bag_recorder') state = master.getSystemState() print state[1] subs = [ t for t, l in state[1] if len([ node_name for node_name in self.selected_nodes if node_name in l ]) > 0 ] topic_data_list = master.getPublishedTopics('') topic_data_list.sort() for topic, datatype in topic_data_list: if ("/" + topic.split("/")[1] + "/task" in subs): subs.append(topic) for topic in subs: self.parent_widget.changeTopicCheckState(topic, Qt.Checked) self.parent_widget.updateList(Qt.Checked, topic) self.close()
class SystemWidget(QWidget): """ main class inherits from the ui window class. You can specify the topics that the topic pane. SystemWidget.start must be called in order to update topic pane. """ _column_names = ['topic', 'type', 'bandwidth', 'rate', 'value'] def __init__(self, plugin=None): """ """ super(SystemWidget, self).__init__() rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('rqt_agent'), 'resource', 'SystemWidget.ui') loadUi(ui_file, self) self._plugin = plugin self._subsystems = {} self.all_subsystems = {} self._widgets = {} self.prev_subsystems = [] self.levels_layouts = [] self.structure_root = None self.structure_graph = None self.structure_changed = False self.scrollArea = QScrollArea() self.scrollArea.setWidgetResizable(True) self.horizontalLayout.addWidget(self.scrollArea) self.mainWidget = QWidget() self.scrollArea.setWidget(self.mainWidget) self.verticalLayout = QVBoxLayout() self.mainWidget.setLayout(self.verticalLayout) # self._tree_items = {} # self._column_index = {} # for column_name in self._column_names: # self._column_index[column_name] = len(self._column_index) # self.refresh_topics() # init and start update timer self._timer_refresh_topics = QTimer(self) self._timer_refresh_topics.timeout.connect(self.refresh_topics) def checkStructureChange(self): result = False for subsystem_name in self.prev_subsystems: if not subsystem_name in self._widgets: result = True break if result == False: for subsystem_name in self._widgets: if not subsystem_name in self.prev_subsystems: result = True break self.prev_subsystems = [] for subsystem_name in self._widgets: self.prev_subsystems.append(subsystem_name) return result def start(self): """ This method needs to be called to start updating topic pane. """ self._timer_refresh_topics.start(100) def generateStructure(self): names = [] for w1_name in self._widgets: names.append(w1_name) self._widgets[w1_name].resetBuffersLayout() for w1_name in self._widgets: w1 = self._widgets[w1_name] if not w1.isInitialized(): continue for w2_name in self._widgets: w2 = self._widgets[w2_name] if not w2.isInitialized(): continue common_buffers = w1.getCommonBuffers(w2) if common_buffers != None: w1.groupBuffers(common_buffers, w2.subsystem_name) w2.groupBuffers(common_buffers, w1.subsystem_name) parents_dict = {} for w1_name in self._widgets: w1 = self._widgets[w1_name] if not w1.isInitialized(): continue for w2_name in self._widgets: w2 = self._widgets[w2_name] if not w2.isInitialized(): continue rel_pose = w1.getLowerSubsystemPosition(w2.subsystem_name) if rel_pose != -1: parents_dict[w2_name] = w1_name # print parents_dict # get top-most subsystem (root) root = None if parents_dict: root = list(parents_dict.keys())[0] while root in parents_dict: root = parents_dict[root] levels = [] if root == None: # there are no levels one_level = [] for w_name in self._widgets: one_level.append(w_name) if len(one_level) > 0: levels.append(one_level) else: levels.append([root]) while True: # expand all subsystems in the lowest level current_lowest = levels[-1] next_lower_level = [] for s in current_lowest: lower_list = self._widgets[s].getLowerSubsystems() next_lower_level = next_lower_level + lower_list if len(next_lower_level) == 0: break else: levels.append(next_lower_level) # TODO: manage disjoint trees added_subsystems = [] for l in levels: for s in l: added_subsystems.append(s) for w_name in self._widgets: if not w_name in added_subsystems: print "WARNING: subsystem %s is not in the main tree. This is not implemented." % ( w_name) print "levels:", levels return levels def layout_widgets(self, layout): return (layout.itemAt(i) for i in range(layout.count())) @Slot() def refresh_topics(self): """ refresh tree view items """ # # update the list of subsystems # topic_list = rospy.get_published_topics() if topic_list is None: rospy.logerr( 'Not even a single published topic found. Check network configuration' ) return # start new topic dict new_subsystems = {} for topic_name, topic_type in topic_list: name_split = topic_name.split('/') # print name_split if (len(name_split) == 3) and (name_split[0] == '') and ( name_split[2] == 'diag') and (topic_type == "diagnostic_msgs/DiagnosticArray"): subsystem_name = name_split[1] # if topic is new if subsystem_name not in self._subsystems: # create new TopicInfo topic_info = TopicInfo(topic_name, topic_type) new_subsystems[subsystem_name] = topic_info topic_info.start_monitoring() else: # if topic has been seen before, copy it to new dict and # remove it from the old one new_subsystems[subsystem_name] = self._subsystems[ subsystem_name] del self._subsystems[subsystem_name] # remove unused subsystems while True: repeat = False for s in self._subsystems: if not s in new_subsystems: del self._subsystems[s] repeat = True break if not repeat: break # switch to new topic dict self._subsystems = new_subsystems # print self._subsystems.keys() # # update each subsystem # new_widgets = {} for subsystem_name in self._subsystems: msg = self._subsystems[subsystem_name].last_message if (msg != None) and (len(msg.status) == 2) and \ msg.status[0].name == 'components' and msg.status[1].name == 'diagnostics': name_split = subsystem_name.split('/') if not subsystem_name in self.all_subsystems: self.all_subsystems[subsystem_name] = SubsystemWidget( self._plugin, subsystem_name) if not subsystem_name in self._widgets: new_widgets[subsystem_name] = self.all_subsystems[ subsystem_name] # self.verticalLayout.addWidget(new_widgets[subsystem_name]) else: new_widgets[subsystem_name] = self._widgets[subsystem_name] # del self._widgets[subsystem_name] # for value in msg.status[1].values: # if value.key == 'master_component': # new_widgets[subsystem_name].setStateName(value.value, '') # break # remove unused subsystems # while True: # repeat = False # for s in self._widgets: # if not s in new_widgets: # del self._widgets[s] # repeat = True # break # if not repeat: # break self._widgets = new_widgets # print self._widgets.keys() structure_changed = self.checkStructureChange() if structure_changed: self.structure_changed = True if self.structure_changed: allInitialized = True for subsystem_name in self._widgets: if not self._widgets[subsystem_name].isInitialized(): allInitialized = False break if allInitialized: # remove all widgets from layouts # and remove all layouts for i in reversed(range(len(self.levels_layouts))): layout = self.levels_layouts[i] for i in reversed(range(layout.count())): # The new widget is deleted when its parent is deleted. layout.itemAt(i).widget().setParent(None) self.verticalLayout.removeItem(layout) del layout self.levels_layouts = [] levels = self.generateStructure() for l in levels: hbox = QHBoxLayout() for w in l: hbox.addWidget(self._widgets[w]) self._widgets[w].show() self.levels_layouts.append(hbox) self.verticalLayout.addLayout(hbox) # for # TODO self.structure_changed = False while True: repeat = False for s in self.all_subsystems: if not s in self._widgets: del self.all_subsystems[s] repeat = True break if not repeat: break for subsystem_name in self._widgets: self._widgets[subsystem_name].update_subsystem( self._subsystems[subsystem_name].last_message) def shutdown_plugin(self): for topic in self._topics.values(): topic['info'].stop_monitoring() self._timer_refresh_topics.stop() def set_selected_topics(self, selected_topics): """ @param selected_topics: list of tuple. [(topic_name, topic_type)] @type selected_topics: [] """ rospy.logdebug('set_selected_topics topics={}'.format( len(selected_topics))) self._selected_topics = selected_topics # TODO(Enhancement) Save/Restore tree expansion state def save_settings(self, plugin_settings, instance_settings): header_state = self.topics_tree_widget.header().saveState() instance_settings.set_value('tree_widget_header_state', header_state) def restore_settings(self, pluggin_settings, instance_settings): if instance_settings.contains('tree_widget_header_state'): header_state = instance_settings.value('tree_widget_header_state') if not self.topics_tree_widget.header().restoreState(header_state): rospy.logwarn("rqt_topic: Failed to restore header state.")