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 __init__(self, map_topic='/map', paths=['/move_base/NavFn/plan', '/move_base/TrajectoryPlannerROS/local_plan'], polygons=['/move_base/local_costmap/robot_footprint']): super(NavViewWidget, self).__init__() self._layout = QVBoxLayout() self._button_layout = QHBoxLayout() self.setAcceptDrops(True) self.setWindowTitle('Navigation Viewer') self.paths = paths self.polygons = polygons self.map = map_topic self._tf = tf.TransformListener() self._nav_view = NavView(map_topic, paths, polygons, tf = self._tf, parent = self) self._set_pose = QPushButton('Set Pose') self._set_pose.clicked.connect(self._nav_view.pose_mode) self._set_goal = QPushButton('Set Goal') self._set_goal.clicked.connect(self._nav_view.goal_mode) self._button_layout.addWidget(self._set_pose) self._button_layout.addWidget(self._set_goal) self._layout.addLayout(self._button_layout) self._layout.addWidget(self._nav_view) self.setLayout(self._layout)
def _create_log_bar(self): self.log_dock = QDockWidget(self) self.log_dock.setObjectName('LogFrame') self.log_dock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable) self.log_bar = QWidget(self) self.horizontal_layout_log_bar = QHBoxLayout(self.log_bar) self.horizontal_layout_log_bar.setContentsMargins(2, 0, 2, 0) self.horizontal_layout_log_bar.setObjectName("horizontal_layout_log_bar") # add info label self._log_warning_count = 0 self.log_browser = QTextEdit() self.log_browser.setObjectName("log_browser") self.log_browser.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.log_browser.setLineWrapMode(QTextEdit.NoWrap) # self.log_browser.setMaximumHeight(120) color = QColor(255, 255, 235) bg_style = "QTextEdit#log_browser { background-color: %s;}" % color.name() self.log_bar.setStyleSheet("%s" % (bg_style)) self.horizontal_layout_log_bar.addWidget(self.log_browser) # add hide button self.clear_log_button = QPushButton("clear", self) self.clear_log_button.setObjectName("clear_log_button") self.clear_log_button.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Maximum) self.clear_log_button.clicked.connect(self.on_clear_log_button_clicked) self.clear_log_button.setFlat(True) self.horizontal_layout_log_bar.addWidget(self.clear_log_button) self.log_dock.setWidget(self.log_bar) return self.log_dock
def __init__(self, parent=None, logger=Logger()): QWidgetWithLogger.__init__(self, parent, logger) # start widget hbox = QHBoxLayout() hbox.setMargin(0) hbox.setContentsMargins(0, 0, 0, 0) # get system icon icon = QIcon.fromTheme("view-refresh") size = icon.actualSize(QSize(32, 32)) # add combo box self.parameter_set_names_combo_box = QComboBox() self.parameter_set_names_combo_box.currentIndexChanged[str].connect( self.param_changed) hbox.addWidget(self.parameter_set_names_combo_box) # add refresh button self.get_all_parameter_set_names_button = QPushButton() self.get_all_parameter_set_names_button.clicked.connect( self._get_all_parameter_set_names) self.get_all_parameter_set_names_button.setIcon(icon) self.get_all_parameter_set_names_button.setFixedSize( size.width() + 2, size.height() + 2) hbox.addWidget(self.get_all_parameter_set_names_button) # end widget self.setLayout(hbox) # init widget self.reset_parameter_set_selection()
def __init__(self, context): super(MultiRobotPasserGUIPlugin, self).__init__(context) # Give QObjects reasonable names self.setObjectName('MultiRobotPasserGUIPlugin') # Create QWidget self.widget = QWidget() self.master_layout = QVBoxLayout(self.widget) self.buttons = {} self.button_layout = QHBoxLayout() self.master_layout.addLayout(self.button_layout) for button_text in ["Enable", "Disable"]: button = QPushButton(button_text, self.widget) button.clicked[bool].connect(self.handle_button) button.setCheckable(True) self.button_layout.addWidget(button) self.buttons[button_text] = button self.widget.setObjectName('MultiRobotPasserGUIPluginUI') if context.serial_number() > 1: self.widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number())) context.add_widget(self.widget) self.status_subscriber = rospy.Subscriber("status", Bool, self.status_callback) self.enable = rospy.ServiceProxy("enable", Empty) self.disable = rospy.ServiceProxy("disable", Empty) self.enabled = False self.connect(self.widget, SIGNAL("update"), self.update)
def __init__(self, context): super(EusGUI, self).__init__(context) # Give QObjects reasonable names self.setObjectName('EusGUI') self.msg = None # Create a container widget and give it a layout self._toolbar = QToolBar() self._toolbar.addWidget(QLabel('EusGUI')) self._container = QWidget() self._layout = QVBoxLayout() self._container.setLayout(self._layout) self._layout.addWidget(self._toolbar) self._prev_button = QPushButton('PREV') self._prev_button.clicked.connect(self._prev_cb) self._layout.addWidget(self._prev_button) self._refresh_button = QPushButton('DO IT AGAIN') self._refresh_button.clicked.connect(self._refresh_cb) self._layout.addWidget(self._refresh_button) self._next_button = QPushButton('NEXT') self._next_button.clicked.connect(self._next_cb) self._layout.addWidget(self._next_button) context.add_widget(self._container)
def __init__(self, icon, title, text, detailed_text="", buttons=QMessageBox.Ok): QMessageBox.__init__(self, icon, title, text, buttons) if detailed_text: self.setDetailedText(detailed_text) horizontalSpacer = QSpacerItem(480, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) layout = self.layout() layout.addItem(horizontalSpacer, layout.rowCount(), 0, 1, layout.columnCount()) if QMessageBox.Abort & buttons: self.setEscapeButton(QMessageBox.Abort) elif QMessageBox.Ignore & buttons: self.setEscapeButton(QMessageBox.Ignore) else: self.setEscapeButton(buttons) self.textEdit = textEdit = self.findChild(QTextEdit) if textEdit is not None: textEdit.setMinimumHeight(0) textEdit.setMaximumHeight(600) textEdit.setMinimumWidth(0) textEdit.setMaximumWidth(600) textEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.ignore_all_btn = QPushButton('Don\'t display again') self.addButton(self.ignore_all_btn, QMessageBox.HelpRole)
def __init__(self, parent=None, current_values=None): super(BlacklistDialog, self).__init__(parent) self.setWindowTitle("Blacklist") vbox = QVBoxLayout() self.setLayout(vbox) self._blacklist = Blacklist() if isinstance(current_values, list): for val in current_values: self._blacklist.append(val) vbox.addWidget(self._blacklist) controls_layout = QHBoxLayout() add_button = QPushButton(icon=QIcon.fromTheme('list-add')) rem_button = QPushButton(icon=QIcon.fromTheme('list-remove')) ok_button = QPushButton("Ok") cancel_button = QPushButton("Cancel") add_button.clicked.connect(self._add_item) rem_button.clicked.connect(self._remove_item) ok_button.clicked.connect(self.accept) cancel_button.clicked.connect(self.reject) controls_layout.addWidget(add_button) controls_layout.addWidget(rem_button) controls_layout.addStretch(0) controls_layout.addWidget(ok_button) controls_layout.addWidget(cancel_button) vbox.addLayout(controls_layout)
class WarningMessageBox(QMessageBox): def __init__(self, icon, title, text, detailed_text="", buttons=QMessageBox.Ok): QMessageBox.__init__(self, icon, title, text, buttons) if detailed_text: self.setDetailedText(detailed_text) horizontalSpacer = QSpacerItem(480, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) layout = self.layout() layout.addItem(horizontalSpacer, layout.rowCount(), 0, 1, layout.columnCount()) if QMessageBox.Abort & buttons: self.setEscapeButton(QMessageBox.Abort) elif QMessageBox.Ignore & buttons: self.setEscapeButton(QMessageBox.Ignore) else: self.setEscapeButton(buttons) self.textEdit = textEdit = self.findChild(QTextEdit) if textEdit is not None: textEdit.setMinimumHeight(0) textEdit.setMaximumHeight(600) textEdit.setMinimumWidth(0) textEdit.setMaximumWidth(600) textEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.ignore_all_btn = QPushButton('Don\'t display again') self.addButton(self.ignore_all_btn, QMessageBox.HelpRole) def paintEvent(self, event): QMessageBox.paintEvent(self, event) self.ignore_all_btn.setVisible(self.textEdit.isVisible() if self.textEdit else False)
class MasterSyncButtonHelper(QObject): ''' This is helper class to which contains a button and can emit signals. The MasterSyncItem can not emit signals, but is used in QStandardModel. ''' clicked = Signal(bool, str) NOT_SYNC = 0 SWITCHED = 1 SYNC = 2 ICON_PREFIX = 'irondevil' # ICON_PREFIX = 'crystal_clear' def __init__(self, master): QObject.__init__(self) self.name = master.name self._master = master self._syncronized = MasterSyncButtonHelper.NOT_SYNC self.ICONS = {MasterSyncButtonHelper.SYNC: QIcon(":/icons/%s_sync.png" % self.ICON_PREFIX), MasterSyncButtonHelper.NOT_SYNC: QIcon(":/icons/%s_not_sync.png" % self.ICON_PREFIX), MasterSyncButtonHelper.SWITCHED: QIcon(":/icons/%s_start_sync.png" % self.ICON_PREFIX)} self.widget = QPushButton() # self.widget.setFlat(True) self.widget.setIcon(self.ICONS[MasterSyncButtonHelper.NOT_SYNC]) self.widget.setMaximumSize(48, 48) self.widget.setCheckable(True) self.widget.clicked.connect(self.on_sync_clicked) def on_sync_clicked(self, checked): self.set_sync_state(MasterSyncButtonHelper.SWITCHED) self.clicked.emit(checked, self._master.uri) def master(self): return self._master def get_sync_state(self): return self._syncronized def set_sync_state(self, value): if self._syncronized != value: self._syncronized = value if value in self.ICONS: self.widget.setIcon(self.ICONS[value]) self.widget.setChecked(value == MasterSyncButtonHelper.SYNC) def __eq__(self, item): if isinstance(item, str) or isinstance(item, unicode): return self.master.name.lower() == item.lower() elif not (item is None): return self.master.name.lower() == item.master.name.lower() return False def __gt__(self, item): if isinstance(item, str) or isinstance(item, unicode): return self.master.name.lower() > item.lower() elif not (item is None): return self.master.name.lower() > item.master.name.lower() return False
class MasterSyncButtonHelper(QObject): ''' This is helper class to which contains a button and can emit signals. The MasterSyncItem can not emit signals, but is used in QStandardModel. ''' clicked = Signal(bool, str) NOT_SYNC = 0 SWITCHED = 1 SYNC = 2 ICON_PREFIX = 'irondevil' # ICON_PREFIX = 'crystal_clear' def __init__(self, master): QObject.__init__(self) self.name = master.name self._master = master self._syncronized = MasterSyncButtonHelper.NOT_SYNC self.ICONS = {MasterSyncButtonHelper.SYNC: nm.settings().icon("%s_sync.png" % self.ICON_PREFIX), MasterSyncButtonHelper.NOT_SYNC: nm.settings().icon("%s_not_sync.png" % self.ICON_PREFIX), MasterSyncButtonHelper.SWITCHED: nm.settings().icon("%s_start_sync.png" % self.ICON_PREFIX)} self.widget = QPushButton() # self.widget.setFlat(True) self.widget.setIcon(self.ICONS[MasterSyncButtonHelper.NOT_SYNC]) self.widget.setMaximumSize(48, 48) self.widget.setCheckable(True) self.widget.clicked.connect(self.on_sync_clicked) def on_sync_clicked(self, checked): self.set_sync_state(MasterSyncButtonHelper.SWITCHED) self.clicked.emit(checked, self._master.uri) def master(self): return self._master def get_sync_state(self): return self._syncronized def set_sync_state(self, value): if self._syncronized != value: self._syncronized = value if value in self.ICONS: self.widget.setIcon(self.ICONS[value]) self.widget.setChecked(value == MasterSyncButtonHelper.SYNC) def __eq__(self, item): if isstring(item): return self.master.name.lower() == item.lower() elif not (item is None): return self.master.name.lower() == item.master.name.lower() return False def __gt__(self, item): if isstring(item): return self.master.name.lower() > item.lower() elif not (item is None): return self.master.name.lower() > item.master.name.lower() return False
def _create_buttons(self): # create the buttons line self.buttons = QWidget(self) self.horizontalLayout = QHBoxLayout(self.buttons) self.horizontalLayout.setContentsMargins(4, 0, 4, 0) self.horizontalLayout.setObjectName("horizontalLayout") # add the search button self.searchButton = QPushButton(self) self.searchButton.setObjectName("searchButton") # self.searchButton.clicked.connect(self.on_shortcut_find) self.searchButton.toggled.connect(self.on_toggled_find) self.searchButton.setText(self._translate("&Find")) self.searchButton.setToolTip('Open a search dialog (Ctrl+F)') self.searchButton.setFlat(True) self.searchButton.setCheckable(True) self.horizontalLayout.addWidget(self.searchButton) # add the replace button self.replaceButton = QPushButton(self) self.replaceButton.setObjectName("replaceButton") # self.replaceButton.clicked.connect(self.on_shortcut_replace) self.replaceButton.toggled.connect(self.on_toggled_replace) self.replaceButton.setText(self._translate("&Replace")) self.replaceButton.setToolTip('Open a search&replace dialog (Ctrl+R)') self.replaceButton.setFlat(True) self.replaceButton.setCheckable(True) self.horizontalLayout.addWidget(self.replaceButton) # add the goto button self.gotoButton = QPushButton(self) self.gotoButton.setObjectName("gotoButton") self.gotoButton.clicked.connect(self.on_shortcut_goto) self.gotoButton.setText(self._translate("&Goto line")) self.gotoButton.setShortcut("Ctrl+G") self.gotoButton.setToolTip('Open a goto dialog (Ctrl+G)') self.gotoButton.setFlat(True) self.horizontalLayout.addWidget(self.gotoButton) # add a tag button self.tagButton = self._create_tag_button(self) self.horizontalLayout.addWidget(self.tagButton) # add spacer spacerItem = QSpacerItem(515, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) # add line number label self.pos_label = QLabel() self.horizontalLayout.addWidget(self.pos_label) # add spacer spacerItem = QSpacerItem(515, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) # add save button self.saveButton = QPushButton(self) self.saveButton.setObjectName("saveButton") self.saveButton.clicked.connect(self.on_saveButton_clicked) self.saveButton.setText(self._translate("&Save")) self.saveButton.setShortcut("Ctrl+S") self.saveButton.setToolTip('Save the changes to the file (Ctrl+S)') self.saveButton.setFlat(True) self.horizontalLayout.addWidget(self.saveButton) return self.buttons
def __init__(self, parent = None, logger = Logger(), step_plan_topic = str()): QWidgetWithLogger.__init__(self, parent, logger) # start widget vbox = QVBoxLayout() vbox.setMargin(0) vbox.setContentsMargins(0, 0, 0, 0) # step plan input topic selection if len(step_plan_topic) == 0: step_plan_topic_widget = QTopicWidget(topic_type = 'vigir_footstep_planning_msgs/StepPlan') step_plan_topic_widget.topic_changed_signal.connect(self._init_step_plan_subscriber) vbox.addWidget(step_plan_topic_widget) else: self._init_step_plan_subscriber(step_plan_topic) # execute action server topic selection execute_topic_widget = QTopicWidget(topic_type = 'vigir_footstep_planning_msgs/ExecuteStepPlanAction', is_action_topic = True) execute_topic_widget.topic_changed_signal.connect(self._init_execute_action_client) vbox.addWidget(execute_topic_widget) # start button part buttons_hbox = QHBoxLayout() buttons_hbox.setMargin(0) # execute self.execute_command = QPushButton("Execute (Steps: 0)") self.execute_command.clicked.connect(self.execute_command_callback) self.execute_command.setEnabled(False) buttons_hbox.addWidget(self.execute_command) # repeat self.repeat_command = QPushButton("Repeat") self.repeat_command.clicked.connect(self.execute_command_callback) self.repeat_command.setEnabled(False) buttons_hbox.addWidget(self.repeat_command) # stop self.stop_command = QPushButton("Stop") self.stop_command.clicked.connect(self.stop_command_callback) self.stop_command.setEnabled(False) buttons_hbox.addWidget(self.stop_command) # end button part vbox.addLayout(buttons_hbox) # end widget self.setLayout(vbox) # init widget if len(step_plan_topic) == 0: step_plan_topic_widget.emit_topic_name() execute_topic_widget.emit_topic_name()
def __init__(self, parent=None): super(ComboBoxDialog, self).__init__() self.number = 0 vbox = QtGui.QVBoxLayout(self) self.combo_box = QComboBox(self) self.combo_box.activated.connect(self.onActivated) vbox.addWidget(self.combo_box) button = QPushButton() button.setText("Done") button.clicked.connect(self.buttonCallback) vbox.addWidget(button) self.setLayout(vbox)
def update_buttons(self): self.clean() for index, level in enumerate(self.levels): self.text_label.setText("Choose Level: ") button = QPushButton(level.level_id, self._widget) button.clicked[bool].connect(self.handle_button) button.setCheckable(True) self._button_layout.addWidget(button) self.buttons.append(button) # Subscribe to the current level we are on. if self.status_subscriber is None: self.status_subscriber = rospy.Subscriber("level_mux/current_level", LevelMetaData, self.process_level_status)
def __init__(self, endpoint, name, parent=None): self._endpoint = endpoint self._name = name if not name: self._name = Cam.endpoint_type_as_str(endpoint.server_type) self.name = "%s/%d" % (self._name, endpoint.resource_id) QPushButton.__init__(self, self.name, parent) self.setCheckable(True) self.setFocusPolicy(Qt.NoFocus) self.setFixedHeight(24) # self.setFixedSize(57, 24) self.toggled.connect(self._on_toggled) self._ignore_next_click = False
def __init__(self, context): super(ImageSnapShotGUI, self).__init__(context) # Give QObjects reasonable names self.setObjectName('ImageSnapShotGUI') # Process standalone plugin command-line arguments from argparse import ArgumentParser parser = ArgumentParser() # Add argument(s) to the parser. parser.add_argument("-q", "--quiet", action="store_true", dest="quiet", help="Put plugin in silent mode") args, unknowns = parser.parse_known_args(context.argv()) self._toolbar = QToolBar() self._toolbar.addWidget(QLabel('ImageSnapShot')) # Create a container widget and give it a layout self._container = QWidget() self._layout = QVBoxLayout() self._container.setLayout(self._layout) self._layout.addWidget(self._toolbar) # Add a button for .... self._go_button = QPushButton('Head') self._go_button.clicked.connect(self._head) self._layout.addWidget(self._go_button) self._clear_button = QPushButton('Larm') self._clear_button.clicked.connect(self._larm) self._layout.addWidget(self._clear_button) self._clear_button = QPushButton('Rarm') self._clear_button.clicked.connect(self._rarm) self._layout.addWidget(self._clear_button) self._clear_button = QPushButton('L FishEye') self._clear_button.clicked.connect(self._lfisheye) self._layout.addWidget(self._clear_button) self._clear_button = QPushButton('R FishEye') self._clear_button.clicked.connect(self._rfisheye) self._layout.addWidget(self._clear_button) # self._step_run_button.setStyleSheet('QPushButton {color: black}') context.add_widget(self._container) self._head_pub = rospy.Publisher('/head_snap/snapshot', std_msgs.msg.Empty) self._lhand_pub = rospy.Publisher('/lhand_snap/snapshot', std_msgs.msg.Empty) self._rhand_pub = rospy.Publisher('/rhand_snap/snapshot', std_msgs.msg.Empty) self._lfisheye_pub = rospy.Publisher('/lfisheye_snap/snapshot', std_msgs.msg.Empty) self._rfisheye_pub = rospy.Publisher('/rfisheye_snap/snapshot', std_msgs.msg.Empty)
def setup_group_frame(self, group): layout = QVBoxLayout() # grid for buttons for named targets grid = QGridLayout() grid.setSpacing(1) self.button_group = QButtonGroup(self) row = 0 column = 0 named_targets = self.get_named_targets(group) for target in named_targets: button = QPushButton(target) self.button_group.addButton(button) grid.addWidget(button, row, column) column += 1 if column >= self.MAX_COLUMNS: row += 1 column = 0 self.button_group.buttonClicked.connect(self._handle_button_clicked) # grid for show joint value and move arm buttons/text field joint_values_grid = QGridLayout() joint_values_grid.setSpacing(1) button_show_joint_values = QPushButton('Current Joint Values') button_show_joint_values.clicked[bool].connect( self._handle_show_joint_values_clicked) line_edit = QLineEdit() self.text_joint_values.append(line_edit) button_move_to = QPushButton('Move to') button_move_to.clicked[bool].connect(self._handle_move_to_clicked) joint_values_grid.addWidget(button_show_joint_values, 0, 1) joint_values_grid.addWidget(line_edit, 0, 2) joint_values_grid.addWidget(button_move_to, 0, 3) layout.addLayout(grid) line = QFrame() line.setFrameShape(QFrame.HLine) line.setFrameShadow(QFrame.Sunken) layout.addWidget(line) layout.addLayout(joint_values_grid) frame = QFrame() frame.setLayout(layout) return frame
def __init__(self, master): QObject.__init__(self) self.name = master.name self._master = master self._syncronized = MasterSyncButtonHelper.NOT_SYNC self.ICONS = {MasterSyncButtonHelper.SYNC: nm.settings().icon("%s_sync.png" % self.ICON_PREFIX), MasterSyncButtonHelper.NOT_SYNC: nm.settings().icon("%s_not_sync.png" % self.ICON_PREFIX), MasterSyncButtonHelper.SWITCHED: nm.settings().icon("%s_start_sync.png" % self.ICON_PREFIX)} self.widget = QPushButton() # self.widget.setFlat(True) self.widget.setIcon(self.ICONS[MasterSyncButtonHelper.NOT_SYNC]) self.widget.setMaximumSize(48, 48) self.widget.setCheckable(True) self.widget.clicked.connect(self.on_sync_clicked)
def update_buttons(self): self.clean() for index, level in enumerate(self.levels): self.text_label.setText("Choose Level: ") button = QPushButton(level.level_id, self._widget) button.clicked[bool].connect(self.handle_button) button.setCheckable(True) self._button_layout.addWidget(button) self.buttons.append(button) # Subscribe to the current level we are on. if self.status_subscriber is None: self.status_subscriber = rospy.Subscriber( "level_mux/current_level", LevelMetaData, self.process_level_status)
def loadThrusters(self): # Loop over all of the thruster values found in the params for i in range(0, len(self.names)): # Add a button to a list so we can mess with it later self.thrusterButtons.append(QPushButton(self.names[i]['name'])) # Modify setting of the button self.thrusterButtons[i].setCheckable(True) # Save the callbacks in a list self.thrusterCallbacks[self.names[i]['name']] = \ getattr(self, '_handle_thruster' + str(i)) # Connect the callback to the button's toggle event self.thrusterButtons[i].toggled[bool].connect( self.thrusterCallbacks[self.names[i]['name']]) # Add the button to the Ui self._widget.thrusterButtons.addWidget(self.thrusterButtons[i]) # Get the orientation self.thrusterScales.append(0) for v in self.names[i]['orientation'].values(): self.thrusterScales[i] = self.thrusterScales[i] + v # Append a value to the thruster message for this button self.thrusterMessage.data.append(0.0) print self.thrusterScales
def __init__(self, parent): super(TimelineWidget, self).__init__() self.parent = parent self._layout = QHBoxLayout() #self._view = QGraphicsView() self._view = TimelineWidget.TimelineView(self) self._scene = QGraphicsScene() self._colors = [QColor('green'), QColor('yellow'), QColor('red')] self._messages = [None for x in range(20)] self._mq = [1 for x in range(20)] self._view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._view.setScene(self._scene) self._layout.addWidget(self._view, 1) self.pause_button = QPushButton('Pause') self.pause_button.setCheckable(True) self.pause_button.clicked.connect(self.pause) self._layout.addWidget(self.pause_button) self.setLayout(self._layout) self.update.connect(self.redraw)
def __init__(self, parent = None, logger = Logger()): QWidgetWithLogger.__init__(self, parent, logger) # start widget hbox = QHBoxLayout() hbox.setMargin(0) hbox.setContentsMargins(0, 0, 0, 0) # get system icon icon = QIcon.fromTheme("view-refresh") size = icon.actualSize(QSize(32, 32)) # add combo box self.parameter_set_names_combo_box = QComboBox() self.parameter_set_names_combo_box.currentIndexChanged[str].connect(self.param_changed) hbox.addWidget(self.parameter_set_names_combo_box) # add refresh button self.get_all_parameter_set_names_button = QPushButton() self.get_all_parameter_set_names_button.clicked.connect(self._get_all_parameter_set_names) self.get_all_parameter_set_names_button.setIcon(icon) self.get_all_parameter_set_names_button.setFixedSize(size.width()+2, size.height()+2) hbox.addWidget(self.get_all_parameter_set_names_button) # end widget self.setLayout(hbox) # init widget self.reset_parameter_set_selection()
def __init__(self, context, actions): super(ActionClientContainerWidget, self).__init__() grid = QGridLayout() grid.setSpacing(1) MAX_COLUMNS = 2 self.setObjectName('ActionClientContainerWidget') self.clear_button = QPushButton("Clear all") self.clear_button.clicked[bool].connect(self._handle_clear_clicked) grid.addWidget(self.clear_button, 0, 0) self.widgets = [] row = 1 column = 0 for k in sorted(actions.keys()): action_name = k widget = ActionClientWidget(context, action_name, actions[k]) grid.addWidget(widget, row, column) self.widgets.append(widget) column += 1 if column >= MAX_COLUMNS: row += 1 column = 0 self.setLayout(grid)
def add_command_button(self, parent, text, command): button = QPushButton(text) self.command_mapper.setMapping(button, command) button.clicked.connect(self.command_mapper.map) parent.addWidget(button) self.command_buttons.append(button) return button
def __init__(self, context): super(SpectrogramPlugin, self).__init__(context) self.setObjectName('Spectrogram') self._widget = QWidget() layout = QVBoxLayout() self._widget.setLayout(layout) layout_ = QHBoxLayout() self.line_edit = QLineEdit() layout_.addWidget(self.line_edit) self.apply_btn = QPushButton("Apply") self.apply_btn.clicked.connect(self.apply_clicked) layout_.addWidget(self.apply_btn) layout.addLayout(layout_) self.fig = Figure((5, 4), dpi=100) self.canvas = FigureCanvas(self.fig) self.axes = self.fig.add_subplot(111) self.fig.tight_layout() layout.addWidget(self.canvas) context.add_widget(self._widget) self.update_signal.connect(self.update_spectrogram) self.subscriber_signal.connect(self.update_subscriber) self.subscriber_signal.emit('spec')
def __init__(self, path, parent=None): QWidget.__init__(self, parent) self.path = path self._layout = QHBoxLayout(self) self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) self._button = QPushButton('...') self._button.setMaximumSize(QSize(24, 20)) self._button.clicked.connect(self._on_path_select_clicked) self._layout.addWidget(self._button) self._lineedit = QLineEdit(path) self._lineedit.returnPressed.connect(self._on_editing_finished) self._layout.addWidget(self._lineedit) self.setLayout(self._layout) self.setFocusProxy(self._button) self.setAutoFillBackground(True)
def startPropertyEdit(self): self.editing_properties = True self.edit_existing_location = self.edit_properties_location self.edit_area_button[LocationFunction.ADD_LOCATION_AREA].setEnabled(True) self.edit_area_button[LocationFunction.EDIT_EXISTING_AREA].setEnabled(True) # Construct the configuration layout. clearLayoutAndFixHeight(self.configuration_layout) self.update_name_label = QLabel("Location (" + self.edit_properties_location + ") New Name: ", self.widget) self.configuration_layout.addWidget(self.update_name_label) self.update_name_textedit = QLineEdit(self.widget) self.update_name_textedit.setText(self.edit_properties_location) self.update_name_textedit.textEdited.connect(self.locationNameTextEdited) self.configuration_layout.addWidget(self.update_name_textedit) self.update_name_button = QPushButton("Update location Name", self.widget) self.update_name_button.clicked[bool].connect(self.updateLocationName) self.update_name_button.setEnabled(False) self.configuration_layout.addWidget(self.update_name_button) self.remove_location_button = QPushButton("Remove Location", self.widget) self.remove_location_button.clicked[bool].connect(self.removeCurrentLocation) self.configuration_layout.addWidget(self.remove_location_button) self.configuration_layout.addStretch(1) self.updateOverlay()
def __init__(self): super(NodeWidgetsContainer, self).__init__() yaml_file = rospy.get_param("~config_file") stream = open(yaml_file, "r") nodes = yaml.load(stream) rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('mcr_event_gui'), 'ros', 'resources', 'NodeWidgetsContainer.ui') loadUi(ui_file, self) grid = QGridLayout() grid.setSpacing(1) MAX_COLUMNS = 2 self.setObjectName('NodeWidgetsContainer') self.clear_button = QPushButton("Clear all") self.clear_button.clicked[bool].connect(self._handle_clear_clicked) self.stop_button = QPushButton("Stop all") self.stop_button.clicked[bool].connect(self._handle_stop_clicked) grid.addWidget(self.clear_button, 0, 0) grid.addWidget(self.stop_button, 0, 1) self.widgets = [] row = 1 column = 0 for k in sorted(nodes.keys()): node_name = k widget = NodeEventsWidget(node_name, nodes[k]) width = widget.width() height = widget.height() grid.addWidget(widget, row, column) grid.setColumnMinimumWidth(column, width) grid.setRowMinimumHeight(row, height) self.widgets.append(widget) column += 1 if column >= MAX_COLUMNS: row += 1 column = 0 self.setLayout(grid)
class PathEditor(QWidget): ''' This is a path editor used as ItemDeligate in settings view. This editor provides an additional button for directory selection dialog. ''' editing_finished_signal = Signal() def __init__(self, path, parent=None): QWidget.__init__(self, parent) self.path = path self._layout = QHBoxLayout(self) self._layout.setContentsMargins(0, 0, 0, 0) self._layout.setSpacing(0) self._button = QPushButton('...') self._button.setMaximumSize(QSize(24, 20)) self._button.clicked.connect(self._on_path_select_clicked) self._layout.addWidget(self._button) self._lineedit = QLineEdit(path) self._lineedit.returnPressed.connect(self._on_editing_finished) self._layout.addWidget(self._lineedit) self.setLayout(self._layout) self.setFocusProxy(self._button) self.setAutoFillBackground(True) def _on_path_select_clicked(self): # Workaround for QFileDialog.getExistingDirectory because it do not # select the configuration folder in the dialog self.dialog = QFileDialog(self, caption='Select a new settings folder') self.dialog.setOption(QFileDialog.HideNameFilterDetails, True) self.dialog.setFileMode(QFileDialog.Directory) self.dialog.setDirectory(self.path) if self.dialog.exec_(): fileNames = self.dialog.selectedFiles() path = fileNames[0] if os.path.isfile(path): path = os.path.basename(path) self._lineedit.setText(path) self.path = dir self.editing_finished_signal.emit() def _on_editing_finished(self): if self._lineedit.text(): self.path = self._lineedit.text() self.editing_finished_signal.emit()
def __init__(self, masteruri, cfg, ns, nodes, parent=None): QFrame.__init__(self, parent) self._masteruri = masteruri self._nodes = {cfg: {ns: nodes}} frame_layout = QVBoxLayout(self) frame_layout.setContentsMargins(0, 0, 0, 0) # create frame for warning label self.warning_frame = warning_frame = QFrame(self) warning_layout = QHBoxLayout(warning_frame) warning_layout.setContentsMargins(0, 0, 0, 0) warning_layout.addItem( QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) self.warning_label = QLabel() icon = nm.settings().icon('crystal_clear_warning.png') self.warning_label.setPixmap(icon.pixmap(QSize(40, 40))) self.warning_label.setToolTip( 'Multiple configuration for same node found!\nA first one will be selected for the start a node!' ) warning_layout.addWidget(self.warning_label) warning_layout.addItem( QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) frame_layout.addItem( QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) frame_layout.addWidget(warning_frame) # create frame for start/stop buttons buttons_frame = QFrame() buttons_layout = QHBoxLayout(buttons_frame) buttons_layout.setContentsMargins(0, 0, 0, 0) buttons_layout.addItem(QSpacerItem(20, 20)) self.on_button = QPushButton() self.on_button.setFlat(False) self.on_button.setText("On") self.on_button.clicked.connect(self.on_on_clicked) buttons_layout.addWidget(self.on_button) self.off_button = QPushButton() self.off_button.setFlat(True) self.off_button.setText("Off") self.off_button.clicked.connect(self.on_off_clicked) buttons_layout.addWidget(self.off_button) buttons_layout.addItem(QSpacerItem(20, 20)) frame_layout.addWidget(buttons_frame) frame_layout.addItem( QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) self.warning_frame.setVisible(False)
def __init__(self, updater, config): self.updater = ApplyGroup.ApplyUpdater(updater) super(ApplyGroup, self).__init__(self.updater, config) self.button = QPushButton("Apply %s" % self.name) self.button.clicked.connect(self.updater.apply_update) rows = self.grid.rowCount() self.grid.addWidget(self.button, rows + 1, 1, Qt.AlignRight)
def __init__(self): super(Tester, self).__init__(); vlayout = QVBoxLayout(); self.testButton = QPushButton("Exactly one row of buttons"); vlayout.addWidget(self.testButton); self.testButton.clicked.connect(self.exactlyOneRow); self.setLayout(vlayout); self.show();
def __init__(self, buttonProgramArrayIterator): super(ButtonSetPopupSelector, self).__init__(); self.setStyleSheet(SpeakEasyGUI.stylesheetAppBG); self.programButtonDict = {}; self.buttonProgramArrayIt = buttonProgramArrayIterator; self.buttonProgramArrays = []; # saved ButtonProgram arrays self.shownLabelArrays = []; self.currentlyShowingSetIndex = None; self.rootLayout = None; self.cancelButton = QPushButton("Cancel"); self.cancelButton.setStyleSheet(SpeakEasyGUI.recorderButtonStylesheet); self.cancelButton.setMinimumHeight(SpeakEasyGUI.BUTTON_MIN_HEIGHT); #self.cancelButton.clicked.connect(partial(QDialog.done, self, 0)); self.cancelButton.clicked.connect(self.clickedCancelButton); self.OKButton = QPushButton("Pick this One"); self.OKButton.setStyleSheet(SpeakEasyGUI.recorderButtonStylesheet); self.OKButton.setMinimumHeight(SpeakEasyGUI.BUTTON_MIN_HEIGHT); self.OKButton.clicked.connect(self.clickedOKButton); self.currentNextPrevDirection = NextPrev.NEXT; self.nextButton = QPushButton("Next"); self.nextButton.setStyleSheet(SpeakEasyGUI.recorderButtonStylesheet); self.nextButton.setMinimumHeight(SpeakEasyGUI.BUTTON_MIN_HEIGHT); self.nextButton.clicked.connect(self.clickedNextButton); self.prevButton = QPushButton("Previous"); self.prevButton.setStyleSheet(SpeakEasyGUI.recorderButtonStylesheet); self.prevButton.setMinimumHeight(SpeakEasyGUI.BUTTON_MIN_HEIGHT); self.prevButton.clicked.connect(self.clickedPrevButton); self.setNextPrevButtonsEnabledness(); self.endOfSetsLabel = QLabel("<b>No more button sets.</b>") self.noSetsLabel = QLabel("<b>No button sets available.</b>") self.noAvailableSets = False; self.offerNewButtonSet();
def __init__(self, context): super(MultiRobotPatrollerPlugin, self).__init__(context) # Give QObjects reasonable names self.setObjectName('MultiRobotPatrollerPlugin') # Create QWidget self.widget = QWidget() self.master_layout = QVBoxLayout(self.widget) self.buttons = [] self.button_layout = QHBoxLayout() self.master_layout.addLayout(self.button_layout) for button_text in ["Play", "Pause"]: button = QPushButton(button_text, self.widget) button.clicked[bool].connect(self.handle_button) button.setCheckable(True) self.button_layout.addWidget(button) if button_text == "Pause": button.setChecked(True) self.buttons.append(button) self.text_labels = {} self.widget.setObjectName('MultiRobotPatrollerPluginUI') if context.serial_number() > 1: self.widget.setWindowTitle(self._widget.windowTitle() + (' (%d)' % context.serial_number())) context.add_widget(self.widget) self.points = rospy.get_param("points") self.flip_direction = rospy.get_param("flip_direction") self.available_robots = [] self.global_start_counter = 0 self.global_forward = True self.available_robot_subscriber = rospy.Subscriber("/available_robots", AvailableRobotArray, self.available_robot_callback) self.robot_goals = {} self.paused = True self.connect(self.widget, SIGNAL("update"), self.update)
def activateFunction(self): # Add all the necessary buttons to the subfunction layout. clearLayoutAndFixHeight(self.subfunction_layout) for button_text in [LocationFunction.ADD_LOCATION_AREA, LocationFunction.EDIT_EXISTING_AREA]: button = QPushButton(button_text, self.widget) button.clicked[bool].connect(partial(self.startAreaEdit, button_text)) button.setCheckable(True) self.subfunction_layout.addWidget(button) self.edit_area_button[button_text] = button self.edit_area_button[LocationFunction.EDIT_EXISTING_AREA].setEnabled(False) self.subfunction_layout.addStretch(1) # ActivateMouseHooks. self.image.mousePressEvent = self.mousePressEvent self.image.mouseMoveEvent = self.mouseMoveEvent self.image.mouseReleaseEvent = self.mouseReleaseEvent self.updateOverlay()
def startPropertyEdit(self): self.editing_properties = True self.edit_existing_location = self.edit_properties_location self.edit_area_button[LocationFunction.ADD_LOCATION_AREA].setEnabled( True) self.edit_area_button[LocationFunction.EDIT_EXISTING_AREA].setEnabled( True) # Construct the configuration layout. clearLayoutAndFixHeight(self.configuration_layout) neighbors_str = makeNeighborsString( self.locations[self.edit_properties_location], self.locations) self.update_name_label = QLabel( "Location (" + self.edit_properties_location + " - " + neighbors_str + ") New Name: ", self.widget) self.configuration_layout.addWidget(self.update_name_label) self.update_name_textedit = QLineEdit(self.widget) self.update_name_textedit.setText(self.edit_properties_location) self.update_name_textedit.textEdited.connect( self.locationNameTextEdited) self.configuration_layout.addWidget(self.update_name_textedit) self.update_name_button = QPushButton("Update location Name", self.widget) self.update_name_button.clicked[bool].connect(self.updateLocationName) self.update_name_button.setEnabled(False) self.configuration_layout.addWidget(self.update_name_button) self.remove_location_button = QPushButton("Remove Location", self.widget) self.remove_location_button.clicked[bool].connect( self.removeCurrentLocation) self.configuration_layout.addWidget(self.remove_location_button) self.configuration_layout.addStretch(1) self.updateOverlay()
def __init__(self, parent=None, logger=Logger()): QWidgetWithLogger.__init__(self, parent, logger) # start widget vbox = QVBoxLayout() vbox.setMargin(0) vbox.setContentsMargins(0, 0, 0, 0) # add layout which is dynamically filled self.parameter_tree_widget = QParameterTreeWidget(logger=self.logger) vbox.addWidget(self.parameter_tree_widget) # button panel vbox_commands = QVBoxLayout() hbox = QHBoxLayout() # upload topic send_parameter_topic_widget = QTopicWidget(self, 'vigir_footstep_planning_msgs/SetParameterSetAction', True) send_parameter_topic_widget.topic_changed_signal.connect(self._init_upload_paramater_set_client) hbox.addWidget(send_parameter_topic_widget) # upload command self.upload_command = QPushButton("Upload") self.upload_command.clicked.connect(self.upload_parameters) hbox.addWidget(self.upload_command) vbox_commands.addLayout(hbox) # reload command self.reload_command = QPushButton("Reload") self.reload_command.clicked.connect(self.reload_parameters) vbox_commands.addWidget(self.reload_command) # add button panel vbox.addLayout(vbox_commands) # end widget self.setLayout(vbox) # init self.clear() send_parameter_topic_widget.emit_topic_name()
def generate_task_buttons(self, task_list): # remove existing tasks that aren't in received list # two steps to avoid modifying the dict while iterating tasks_to_remove = [name for name in self._task_map if name not in task_list] for name in tasks_to_remove: self._task_map[name].button.setParent(None) del self._task_map[name] # add received tasks that we don't have yet for name in task_list: if name not in self._task_map: button = QPushButton(name, self._widget.scrollAreaWidgetContents) button.clicked.connect(self.task_buttons_click_slot) button.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) self._layout.addWidget(button) self._task_map[name] = TaskInfo(name, button) self.refresh_button_highlighting()
def __init__(self): super(CalibrationMovementsGUI, self).__init__() move_group_name = rospy.get_param('~move_group', 'manipulator') self.angle_delta = math.radians( rospy.get_param('~rotation_delta_degrees', 25)) self.translation_delta = rospy.get_param('~translation_delta_meters', 0.1) max_velocity_scaling = rospy.get_param('~max_velocity_scaling', 0.5) max_acceleration_scaling = rospy.get_param('~max_acceleration_scaling', 0.5) self.local_mover = CalibrationMovements(move_group_name, max_velocity_scaling, max_acceleration_scaling) self.current_pose = -1 self.current_plan = None self.state = CalibrationMovementsGUI.NOT_INITED_YET self.layout = QVBoxLayout() self.labels_layout = QHBoxLayout() self.buttons_layout = QHBoxLayout() self.progress_bar = QProgressBar() self.pose_number_lbl = QLabel('0/8') self.bad_plan_lbl = QLabel('No plan yet') self.guide_lbl = QLabel('Hello') self.guide_lbl.setWordWrap(True) self.check_start_pose_btn = QPushButton('Check starting pose') self.check_start_pose_btn.clicked.connect( self.handle_check_current_state) self.next_pose_btn = QPushButton('Next Pose') self.next_pose_btn.clicked.connect(self.handle_next_pose) self.plan_btn = QPushButton('Plan') self.plan_btn.clicked.connect(self.handle_plan) self.execute_btn = QPushButton('Execute') self.execute_btn.clicked.connect(self.handle_execute) self.labels_layout.addWidget(self.pose_number_lbl) self.labels_layout.addWidget(self.bad_plan_lbl) self.buttons_layout.addWidget(self.check_start_pose_btn) self.buttons_layout.addWidget(self.next_pose_btn) self.buttons_layout.addWidget(self.plan_btn) self.buttons_layout.addWidget(self.execute_btn) self.layout.addWidget(self.progress_bar) self.layout.addLayout(self.labels_layout) self.layout.addWidget(self.guide_lbl) self.layout.addLayout(self.buttons_layout) self.setLayout(self.layout) self.plan_btn.setEnabled(False) self.execute_btn.setEnabled(False) self.setWindowTitle('Local Mover') self.show()
def __init__(self, masteruri, cfg, ns, nodes, parent=None): QFrame.__init__(self, parent) self._masteruri = masteruri self._nodes = {cfg: {ns: nodes}} frame_layout = QVBoxLayout(self) frame_layout.setContentsMargins(0, 0, 0, 0) # create frame for warning label self.warning_frame = warning_frame = QFrame(self) warning_layout = QHBoxLayout(warning_frame) warning_layout.setContentsMargins(0, 0, 0, 0) warning_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) self.warning_label = QLabel() icon = QIcon(':/icons/crystal_clear_warning.png') self.warning_label.setPixmap(icon.pixmap(QSize(40, 40))) self.warning_label.setToolTip('Multiple configuration for same node found!\nA first one will be selected for the start a node!') warning_layout.addWidget(self.warning_label) warning_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) frame_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) frame_layout.addWidget(warning_frame) # create frame for start/stop buttons buttons_frame = QFrame() buttons_layout = QHBoxLayout(buttons_frame) buttons_layout.setContentsMargins(0, 0, 0, 0) buttons_layout.addItem(QSpacerItem(20, 20)) self.on_button = QPushButton() self.on_button.setFlat(False) self.on_button.setText("On") self.on_button.clicked.connect(self.on_on_clicked) buttons_layout.addWidget(self.on_button) self.off_button = QPushButton() self.off_button.setFlat(True) self.off_button.setText("Off") self.off_button.clicked.connect(self.on_off_clicked) buttons_layout.addWidget(self.off_button) buttons_layout.addItem(QSpacerItem(20, 20)) frame_layout.addWidget(buttons_frame) frame_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) self.warning_frame.setVisible(False)
def __init__(self, parent=None): super(LineEditDialog, self).__init__() self.value = None vbox = QtGui.QVBoxLayout(self) # combo box model = QtGui.QStandardItemModel(self) for elm in rospy.get_param_names(): model.setItem(model.rowCount(), 0, QtGui.QStandardItem(elm)) self.combo_box = QtGui.QComboBox(self) self.line_edit = QtGui.QLineEdit() self.combo_box.setLineEdit(self.line_edit) self.combo_box.setCompleter(QtGui.QCompleter()) self.combo_box.setModel(model) self.combo_box.completer().setModel(model) self.combo_box.lineEdit().setText('') vbox.addWidget(self.combo_box) # button button = QPushButton() button.setText("Done") button.clicked.connect(self.buttonCallback) vbox.addWidget(button) self.setLayout(vbox)
def _create_layout(self): name_hor_sub_widget = QWidget() name_hor_layout = QHBoxLayout(name_hor_sub_widget) name_widget = QLabel(self.name + ": ") name_hor_layout.addWidget(name_widget) if self.add == True: btn_add = QPushButton("+", name_hor_sub_widget) btn_add.clicked.connect(self._push_param) btn_add.clicked.connect(self._update_item) name_hor_layout.addWidget(btn_add) btn_subtract = QPushButton("-", name_hor_sub_widget) btn_subtract.clicked.connect(self._pop_param) btn_subtract.clicked.connect(self._update_item) name_hor_layout.addWidget(btn_subtract) pass self.arg_ver_layout.addWidget(name_hor_sub_widget) self.dlg_layout.addWidget(self.arg_ver_sub_widget) self._update_item()
class WarningMessageBox(QMessageBox): def __init__(self, icon, title, text, detailed_text="", buttons=QMessageBox.Ok): QMessageBox.__init__(self, icon, title, text, buttons) self.textEdit = None if detailed_text: self.setDetailedText(detailed_text) self.textEdit = textEdit = self.findChild(QTextEdit) if textEdit is not None: textEdit.setMinimumHeight(0) textEdit.setMaximumHeight(16777215) textEdit.setMinimumWidth(0) textEdit.setMaximumWidth(16777215) textEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # horizontalSpacer = QSpacerItem(480, 0, QSizePolicy.Minimum, QSizePolicy.Expanding) # layout = self.layout() # layout.addItem(horizontalSpacer, layout.rowCount(), 0, 1, layout.columnCount()) if QMessageBox.Abort & buttons: self.setEscapeButton(QMessageBox.Abort) elif QMessageBox.Ignore & buttons: self.setEscapeButton(QMessageBox.Ignore) elif QMessageBox.Cancel & buttons: self.setEscapeButton(QMessageBox.Cancel) else: self.setEscapeButton(buttons) self.ignore_all_btn = QPushButton('Don\'t display again') self.addButton(self.ignore_all_btn, QMessageBox.HelpRole) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.ignore_all_btn.setVisible(False) def paintEvent(self, event): QMessageBox.paintEvent(self, event) if self.textEdit is not None: if self.textEdit.isVisible(): if not self.ignore_all_btn.isVisible(): self.ignore_all_btn.setVisible(True) self.setSizeGripEnabled(True) self.setMaximumHeight(16777215) self.setMaximumWidth(16777215) elif not self.textEdit.isVisible(): if self.ignore_all_btn.isVisible(): self.ignore_all_btn.setVisible(False) self.setSizeGripEnabled(False)
def __init__(self, parent = None, topic_type = str(), is_action_topic = False): QWidget.__init__(self, parent) if is_action_topic: self.topic_type = topic_type + "Goal" else: self.topic_type = topic_type self.is_action_topic = is_action_topic # start widget hbox = QHBoxLayout() hbox.setMargin(0) hbox.setContentsMargins(0, 0, 0, 0) # topic combo box self.topic_combo_box = QComboBox() self.topic_combo_box.setEnabled(False) self.topic_combo_box.blockSignals(True) self.topic_combo_box.setValidator(QRegExpValidator(QRegExp('((\d|\w|/)(?!//))*'), self)) self.topic_combo_box.currentIndexChanged[str].connect(self.topic_changed) hbox.addWidget(self.topic_combo_box) # get system icon icon = QIcon.fromTheme("view-refresh") size = icon.actualSize(QSize(32, 32)) # add refresh button refresh_topics_button = QPushButton() refresh_topics_button.clicked.connect(self.update_topic_list) refresh_topics_button.setIcon(icon) refresh_topics_button.setFixedSize(size.width()+2, size.height()+2) hbox.addWidget(refresh_topics_button) # end widget self.setLayout(hbox) # init widget self.update_topic_list()
def __init__(self, master): QObject.__init__(self) self.name = master.name self._master = master self._syncronized = MasterSyncButtonHelper.NOT_SYNC self.ICONS = {MasterSyncButtonHelper.SYNC: QIcon(":/icons/%s_sync.png" % self.ICON_PREFIX), MasterSyncButtonHelper.NOT_SYNC: QIcon(":/icons/%s_not_sync.png" % self.ICON_PREFIX), MasterSyncButtonHelper.SWITCHED: QIcon(":/icons/%s_start_sync.png" % self.ICON_PREFIX)} self.widget = QPushButton() # self.widget.setFlat(True) self.widget.setIcon(self.ICONS[MasterSyncButtonHelper.NOT_SYNC]) self.widget.setMaximumSize(48, 48) self.widget.setCheckable(True) self.widget.clicked.connect(self.on_sync_clicked)
def _create_find_frame(self): find_frame = QFrame(self) find_hbox_layout = QHBoxLayout(find_frame) find_hbox_layout.setContentsMargins(0, 0, 0, 0) find_hbox_layout.setSpacing(1) self.search_field = EnchancedLineEdit(find_frame) self.search_field.setPlaceholderText('search text') self.search_field.textChanged.connect(self.on_search_text_changed) self.search_field.returnPressed.connect(self.on_search) find_hbox_layout.addWidget(self.search_field) self.search_result_label = QLabel(find_frame) self.search_result_label.setText(' ') find_hbox_layout.addWidget(self.search_result_label) self.find_button_back = QPushButton("<") self.find_button_back.setFixedWidth(44) self.find_button_back.clicked.connect(self.on_search_back) find_hbox_layout.addWidget(self.find_button_back) self.find_button = QPushButton(">") self.find_button.setDefault(True) # self.find_button.setFlat(True) self.find_button.setFixedWidth(44) self.find_button.clicked.connect(self.on_search) find_hbox_layout.addWidget(self.find_button) return find_frame
def __init__(self, parent=None): super(VisualizerWidget, self).__init__(parent) self.setWindowTitle('Graph Profiler Visualizer') vbox = QVBoxLayout() self.setLayout(vbox) toolbar_layout = QHBoxLayout() refresh_button = QPushButton() refresh_button.setIcon(QIcon.fromTheme('view-refresh')) auto_refresh_checkbox = QCheckBox("Auto Refresh") hide_disconnected_topics = QCheckBox("Hide Disconnected Topics") topic_blacklist_button = QPushButton("Topic Blacklist") node_blacklist_button = QPushButton("Node Blacklist") refresh_button.clicked.connect(self._refresh) topic_blacklist_button.clicked.connect(self._edit_topic_blacklist) node_blacklist_button.clicked.connect(self._edit_node_blacklist) auto_refresh_checkbox.setCheckState(2) auto_refresh_checkbox.stateChanged.connect(self._autorefresh_changed) hide_disconnected_topics.setCheckState(2) hide_disconnected_topics.stateChanged.connect(self._hidedisconnectedtopics_changed) toolbar_layout.addWidget(refresh_button) toolbar_layout.addWidget(auto_refresh_checkbox) toolbar_layout.addStretch(0) toolbar_layout.addWidget(hide_disconnected_topics) toolbar_layout.addWidget(topic_blacklist_button) toolbar_layout.addWidget(node_blacklist_button) vbox.addLayout(toolbar_layout) # Initialize the Visualizer self._view = qt_view.QtView() self._adapter = rosprofiler_adapter.ROSProfileAdapter(self._view) self._adapter.set_topic_quiet_list(TOPIC_BLACKLIST) self._adapter.set_node_quiet_list(NODE_BLACKLIST) vbox.addWidget(self._view)
class TextSearchFrame(QDockWidget): ''' A frame to find text in the Editor. ''' search_result_signal = Signal(str, bool, str, int) ''' @ivar: A signal emitted after search_threaded was started. (search text, found or not, file, position in text) for each result a signal will be emitted. ''' replace_signal = Signal(str, str, int, str) ''' @ivar: A signal emitted to replace string at given position. (search text, file, position in text, replaced by text) ''' def __init__(self, tabwidget, parent=None): QDockWidget.__init__(self, "Find", parent) self.setObjectName('SearchFrame') self.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable) self._dockwidget = QFrame(self) self.vbox_layout = QVBoxLayout(self._dockwidget) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(1) # frame with two rows for find and replace find_replace_frame = QFrame(self) find_replace_vbox_layout = QVBoxLayout(find_replace_frame) find_replace_vbox_layout.setContentsMargins(0, 0, 0, 0) find_replace_vbox_layout.setSpacing(1) # find_replace_vbox_layout.addSpacerItem(QSpacerItem(1, 1, QSizePolicy.Expanding, QSizePolicy.Expanding)) # create frame with find row find_frame = self._create_find_frame() find_replace_vbox_layout.addWidget(find_frame) rplc_frame = self._create_replace_frame() find_replace_vbox_layout.addWidget(rplc_frame) # frame for find&replace and search results self.vbox_layout.addWidget(find_replace_frame) self.vbox_layout.addWidget(self._create_found_frame()) # self.vbox_layout.addStretch(2024) self.setWidget(self._dockwidget) # intern search parameters self._tabwidget = tabwidget self.current_search_text = '' self.search_results = [] self.search_results_fileset = set() self._search_result_index = -1 self._search_recursive = False self._search_thread = None def _create_find_frame(self): find_frame = QFrame(self) find_hbox_layout = QHBoxLayout(find_frame) find_hbox_layout.setContentsMargins(0, 0, 0, 0) find_hbox_layout.setSpacing(1) self.search_field = EnchancedLineEdit(find_frame) self.search_field.setPlaceholderText('search text') self.search_field.textChanged.connect(self.on_search_text_changed) self.search_field.returnPressed.connect(self.on_search) find_hbox_layout.addWidget(self.search_field) self.search_result_label = QLabel(find_frame) self.search_result_label.setText(' ') find_hbox_layout.addWidget(self.search_result_label) self.find_button_back = QPushButton("<") self.find_button_back.setFixedWidth(44) self.find_button_back.clicked.connect(self.on_search_back) find_hbox_layout.addWidget(self.find_button_back) self.find_button = QPushButton(">") self.find_button.setDefault(True) # self.find_button.setFlat(True) self.find_button.setFixedWidth(44) self.find_button.clicked.connect(self.on_search) find_hbox_layout.addWidget(self.find_button) return find_frame def _create_replace_frame(self): # create frame with replace row self.rplc_frame = rplc_frame = QFrame(self) rplc_hbox_layout = QHBoxLayout(rplc_frame) rplc_hbox_layout.setContentsMargins(0, 0, 0, 0) rplc_hbox_layout.setSpacing(1) self.replace_field = EnchancedLineEdit(rplc_frame) self.replace_field.setPlaceholderText('replace text') self.replace_field.returnPressed.connect(self.on_replace) rplc_hbox_layout.addWidget(self.replace_field) self.replace_result_label = QLabel(rplc_frame) self.replace_result_label.setText(' ') rplc_hbox_layout.addWidget(self.replace_result_label) self.replace_button = replace_button = QPushButton("> &Replace >") replace_button.setFixedWidth(90) replace_button.clicked.connect(self.on_replace_click) rplc_hbox_layout.addWidget(replace_button) rplc_frame.setVisible(False) return rplc_frame def _create_found_frame(self): ff_frame = QFrame(self) self.found_files_vbox_layout = QVBoxLayout(ff_frame) self.found_files_vbox_layout.setContentsMargins(0, 0, 0, 0) self.recursive_search_box = QCheckBox("recursive search") self.found_files_vbox_layout.addWidget(self.recursive_search_box) self.found_files_list = QTreeWidget(ff_frame) self.found_files_list.setColumnCount(1) self.found_files_list.setFrameStyle(QFrame.StyledPanel) self.found_files_list.setHeaderHidden(True) self.found_files_list.itemActivated.connect(self.on_itemActivated) self.found_files_list.setStyleSheet( "QTreeWidget {" "background-color:transparent;" "}" "QTreeWidget::item {" "background-color:transparent;" "}" "QTreeWidget::item:selected {" "background-color: darkgray;" "}") self.found_files_vbox_layout.addWidget(self.found_files_list) self.recursive_search_box.setChecked(False) return ff_frame def keyPressEvent(self, event): ''' Enable the shortcats for search and replace ''' self.parent().keyPressEvent(event) def on_search(self): ''' Initiate the new search or request a next search result. ''' if self.current_search_text != self.search_field.text() or self._search_recursive != self.recursive_search_box.isChecked(): # clear current search results self._reset() self.current_search_text = self.search_field.text() if self.current_search_text: path_text = {} self._wait_for_result = True for i in range(self._tabwidget.count()): path_text[self._tabwidget.widget(i).filename] = self._tabwidget.widget(i).document().toPlainText() self._search_recursive = self.recursive_search_box.isChecked() self._search_thread = TextSearchThread(self.current_search_text, self._tabwidget.currentWidget().filename, path_text=path_text, recursive=self._search_recursive) self._search_thread.search_result_signal.connect(self.on_search_result) self._search_thread.warning_signal.connect(self.on_warning_result) self._search_thread.start() elif self.search_results: self._check_position() if self.search_results: if self._search_result_index + 1 >= len(self.search_results): self._search_result_index = -1 self._search_result_index += 1 (id, search_text, found, path, index, linenr, line) = self.search_results[self._search_result_index] self.search_result_signal.emit(search_text, found, path, index) self.replace_button.setEnabled(True) self._update_label() def on_search_back(self): ''' Slot to handle the search back function. ''' self._check_position(False) if self.search_results: self._search_result_index -= 1 if self._search_result_index < 0: self._search_result_index = len(self.search_results) - 1 self._update_label() (id, search_text, found, path, index, linenr, line) = self.search_results[self._search_result_index] self.search_result_signal.emit(search_text, found, path, index) self.replace_button.setEnabled(True) def _check_position(self, forward=True): try: # if the position of the textCursor was changed by the user, move the search index cur_pos = self._tabwidget.currentWidget().textCursor().position() id, st, _f, pa, idx, lnr, ltxt = self.search_results[self._search_result_index] sear_pos = idx + len(st) if cur_pos != sear_pos: first_idx = self._get_current_index_for_current_file() if first_idx != -1: id, st, _f, pa, idx, lnr, ltxt = self.search_results[first_idx] sear_pos = idx + len(st) while cur_pos > sear_pos and self._tabwidget.currentWidget().filename == pa: first_idx += 1 id, st, _f, pa, idx, lnr, ltxt = self.search_results[first_idx] sear_pos = idx + len(st) self._search_result_index = first_idx if forward: self._search_result_index -= 1 else: self._reset(True) except: pass def _get_current_index_for_current_file(self): for index in range(len(self.search_results)): id, _st, _f, pa, _idx = self.search_results[index] if self._tabwidget.currentWidget().filename == pa: return index return -1 def on_search_result(self, search_text, found, path, index, linenr, line): ''' Slot to handle the signals for search result. This signals are forwarded used search_result_signal. ''' if found and search_text == self.current_search_text: id = "%d:%s" % (index, path) self.search_results_fileset.add(path) item = (search_text, found, path, index) if item not in self.search_results: self.search_results.append((id, search_text, found, path, index, linenr, line)) if self._wait_for_result: self._search_result_index += 1 if index >= self._tabwidget.currentWidget().textCursor().position() or self._tabwidget.currentWidget().filename != path: self._wait_for_result = False self.search_result_signal.emit(search_text, found, path, index) self.replace_button.setEnabled(True) pkg, rpath = package_name(os.path.dirname(path)) itemstr = '%s [%s]' % (os.path.basename(path), pkg) if not self.found_files_list.findItems(itemstr, Qt.MatchExactly): list_item = QTreeWidgetItem(self.found_files_list) list_item.setText(0, itemstr) list_item.setToolTip(0, path) self.found_files_list.insertTopLevelItem(0, list_item) self.found_files_list.expandAll() for i in range(self.found_files_list.topLevelItemCount()): top_item = self.found_files_list.topLevelItem(i) if top_item.text(0) == itemstr: sub_item_str = "%d: %s" % (linenr, line) list_item2 = QTreeWidgetItem() list_item2.setText(0, sub_item_str) list_item2.setWhatsThis(0, id) top_item.addChild(list_item2) #self.found_files_list.setVisible(len(self.search_results_fileset) > 0) self._update_label() def on_warning_result(self, text): rospy.logwarn(text) def on_replace_click(self): self.on_replace() self.on_search() def on_replace(self): ''' Emits the replace signal, but only if currently selected text is equal to the searched one. ''' if self.search_results: try: id, search_text, _found, path, index, linenr, line_text = self.search_results[self._search_result_index] cursor = self._tabwidget.currentWidget().textCursor() if cursor.selectedText() == search_text: rptxt = self.replace_field.text() for rindex in range(self._search_result_index + 1, len(self.search_results)): iid, st, _f, pa, idx, lnr, ltxt = self.search_results[rindex] if path == pa: self.search_results.pop(rindex) self.search_results.insert(rindex, (iid, st, _f, pa, idx + len(rptxt) - len(st), lnr, ltxt)) else: break self._remove_search_result(self._search_result_index) self._search_result_index -= 1 self.replace_signal.emit(search_text, path, index, rptxt) else: self.replace_button.setEnabled(False) except: import traceback print traceback.format_exc() pass def on_itemActivated(self, item): ''' Go to the results for the selected file entry in the list. ''' splits = item.whatsThis(0).split(':') if len(splits) == 2: item_index = int(splits[0]) item_path = splits[1] new_search_index = -1 tmp_index = -1 search_index = -1 tmp_search_text = '' for id, search_text, found, path, index, linenr, line_text in self.search_results: new_search_index += 1 if item_path == path and item_index == index: self._search_result_index = new_search_index self.search_result_signal.emit(search_text, found, path, index) self._update_label() def on_search_text_changed(self, _text): ''' Clear search result if the text was changed. ''' self._reset() def _update_label(self, clear_label=False): ''' Updates the status label for search results. The info is created from search result lists. ''' msg = ' ' if self.search_results: count_files = len(self.search_results_fileset) msg = '%d/%d' % (self._search_result_index + 1, len(self.search_results)) if count_files > 1: msg = '%s(%d)' % (msg, count_files) if self._search_thread is not None and self._search_thread.is_alive(): msg = 'searching..%s' % msg elif not msg.strip() and self.current_search_text: msg = '0 found' self.current_search_text = '' if clear_label: msg = ' ' self.search_result_label.setText(msg) self.find_button_back.setEnabled(len(self.search_results)) self._select_current_item_in_box(self._search_result_index) def file_changed(self, path): ''' Clears search results if for changed file are some search results are available :param path: changed file path :type path: str ''' if path in self.search_results_fileset: self._reset() def set_replace_visible(self, value): self.rplc_frame.setVisible(value) self.raise_() self.activateWindow() if value: self.replace_field.setFocus() self.replace_field.selectAll() self.setWindowTitle("Find / Replace") else: self.setWindowTitle("Find") self.search_field.setFocus() def is_replace_visible(self): return self.rplc_frame.isVisible() def _reset(self, force_new_search=False): # clear current search results if self._search_thread is not None: self._search_thread.search_result_signal.disconnect() self._search_thread.stop() self._search_thread = None self.current_search_text = '' self.search_results = [] self.search_results_fileset = set() self.found_files_list.clear() # self.found_files_list.setVisible(False) self._update_label(True) self._search_result_index = -1 self.find_button_back.setEnabled(False) if force_new_search: self.on_search() def enable(self): self.setVisible(True) # self.show() self.raise_() self.activateWindow() self.search_field.setFocus() self.search_field.selectAll() def _select_current_item_in_box(self, index): try: (id, search_text, found, path, index, linenr, line) = self.search_results[index] for topidx in range(self.found_files_list.topLevelItemCount()): topitem = self.found_files_list.topLevelItem(topidx) for childdx in range(topitem.childCount()): child = topitem.child(childdx) if child.whatsThis(0) == id: child.setSelected(True) elif child.isSelected(): child.setSelected(False) except: pass def _remove_search_result(self, index): try: (id, search_text, found, path, index, linenr, line) = self.search_results.pop(index) pkg, rpath = package_name(os.path.dirname(path)) itemstr = '%s [%s]' % (os.path.basename(path), pkg) found_items = self.found_files_list.findItems(itemstr, Qt.MatchExactly) for item in found_items: for chi in range(item.childCount()): child = item.child(chi) if child.whatsThis(0) == id: item.removeChild(child) break # delete top level item if it is now empty for topidx in range(self.found_files_list.topLevelItemCount()): if self.found_files_list.topLevelItem(topidx).childCount() == 0: self.found_files_list.takeTopLevelItem(topidx) break # create new set with files contain the search text new_path_set = set(path for _id, _st, _fd, path, _idx, lnr, lntxt in self.search_results) self.search_results_fileset = new_path_set # self.found_files_list.setVisible(len(self.search_results_fileset) > 0) except: import traceback print traceback.format_exc()
class QExecuteStepPlanWidget(QWidgetWithLogger): step_plan_sub = None execute_step_plan_client = None step_plan = None def __init__(self, parent = None, logger = Logger(), step_plan_topic = str()): QWidgetWithLogger.__init__(self, parent, logger) # start widget vbox = QVBoxLayout() vbox.setMargin(0) vbox.setContentsMargins(0, 0, 0, 0) # step plan input topic selection if len(step_plan_topic) == 0: step_plan_topic_widget = QTopicWidget(topic_type = 'vigir_footstep_planning_msgs/StepPlan') step_plan_topic_widget.topic_changed_signal.connect(self._init_step_plan_subscriber) vbox.addWidget(step_plan_topic_widget) else: self._init_step_plan_subscriber(step_plan_topic) # execute action server topic selection execute_topic_widget = QTopicWidget(topic_type = 'vigir_footstep_planning_msgs/ExecuteStepPlanAction', is_action_topic = True) execute_topic_widget.topic_changed_signal.connect(self._init_execute_action_client) vbox.addWidget(execute_topic_widget) # start button part buttons_hbox = QHBoxLayout() buttons_hbox.setMargin(0) # execute self.execute_command = QPushButton("Execute (Steps: 0)") self.execute_command.clicked.connect(self.execute_command_callback) self.execute_command.setEnabled(False) buttons_hbox.addWidget(self.execute_command) # repeat self.repeat_command = QPushButton("Repeat") self.repeat_command.clicked.connect(self.execute_command_callback) self.repeat_command.setEnabled(False) buttons_hbox.addWidget(self.repeat_command) # stop self.stop_command = QPushButton("Stop") self.stop_command.clicked.connect(self.stop_command_callback) self.stop_command.setEnabled(False) buttons_hbox.addWidget(self.stop_command) # end button part vbox.addLayout(buttons_hbox) # end widget self.setLayout(vbox) # init widget if len(step_plan_topic) == 0: step_plan_topic_widget.emit_topic_name() execute_topic_widget.emit_topic_name() def shutdown_plugin(self): print "Shutting down ..." if self.step_plan_sub is None: self.step_plan_sub.unregister() print "Done!" def _init_step_plan_subscriber(self, topic_name): if len(topic_name) > 0: if self.step_plan_sub is not None: self.step_plan_sub.unregister() self.step_plan_sub = rospy.Subscriber(topic_name, StepPlan, self.step_plan_callback) print "Step Plan topic changed: " + topic_name def _init_execute_action_client(self, topic_name): if len(topic_name) > 0: self.execute_step_plan_client = actionlib.SimpleActionClient(topic_name, ExecuteStepPlanAction) self.execute_command.setEnabled(self.step_plan is not None) self.repeat_command.setEnabled(False) self.stop_command.setEnabled(False) print "Execution topic changed: " + topic_name def step_plan_callback(self, step_plan): self.step_plan = step_plan self.execute_command.setText("Execute (Steps: " + str(len(step_plan.steps)) + ")") if len(step_plan.steps) > 0: self.execute_command.setEnabled(self.execute_step_plan_client is not None) self.repeat_command.setEnabled(False) def execute_command_callback(self): if (self.execute_step_plan_client.wait_for_server(rospy.Duration(0.5))): self.execute_command.setEnabled(False) self.repeat_command.setEnabled(True) self.stop_command.setEnabled(True) self.logger.log_info("Executing footstep plan...") goal = ExecuteStepPlanGoal() goal.step_plan = self.step_plan self.execute_step_plan_client.send_goal(goal) else: self.logger.log_error("Can't connect to footstep controller action server!") def stop_command_callback(self): self.stop_command.setEnabled(False) self.execute_step_plan_client.cancel_goal() self.logger.log_info("Preempting step plan.")
class TimelineWidget(QWidget): class TimelineView(QGraphicsView): def __init__(self, parent): super(TimelineWidget.TimelineView, self).__init__() self.parent = parent def mouseReleaseEvent(self, event): self.parent.mouse_release(event) update = pyqtSignal() def __init__(self, parent): super(TimelineWidget, self).__init__() self.parent = parent self._layout = QHBoxLayout() #self._view = QGraphicsView() self._view = TimelineWidget.TimelineView(self) self._scene = QGraphicsScene() self._colors = [QColor('green'), QColor('yellow'), QColor('red')] self._messages = [None for x in range(20)] self._mq = [1 for x in range(20)] self._view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self._view.setScene(self._scene) self._layout.addWidget(self._view, 1) self.pause_button = QPushButton('Pause') self.pause_button.setCheckable(True) self.pause_button.clicked.connect(self.pause) self._layout.addWidget(self.pause_button) self.setLayout(self._layout) self.update.connect(self.redraw) def redraw(self): self._scene.clear() self._scene for i, m in enumerate(self._mq): w = float(self._view.viewport().width())/len(self._mq) h = self._view.viewport().height() rect = self._scene.addRect(w*i, 0, w, h, QColor('black'), self._colors[m]) def mouse_release(self, event): i = int(floor(event.x()/(float(self._view.viewport().width())/len(self._mq)))) msg = self._messages[i] if msg: self.parent.pause(msg) if not self.pause_button.isChecked(): self.pause_button.toggle() def resizeEvent(self, event): self.redraw() def get_worst(self, msg): lvl = 0 for status in msg.status: if status.level > lvl: lvl = status.level return lvl def add_message(self, msg): self._messages = self._messages[1:] self._messages.append(msg) self._mq = self._mq[1:] try: lvl = msg.level except AttributeError: lvl = self.get_worst(msg) if lvl > 2: lvl = 2 self._mq.append(lvl) self.update.emit() def pause(self, state): if state: self.parent.pause(self._messages[-1]) else: self.parent.unpause()
class PlotWidget(QWidget): def __init__(self, timeline, parent, topic): super(PlotWidget, self).__init__(parent) self.setObjectName('PlotWidget') self.timeline = timeline msg_type = self.timeline.get_datatype(topic) self.msgtopic = topic self.start_stamp = self.timeline._get_start_stamp() self.end_stamp = self.timeline._get_end_stamp() # the current region-of-interest for our bag file # all resampling and plotting is done with these limits self.limits = [0,(self.end_stamp-self.start_stamp).to_sec()] rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('rqt_bag_plugins'), 'resource', 'plot.ui') loadUi(ui_file, self) self.message_tree = MessageTree(msg_type, self) self.data_tree_layout.addWidget(self.message_tree) # TODO: make this a dropdown with choices for "Auto", "Full" and # "Custom" # I continue to want a "Full" option here self.auto_res.stateChanged.connect(self.autoChanged) self.resolution.editingFinished.connect(self.settingsChanged) self.resolution.setValidator(QDoubleValidator(0.0,1000.0,6,self.resolution)) self.timeline.selected_region_changed.connect(self.region_changed) self.recompute_timestep() self.plot = DataPlot(self) self.plot.set_autoscale(x=False) self.plot.set_autoscale(y=DataPlot.SCALE_VISIBLE) self.plot.autoscroll(False) self.plot.set_xlim(self.limits) self.data_plot_layout.addWidget(self.plot) self._home_button = QPushButton() self._home_button.setToolTip("Reset View") self._home_button.setIcon(QIcon.fromTheme('go-home')) self._home_button.clicked.connect(self.home) self.plot_toolbar_layout.addWidget(self._home_button) self._config_button = QPushButton("Configure Plot") self._config_button.clicked.connect(self.plot.doSettingsDialog) self.plot_toolbar_layout.addWidget(self._config_button) self.set_cursor(0) self.paths_on = set() self._lines = None # get bag from timeline bag = None start_time = self.start_stamp while bag is None: bag,entry = self.timeline.get_entry(start_time, topic) if bag is None: start_time = self.timeline.get_entry_after(start_time)[1].time self.bag = bag # get first message from bag msg = bag._read_message(entry.position) self.message_tree.set_message(msg[1]) # state used by threaded resampling self.resampling_active = False self.resample_thread = None self.resample_fields = set() def set_cursor(self, position): self.plot.vline(position, color=DataPlot.RED) self.plot.redraw() def add_plot(self, path): self.resample_data([path]) def update_plot(self): if len(self.paths_on)>0: self.resample_data(self.paths_on) def remove_plot(self, path): self.plot.remove_curve(path) self.paths_on.remove(path) self.plot.redraw() def load_data(self): """get a generator for the specified time range on our bag""" return self.bag.read_messages(self.msgtopic, self.start_stamp+rospy.Duration.from_sec(self.limits[0]), self.start_stamp+rospy.Duration.from_sec(self.limits[1])) def resample_data(self, fields): if self.resample_thread: # cancel existing thread and join self.resampling_active = False self.resample_thread.join() for f in fields: self.resample_fields.add(f) # start resampling thread self.resampling_active = True self.resample_thread = threading.Thread(target=self._resample_thread) # explicitly mark our resampling thread as a daemon, because we don't # want to block program exit on a long resampling operation self.resample_thread.setDaemon(True) self.resample_thread.start() def _resample_thread(self): # TODO: # * look into doing partial display updates for long resampling # operations # * add a progress bar for resampling operations x = {} y = {} for path in self.resample_fields: x[path] = [] y[path] = [] msgdata = self.load_data() for entry in msgdata: # detect if we're cancelled and return early if not self.resampling_active: return for path in self.resample_fields: # this resampling method is very unstable, because it picks # representative points rather than explicitly representing # the minimum and maximum values present within a sample # If the data has spikes, this is particularly bad because they # will be missed entirely at some resolutions and offsets if x[path]==[] or (entry[2]-self.start_stamp).to_sec()-x[path][-1] >= self.timestep: y_value = entry[1] for field in path.split('.'): index = None if field.endswith(']'): field = field[:-1] field, _, index = field.rpartition('[') y_value = getattr(y_value, field) if index: index = int(index) y_value = y_value[index] y[path].append(y_value) x[path].append((entry[2]-self.start_stamp).to_sec()) # TODO: incremental plot updates would go here... # we should probably do incremental updates based on time; # that is, push new data to the plot maybe every .5 or .1 # seconds # time is a more useful metric than, say, messages loaded or # percentage, because it will give a reasonable refresh rate # without overloading the computer # if we had a progress bar, we could emit a signal to update it here # update the plot with final resampled data for path in self.resample_fields: if len(x[path]) < 1: qWarning("Resampling resulted in 0 data points for %s" % path) else: if path in self.paths_on: self.plot.clear_values(path) self.plot.update_values(path, x[path], y[path]) else: self.plot.add_curve(path, path, x[path], y[path]) self.paths_on.add(path) self.plot.redraw() self.resample_fields.clear() self.resampling_active = False def recompute_timestep(self): # this is only called if we think the timestep has changed; either # by changing the limits or by editing the resolution limits = self.limits if self.auto_res.isChecked(): timestep = round((limits[1]-limits[0])/200.0,5) else: timestep = float(self.resolution.text()) self.resolution.setText(str(timestep)) self.timestep = timestep def region_changed(self, start, end): # this is the only place where self.limits is set limits = [ (start - self.start_stamp).to_sec(), (end - self.start_stamp).to_sec() ] # cap the limits to the start and end of our bag file if limits[0]<0: limits = [0.0,limits[1]] if limits[1]>(self.end_stamp-self.start_stamp).to_sec(): limits = [limits[0],(self.end_stamp-self.start_stamp).to_sec()] self.limits = limits self.recompute_timestep() self.plot.set_xlim(limits) self.plot.redraw() self.update_plot() def settingsChanged(self): # resolution changed. recompute the timestep and resample self.recompute_timestep() self.update_plot() def autoChanged(self, state): if state==2: # auto mode enabled. recompute the timestep and resample self.resolution.setDisabled(True) self.recompute_timestep() self.update_plot() else: # auto mode disabled. enable the resolution text box # no change to resolution yet, so no need to redraw self.resolution.setDisabled(False) def home(self): # TODO: re-add the button for this. It's useful for restoring the # X and Y limits so that we can see all of the data # effectively a "zoom all" button # reset the plot to our current limits self.plot.set_xlim(self.limits) # redraw the plot; this forces a Y autoscaling self.plot.redraw()
def __init__(self, context): super(LogicalMarkerPlugin, self).__init__(context) # Create an image for the original map. This will never change. try: self.map_yaml_file_str = rospy.get_param("~map_file") self.data_directory = rospy.get_param("~data_directory") except KeyError: rospy.logfatal("~map_file and ~data_directory need to be set to use the logical marker") return map_image_location = getImageFileLocation(self.map_yaml_file_str) map = loadMapFromFile(self.map_yaml_file_str) locations_file = getLocationsFileLocationFromDataDirectory(self.data_directory) doors_file = getDoorsFileLocationFromDataDirectory(self.data_directory) objects_file = getObjectsFileLocationFromDataDirectory(self.data_directory) # Give QObjects reasonable names self.setObjectName('LogicalMarkerPlugin') # Create QWidget self.master_widget = QWidget() self.master_layout = QVBoxLayout(self.master_widget) # Main Functions - Doors, Locations, Objects self.function_layout = QHBoxLayout() self.master_layout.addLayout(self.function_layout) self.function_buttons = [] self.current_function = None for button_text in ['Locations', 'Doors', 'Objects']: button = QPushButton(button_text, self.master_widget) button.clicked[bool].connect(self.handle_function_button) button.setCheckable(True) self.function_layout.addWidget(button) self.function_buttons.append(button) self.function_layout.addStretch(1) self.master_layout.addWidget(self.get_horizontal_line()) # Subfunction toolbar self.subfunction_layout = QHBoxLayout() clearLayoutAndFixHeight(self.subfunction_layout) self.master_layout.addLayout(self.subfunction_layout) self.current_subfunction = None self.master_layout.addWidget(self.get_horizontal_line()) self.image = MapImage(map_image_location, self.master_widget) self.master_layout.addWidget(self.image) self.master_layout.addWidget(self.get_horizontal_line()) # Configuration toolbar self.configuration_layout = QHBoxLayout() clearLayoutAndFixHeight(self.configuration_layout) self.master_layout.addLayout(self.configuration_layout) # Add a stretch at the bottom. self.master_layout.addStretch(1) self.master_widget.setObjectName('LogicalMarkerPluginUI') if context.serial_number() > 1: self.master_widget.setWindowTitle(self.master_widget.windowTitle() + (' (%d)' % context.serial_number())) context.add_widget(self.master_widget) # Activate the functions self.functions = {} self.functions['Locations'] = LocationFunction(locations_file, map, self.master_widget, self.subfunction_layout, self.configuration_layout, self.image) self.functions['Doors'] = DoorFunction(doors_file, map, self.functions['Locations'], self.master_widget, self.subfunction_layout, self.configuration_layout, self.image) self.functions['Objects'] = ObjectFunction(objects_file, map, self.functions['Locations'], self.master_widget, self.subfunction_layout, self.configuration_layout, self.image)
def __init__(self, timeline, parent, topic): super(PlotWidget, self).__init__(parent) self.setObjectName('PlotWidget') self.timeline = timeline msg_type = self.timeline.get_datatype(topic) self.msgtopic = topic self.start_stamp = self.timeline._get_start_stamp() self.end_stamp = self.timeline._get_end_stamp() # the current region-of-interest for our bag file # all resampling and plotting is done with these limits self.limits = [0,(self.end_stamp-self.start_stamp).to_sec()] rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('rqt_bag_plugins'), 'resource', 'plot.ui') loadUi(ui_file, self) self.message_tree = MessageTree(msg_type, self) self.data_tree_layout.addWidget(self.message_tree) # TODO: make this a dropdown with choices for "Auto", "Full" and # "Custom" # I continue to want a "Full" option here self.auto_res.stateChanged.connect(self.autoChanged) self.resolution.editingFinished.connect(self.settingsChanged) self.resolution.setValidator(QDoubleValidator(0.0,1000.0,6,self.resolution)) self.timeline.selected_region_changed.connect(self.region_changed) self.recompute_timestep() self.plot = DataPlot(self) self.plot.set_autoscale(x=False) self.plot.set_autoscale(y=DataPlot.SCALE_VISIBLE) self.plot.autoscroll(False) self.plot.set_xlim(self.limits) self.data_plot_layout.addWidget(self.plot) self._home_button = QPushButton() self._home_button.setToolTip("Reset View") self._home_button.setIcon(QIcon.fromTheme('go-home')) self._home_button.clicked.connect(self.home) self.plot_toolbar_layout.addWidget(self._home_button) self._config_button = QPushButton("Configure Plot") self._config_button.clicked.connect(self.plot.doSettingsDialog) self.plot_toolbar_layout.addWidget(self._config_button) self.set_cursor(0) self.paths_on = set() self._lines = None # get bag from timeline bag = None start_time = self.start_stamp while bag is None: bag,entry = self.timeline.get_entry(start_time, topic) if bag is None: start_time = self.timeline.get_entry_after(start_time)[1].time self.bag = bag # get first message from bag msg = bag._read_message(entry.position) self.message_tree.set_message(msg[1]) # state used by threaded resampling self.resampling_active = False self.resample_thread = None self.resample_fields = set()