def __init__(self, bagFiles, parent=None): super(CompareDataTab, self).__init__() self.parent = parent # attributes self.bagFiles = bagFiles self.plotData = ([], [], 0.0, 0.0) self.plotInfo = { 'label': '', 'y_label': '', } # widgets self.operationSelector = OperationSelectorWidget(self) self.thresholdSetter = ThresholdSetter(self) self.waitMessageBox = QMessageBox(self) self.waitMessageBox.setIcon(QMessageBox.Information) self.waitMessageBox.setWindowTitle('Computation') # layout: layout = QHBoxLayout() layout.addWidget(self.operationSelector) layout.addWidget(self.thresholdSetter) self.setLayout(layout)
def startPressed(self): ''' is called when the start button is clicked calls the function to get the data to plot dependent on what tab is selected ''' currentTab = self.tabWidget.currentIndex() try: if currentTab == 0: # rawDataTab is active plotData, plotInfo = self.rawDataTab.getPlotData() elif currentTab == 1: # plotData, plotInfo = self.compareTab.getPlotData() elif currentTab == 2: plotData, plotInfo = self.diffTab.getPlotData() # emit signal with data self.newPlotData.emit(plotData, plotInfo) # close dialog self.close() except Exception as e: msg_box = QMessageBox(QMessageBox.Critical, 'Error', str(e)) msg_box.exec_()
def update_gait_duration(self, duration): rescale_setpoints = self.scale_setpoints_check_box.isChecked() if self.gait.has_setpoints_after_duration( duration) and not rescale_setpoints: if not self.gait.has_multiple_setpoints_before_duration(duration): QMessageBox.question( self._widget, 'Could not update gait duration', 'Not all joints have multiple setpoints before duration ' + str(duration), QMessageBox.Ok) return discard_setpoints = QMessageBox.question( self._widget, 'Gait duration lower than highest time setpoint', 'Do you want to discard any setpoints higher than the given ' 'duration?', QMessageBox.Yes | QMessageBox.No) if discard_setpoints == QMessageBox.No: self.duration_spin_box.setValue(self.gait.duration) return self.gait.set_duration(duration, rescale_setpoints) self.time_slider.setRange(0, 100 * self.gait.duration) was_playing = self.time_slider_thread is not None self.stop_time_slider_thread() self.create_joint_settings() if was_playing: self.start_time_slider_thread()
def check_files_amount(self): flag = True if len(self.files) <= 0: QMessageBox.about(self, "Load CSV", "One file at least should be chosen") flag = False return flag
def _check_for_master(self): # check if master is available try: rospy.get_master().getSystemState() return except Exception: pass # spawn thread to detect when master becomes available self._wait_for_master_thread = threading.Thread( target=self._wait_for_master) self._wait_for_master_thread.start() self._wait_for_master_dialog = QMessageBox( QMessageBox.Question, self.tr('Waiting for ROS master'), self. tr("Could not find ROS master. Either start a 'roscore' or abort loading the plugin." ), QMessageBox.Abort) self._master_found_signal.connect(self._wait_for_master_dialog.done, Qt.QueuedConnection) button = self._wait_for_master_dialog.exec_() # check if master existence was not detected by background thread no_master = button != QMessageBox.Ok self._wait_for_master_dialog.deleteLater() self._wait_for_master_dialog = None if no_master: raise PluginLoadError( 'RosPyPluginProvider._init_node() could not find ROS master')
def publishState(self): try: rospy.wait_for_service(Supervision.PublishStateService, 0.5) publish_state = rospy.ServiceProxy(Supervision.PublishStateService, EmptySrv) publish_state() except rospy.exceptions.ROSException as e: QMessageBox.warning(self, "Service unreachable.", str(e))
class CompareDataTab(QWidget): def __init__(self, bagFiles, parent=None): super(CompareDataTab, self).__init__() self.parent = parent # attributes self.bagFiles = bagFiles self.plotData = ([], [], 0.0, 0.0) self.plotInfo = { 'label': '', 'y_label': '', } # widgets self.operationSelector = OperationSelectorWidget(self) self.thresholdSetter = ThresholdSetter(self) self.waitMessageBox = QMessageBox(self) self.waitMessageBox.setIcon(QMessageBox.Information) self.waitMessageBox.setWindowTitle('Computation') # layout: layout = QHBoxLayout() layout.addWidget(self.operationSelector) layout.addWidget(self.thresholdSetter) self.setLayout(layout) def getPlotData(self): ''' returns plotData and plotInfo ''' if self.bagFiles[0] == '' or self.bagFiles[1] == '': raise Exception( "Bag file missing. Please import two bag files in the main interface." ) threshold = self.thresholdSetter.getThreshold() # get operation operation = self.operationSelector.getOperation() if operation == '': raise Exception("Please select an operation.") self.plotInfo['label'] = operation + '@t=' + str(threshold) self.plotInfo['y_label'] = 'cases' # start new thread thread = EvaluationThread(self, operation, self.bagFiles, threshold) # thread.finished.connect(self.waitMessageBox.close) thread.start() # self.waitMessageBox.setText('Computing ' + operation + ' values... \nThis could take a few seconds') # # if thread.isRunning(): # self.waitMessageBox.exec_() return self.plotData, self.plotInfo
def on_qt_delete_btn_clicked(self): msgbox = QMessageBox( QMessageBox.Warning, 'Do you want to delete this?', 'Name: {0}\nPath: {1}'.format(self._path_model.cur_bagfilename, self._path_model.cur_bagpath)) msgbox.addButton('DELETE', QMessageBox.AcceptRole) msgbox.addButton('cancel', QMessageBox.RejectRole) if msgbox.exec_() == 0: self._path_model.delete_file()
def question_yn( qmsg='Message', title='Question' ): msgbox = QMessageBox() result = msgbox.question( msgbox, title, qmsg, msgbox.Yes | msgbox.No, msgbox.No ) if result == msgbox.Yes: return True else: return False
def show(self): try: # append folder of 'qt_gui_cpp/lib' to module search path qt_gui_cpp_path = os.path.realpath(get_package_path('qt_gui_cpp')) except Exception: qt_gui_cpp = None else: sys.path.append(os.path.join(qt_gui_cpp_path, 'lib')) sys.path.append(os.path.join(qt_gui_cpp_path, 'src')) from qt_gui_cpp.cpp_binding_helper import qt_gui_cpp logo = os.path.join(self._qtgui_path, 'share', 'qt_gui', 'resource', 'ros_org_vertical.png') text = '<img src="%s" width="56" height="200" style="float: left;"/>' % logo text += '<h3 style="margin-top: 1px;">%s</h3>' % self.tr('rqt') text += '<p>%s %s</p>' % ( self.tr('rqt is a framework for graphical user interfaces.'), self. tr('It is extensible with plugins which can be written in either Python or C++.' )) text += '<p>%s</p>' % (self.tr( 'Please see the <a href="%s">Wiki</a> for more information on rqt and available ' 'plugins.' % 'http://wiki.ros.org/rqt')) text += '<p>%s: ' % self.tr('Utilized libraries:') text += 'Python %s, ' % platform.python_version() if QT_BINDING == 'pyside': text += 'PySide' elif QT_BINDING == 'pyqt': text += 'PyQt' text += ' %s (%s), ' % (QT_BINDING_VERSION, ', '.join( sorted(QT_BINDING_MODULES))) text += 'Qt %s, ' % qVersion() if qt_gui_cpp is not None: if QT_BINDING == 'pyside': text += '%s' % (self.tr('%s C++ bindings available') % 'Shiboken') elif QT_BINDING == 'pyqt': text += '%s' % (self.tr('%s C++ bindings available') % 'SIP') else: text += '%s' % self.tr('C++ bindings available') else: text += '%s' % self.tr( 'no C++ bindings found - no C++ plugins available') text += '.</p>' mb = QMessageBox(QMessageBox.NoIcon, self.tr('About rqt'), text, QMessageBox.Ok, self.parent()) mb.exec_()
class RosPyPluginProvider(CompositePluginProvider): _master_found_signal = Signal(int) def __init__(self): super(RosPyPluginProvider, self).__init__([RospkgPluginProvider('rqt_gui', 'rqt_gui_py::Plugin')]) self.setObjectName('RosPyPluginProvider') self._node_initialized = False self._wait_for_master_dialog = None self._wait_for_master_thread = None def load(self, plugin_id, plugin_context): self._check_for_master() self._init_node() return super(RosPyPluginProvider, self).load(plugin_id, plugin_context) def _check_for_master(self): # check if master is available try: rospy.get_master().getSystemState() return except Exception: pass # spawn thread to detect when master becomes available self._wait_for_master_thread = threading.Thread(target=self._wait_for_master) self._wait_for_master_thread.start() self._wait_for_master_dialog = QMessageBox(QMessageBox.Question, self.tr('Waiting for ROS master'), self.tr("Could not find ROS master. Either start a 'roscore' or abort loading the plugin."), QMessageBox.Abort) self._master_found_signal.connect(self._wait_for_master_dialog.done, Qt.QueuedConnection) button = self._wait_for_master_dialog.exec_() # check if master existence was not detected by background thread no_master = button != QMessageBox.Ok self._wait_for_master_dialog.deleteLater() self._wait_for_master_dialog = None if no_master: raise PluginLoadError('RosPyPluginProvider._init_node() could not find ROS master') def _wait_for_master(self): while True: time.sleep(0.1) if not self._wait_for_master_dialog: break try: rospy.get_master().getSystemState() except Exception: continue self._master_found_signal.emit(QMessageBox.Ok) break def _init_node(self): # initialize node once if not self._node_initialized: name = 'rqt_gui_py_node_%d' % os.getpid() qDebug('RosPyPluginProvider._init_node() initialize ROS node "%s"' % name) rospy.init_node(name, disable_signals=True) self._node_initialized = True
def __init__(self, context, bag_widget, publish_clock): super(AnnotatorWidget, self).__init__() rp = rospkg.RosPack() ui_file = os.path.join(rp.get_path('rqt_bag_meri_annotator'), 'resource', 'MeriPlugin.ui') loadUi(ui_file, self, {'AnnotatorGraphicsView': AnnotatorGraphicsView}) self.setObjectName('AnnotatorWidget') self.setMouseTracking(True) self.annotation_data = list() self.interaction_time = 120.0 self.bag_widget = bag_widget self.bagtimeline = self.bag_widget._timeline self._child_index = 0 self.settings = QSettings("UFES", "MERI Annotator Widget") #self.settings.setValue("Last_child_index",self._child_index) self.instance = vlc.Instance() self.mediaplayer = self.instance.media_player_new() self.isPaused = False self.msgBox = QMessageBox() self.msgBox.setIcon(QMessageBox.Information) self.msgBox.setWindowTitle('Annotator Interface Information') self.msgBox.setStandardButtons(QMessageBox.Ok) self.BtnSaveJson.clicked.connect(self.BtnSaveJsonClicked) self.BtnLoadJson.clicked.connect(self.BtnLoadJsonClicked) self.BtnNext.clicked.connect(self.BtnNextClicked) self.BtnSetupBag.clicked.connect(self.BtnSetupBagClicked) self.BtnPrevious.clicked.connect(self.BtnPreviousClicked) self.BtnZero.clicked.connect(self.BtnZeroClicked) self.BtnOne.clicked.connect(self.BtnOneClicked) self.BtnTwo.clicked.connect(self.BtnTwoClicked) self.BtnAimLess.clicked.connect(self.BtnAimLessClicked) self.BtnGoalOriented.clicked.connect(self.BtnGoalOrientedClicked) self.BtnRobotStarted.clicked.connect(self.BtnRobotStartedClicked) self.BtnPointing.clicked.connect(self.BtnPointingClicked) self.BtnFollowLor.clicked.connect(self.BtnFollowLorClicked) self.BtnAdultSeek.clicked.connect(self.BtnAdultSeekClicked) self.BtnECTwC.clicked.connect(self.BtnECTwCClicked) self.BtnECTwR.clicked.connect(self.BtnECTwRClicked) self.BtnECTwT.clicked.connect(self.BtnECTwTClicked) self.BtnPlay.clicked.connect(self.BtnPlayClicked) self.BtnPause.clicked.connect(self.BtnPauseClicked) self.BtnStop.clicked.connect(self.BtnStopClicked) self.BtnPlay.setIcon(QIcon.fromTheme('media-playback-start')) self.BtnPause.setIcon(QIcon.fromTheme('media-playback-pause')) self.BtnLoadJson.setIcon(QIcon.fromTheme('document-open')) self.BtnSaveJson.setIcon(QIcon.fromTheme('document-save')) self.BtnStop.setIcon(QIcon.fromTheme('media-playback-stop')) self.BtnNext.setIcon(QIcon.fromTheme('go-next')) self.BtnSetupBag.setIcon(QIcon.fromTheme('document-properties')) self.BtnPrevious.setIcon(QIcon.fromTheme('go-previous'))
def _rightclick_menu(self, event): """ :type event: QEvent """ # QTreeview.selectedIndexes() returns 0 when no node is selected. # This can happen when after booting no left-click has been made yet # (ie. looks like right-click doesn't count). These lines are the # workaround for that problem. selected = self._messages_tree.selectedIndexes() if len(selected) == 0: return menu = QMenu() text_action = QAction(self.tr('View Text'), menu) menu.addAction(text_action) raw_action = QAction(self.tr('View Raw'), menu) menu.addAction(raw_action) remove_action = QAction(self.tr('Remove message'), menu) menu.addAction(remove_action) action = menu.exec_(event.globalPos()) if action == raw_action or action == text_action: rospy.logdebug('_rightclick_menu selected={}'.format(selected)) selected_type = selected[1].data() if selected_type[-2:] == '[]': selected_type = selected_type[:-2] browsetext = None try: if (self._mode == rosmsg.MODE_MSG or self._mode == rosaction.MODE_ACTION): browsetext = rosmsg.get_msg_text(selected_type, action == raw_action) elif self._mode == rosmsg.MODE_SRV: browsetext = rosmsg.get_srv_text(selected_type, action == raw_action) else: raise except rosmsg.ROSMsgException as e: QMessageBox.warning( self, self.tr('Warning'), self.tr('The selected item component ' + 'does not have text to view.')) if browsetext is not None: self._browsers.append( TextBrowseDialog(browsetext, self._rospack)) self._browsers[-1].show() if action == remove_action: self._messages_tree.model().removeRow(selected[0].row())
def check_choose(self): flag = True temp = [] for item in self.group_selected_items.values(): if item: for i in item: temp.append(i) if len(temp) == 0: QMessageBox.about(self, "Features", "One feature at least should be chosen") flag = False return flag
def check_int(self, number, condition, title, message_body): try: # print type(number) val = int(number) if val <= condition: QMessageBox.about(self, title, "The number should > %s" % condition) return False except ValueError: QMessageBox.about(self, title, message_body) return False return True
def _rightclick_menu(self, event): """ :type event: QEvent """ # QTreeview.selectedIndexes() returns 0 when no node is selected. # This can happen when after booting no left-click has been made yet # (ie. looks like right-click doesn't count). These lines are the # workaround for that problem. selected = self._messages_tree.selectedIndexes() if len(selected) == 0: return menu = QMenu() text_action = QAction(self.tr('View Text'), menu) menu.addAction(text_action) raw_action = QAction(self.tr('View Raw'), menu) menu.addAction(raw_action) remove_action = QAction(self.tr('Remove message'), menu) menu.addAction(remove_action) action = menu.exec_(event.globalPos()) if action == raw_action or action == text_action: rospy.logdebug('_rightclick_menu selected={}'.format(selected)) selected_type = selected[1].data() if selected_type[-2:] == '[]': selected_type = selected_type[:-2] browsetext = None try: if (self._mode == rosmsg.MODE_MSG or self._mode == rosaction.MODE_ACTION): browsetext = rosmsg.get_msg_text(selected_type, action == raw_action) elif self._mode == rosmsg.MODE_SRV: browsetext = rosmsg.get_srv_text(selected_type, action == raw_action) else: raise except rosmsg.ROSMsgException as e: QMessageBox.warning(self, self.tr('Warning'), self.tr('The selected item component ' + 'does not have text to view.')) if browsetext is not None: self._browsers.append(TextBrowseDialog(browsetext, self._rospack)) self._browsers[-1].show() if action == remove_action: self._messages_tree.model().removeRow(selected[0].row())
def createTimeSeriesFeatures(self, files, saved_dir, window, group_selected_items, step): import TimeSeriesFeatures as TS # saved_dir = saved_dir[0].encode('utf-8') for input_path in files: output_path = generate_csv_from_bag(saved_dir, input_path) print "++++++++++++++++++++++++++ ", output_path print "in = %s out = %s " % (input_path, output_path) print "step = %s" % step ts = TS.TimeSeries(input_path, output_path, window, group_selected_items, step) ts.generate_time_series_features() QMessageBox.about(self, "csv save", "csv was saved successfuly")
def dialog_window(self, message, detail, check): self.message = QMessageBox() self.has_message_opened = 1 self.message.setIcon(QMessageBox.Warning) self.message.setText(message) self.message.setInformativeText(detail) self.message.setWindowTitle("Items are unchecked") self.message.setStandardButtons(QMessageBox.Yes | QMessageBox.No) self.message.show() if check == True: # Check == True means it is from ok_clicked self.message.buttonClicked.connect(self.message_action) else: self.message.buttonClicked.connect(self.message_action_uncheck)
def check_validation(self): flag = self.check_files_amount() flag = flag & self.check_choose() flag = flag & self.check_int(self.window.text(), 2, "Error in Window Time", "That's not a number!") flag = flag & self.check_int(self.step.text(), 0, "Error in Step", "That's not a integer!") # TODO selected topic not empty if self.saved_dir == []: QMessageBox.about(self, "Save CSV", "Select path for saving") flag = False return flag
def _choose_new_perspective_name(self, show_cloning=True): # input dialog for new perspective name if self._create_perspective_dialog is None: ui_file = os.path.join(self._qtgui_path, 'resource', 'perspective_create.ui') self._create_perspective_dialog = loadUi(ui_file) # custom validator preventing forward slashs class CustomValidator(QValidator): def __init__(self, parent=None): super(CustomValidator, self).__init__(parent) def fixup(self, value): value = value.replace('/', '') def validate(self, value, pos): if value.find('/') != -1: pos = value.find('/') return (QValidator.Invalid, value, pos) if value == '': return (QValidator.Intermediate, value, pos) return (QValidator.Acceptable, value, pos) self._create_perspective_dialog.perspective_name_edit.setValidator( CustomValidator()) # set default values self._create_perspective_dialog.perspective_name_edit.setText('') self._create_perspective_dialog.clone_checkbox.setChecked(True) self._create_perspective_dialog.clone_checkbox.setVisible(show_cloning) # show dialog and wait for it's return value return_value = self._create_perspective_dialog.exec_() if return_value == self._create_perspective_dialog.Rejected: return name = str(self._create_perspective_dialog.perspective_name_edit.text( )).lstrip(self.HIDDEN_PREFIX) if name == '': QMessageBox.warning( self._menu_manager.menu, self.tr('Empty perspective name'), self.tr('The name of the perspective must be non-empty.')) return if name in self.perspectives: QMessageBox.warning( self._menu_manager.menu, self.tr('Duplicate perspective name'), self.tr('A perspective with the same name already exists.')) return return name
def press_load_yaml(self): ret = QMessageBox.question( self._widget, "Load YAML", 'Do you want to load a new YAML and discard current changes?', QMessageBox.Ok, QMessageBox.Cancel) if ret == QMessageBox.Ok: self.load_yaml()
def open(self): ''' Deletes all current frames and instead loads an animation from a json file ''' if len(self._widget.frameList) > 1: message = "This will discard your current Animation. Continue?" sure = QMessageBox.question(self._widget, 'Sure?', message, QMessageBox.Yes | QMessageBox.No) if sure == QMessageBox.No: return my_file = QFileDialog.getOpenFileName()[0] if my_file: status = self._recorder.load_animation(my_file) if status == "": status = "Load successful." self._widget.statusBar.showMessage(status) animstate = self._recorder.get_animation_state() for i in animstate: try: self._checkBoxesPower[i['name']] = i['torque'] except KeyError: self._checkBoxesPower[i['name']] = {} for key in self.ids: self._checkBoxesPower[i['name']][key] = 2 self.update_frames() metadata = self._recorder.get_meta_data() self._widget.lineAnimationName.setText(metadata[0]) self._widget.lineAuthor.setText(metadata[2]) self._widget.lineVersion.setText(str(metadata[1])) self._widget.fieldDescription.setPlainText(metadata[3])
def help(self): ''' Prints out the help dialogue ''' helpDialog = QMessageBox.about( self._widget, "About RecordUI", "This is RecordUI, a tool to record robot animations.\n \n Keyboard shortcuts: \n \n \ New: Ctrl + N \n \ Open: Ctrl + O \n \ Save: Ctrl + S \n \ Save as: Ctrl + Shift + S \n \n \ Play Init: Ctrl + I \n \ Play Frame: Ctrl + P \n \ Play Next: Alt + P \n \ Play Animation: Ctrl + Shift + P \n \ Play Until: Ctrl + Alt + P \n \n \ Record Frame: Space \n \ Duplicate Frame: '+' \n \ Delete Frame: '-' \n \ Undo: Ctrl + Z \n \ Redo: Ctrl + Y \n \ Help: Ctrl + H \n \n \ Mirror to Left: Ctrl + Left Arrow \n \ Mirror to Right: Ctrl + Right Arrow \n \ Invert: Ctrl + Down Arrow")
def initUI(self): global count self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) buttonReply = QMessageBox.information( self, 'Object Detection', "%s Detection \n do you want to record continue?" % catch, QMessageBox.Yes | QMessageBox.Save | QMessageBox.Cancel | QMessageBox.Reset | QMessageBox.No, QMessageBox.No) if buttonReply == QMessageBox.Yes: print('Yes clicked.') elif buttonReply == QMessageBox.Save: print('Save clicked.') elif buttonReply == QMessageBox.Cancel: print('Cancel clicked.') elif buttonReply == QMessageBox.Close: print('Close clicked.') elif buttonReply == QMessageBox.Reset: print('Reply clicked.') else: os.system("rosnode list | grep record* | xargs rosnode kill") print('No clicked.') count = 0 print(count)
def export_to_file(gait, gait_directory): if gait_directory is None or gait_directory == '': return # Name and version will be empty as it's stored in the filename. subgait_msg = gait.to_subgait_msg() output_file_directory = os.path.join( gait_directory, gait.gait_name.replace(' ', '_'), gait.subgait_name.replace(' ', '_')) output_file_path = os.path.join( output_file_directory, gait.version.replace(' ', '_') + '.subgait') file_exists = os.path.isfile(output_file_path) if file_exists: overwrite_file = QMessageBox.question( None, 'File already exists', 'Do you want to overwrite ' + str(output_file_path) + '?', QMessageBox.Yes | QMessageBox.No) if overwrite_file == QMessageBox.No: return rospy.loginfo('Writing gait to ' + output_file_path) if not os.path.isdir(output_file_directory): os.makedirs(output_file_directory) with open(output_file_path, 'w') as output_file: output_file.write(str(subgait_msg)) user_interface_controller.notify('Gait Saved', output_file_path)
def press_save_yaml(self): ret = QMessageBox.question( self._widget, "Save YAML", 'Do you want to save changes to current YAML file, overwitting its content?', QMessageBox.Ok, QMessageBox.Cancel) if ret == QMessageBox.Ok: self.save_yaml()
def mergeTracks(self, unused=None): (track1Id, ok) = QInputDialog.getInteger(self.widget, "Merge two tracks", "Please enter the ID of the 1st person track you want to merge.") if not ok: return (track2Id, ok) = QInputDialog.getInteger(self.widget, "Merge two tracks", "Please enter the ID of the 2nd person track you want to merge.") if not ok: return if track1Id == track2Id: QMessageBox.critical(self.widget, "Merge two tracks", "Track IDs cannot be identical!") return if self.verifyTrackExists(track1Id) and self.verifyTrackExists(track2Id): self.editor.mergeTracks(track1Id, track2Id) self.updateTrackCount() QMessageBox.information(self.widget, "Merge two tracks", "Person tracks %d and %d have been merged!" % (track1Id, track2Id))
def _export_region(self, path, topics, start_stamp, end_stamp): """ Starts a thread to save the current selection to a new bag file :param path: filesystem path to write to, ''str'' :param topics: topics to write to the file, ''list(str)'' :param start_stamp: start of area to save, ''rospy.Time'' :param end_stamp: end of area to save, ''rospy.Time'' """ if not self.start_background_task('Copying messages to "%s"' % path): return # TODO implement a status bar area with information on the current save status bag_entries = list( self.get_entries_with_bags(topics, start_stamp, end_stamp)) if self.background_task_cancel: return # Get the total number of messages to copy total_messages = len(bag_entries) # If no messages, prompt the user and return if total_messages == 0: QMessageBox(QMessageBox.Warning, 'rqt_bag', 'No messages found', QMessageBox.Ok).exec_() self.stop_background_task() return # Open the path for writing try: export_bag = rosbag.Bag(path, 'w') except Exception: QMessageBox(QMessageBox.Warning, 'rqt_bag', 'Error opening bag file [%s] for writing' % path, QMessageBox.Ok).exec_() self.stop_background_task() return # Run copying in a background thread self._export_thread = threading.Thread(target=self._run_export_region, args=(export_bag, topics, start_stamp, end_stamp, bag_entries)) self._export_thread.start()
def new(self): ''' Deletes all currently recorded frames ''' if len(self._widget.frameList) > 1: message = "This will discard your current Animation. Continue?" sure = QMessageBox.question(self._widget, 'Sure?', message, QMessageBox.Yes | QMessageBox.No) if sure == QMessageBox.Yes: self._recorder.clear() self.update_frames()
def _handle_generate(self, button): ''' generate a new trial config ''' trial_config = self.current_benchmark.generate() names = [] for key in self.trial_configs.keys(): names.append(key) msg = 'Select a name for this trial configuration' text = '' while True: text, ok = QInputDialog.getText(self, 'Trial name', msg) if text not in names: break QMessageBox.critical(self, "Error", "Name exists already") if ok: trial_item = QListWidgetItem(text) trial_item.setFlags(trial_item.flags() | Qt.ItemIsEditable) self.trial_list_widget.addItem(trial_item) self.trial_configs[text] = trial_config self.trial_list_widget.setCurrentItem(trial_item)
def question_yn(qmsg='Message', title='Question'): ''' Asking Yes or No using PyQt QMessgageBox() Return 'True' only in the case that 'Yes' is chosen. @type qmsg : str @param qmsg : Question message for Yes/No answer (Default='Message') @type title : str @param title : Title of the message box window (Default='Question') @rtype : bool @return : Return when 'Yes' is chosen. ''' msgbox = QMessageBox() result = msgbox.question(msgbox, title, qmsg, msgbox.Yes | msgbox.No, msgbox.No) if result == msgbox.Yes: return True else: return False
def _handle_custom_keypress(self, event, old_keyPressEvent=QTableView.keyPressEvent): """ Handles the delete key. The delete key removes the tableview's selected rows from the datamodel """ if event.key() == Qt.Key_Delete and len(self._model._messages) > 0: delete = QMessageBox.Yes if len(self.table_view.selectionModel().selectedIndexes()) == 0: delete = QMessageBox.question(self, self.tr('Message'), self.tr("Are you sure you want to delete all messages?"), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if delete == QMessageBox.Yes and event.key() == Qt.Key_Delete and event.modifiers() == Qt.NoModifier: if self._delete_selected_rows(): event.accept() return old_keyPressEvent(self.table_view, event)
def start_background_task(self, background_task): """ Verify that a background task is not currently running before starting a new one :param background_task: name of the background task, ''str'' """ if self.background_task is not None: QMessageBox( QMessageBox.Warning, 'Exclamation', 'Background operation already running:\n\n%s' % self.background_task, QMessageBox.Ok).exec_() return False self.background_task = background_task self.background_task_cancel = False return True
def _check_for_master(self): # check if master is available try: rospy.get_master().getSystemState() return except Exception: pass # spawn thread to detect when master becomes available self._wait_for_master_thread = threading.Thread(target=self._wait_for_master) self._wait_for_master_thread.start() self._wait_for_master_dialog = QMessageBox(QMessageBox.Question, self.tr('Waiting for ROS master'), self.tr("Could not find ROS master. Either start a 'roscore' or abort loading the plugin."), QMessageBox.Abort) self._master_found_signal.connect(self._wait_for_master_dialog.done, Qt.QueuedConnection) button = self._wait_for_master_dialog.exec_() # check if master existence was not detected by background thread no_master = button != QMessageBox.Ok self._wait_for_master_dialog.deleteLater() self._wait_for_master_dialog = None if no_master: raise PluginLoadError('RosPyPluginProvider._init_node() could not find ROS master')
def dasherr(msg, obj, title='Error'): """ Logs a message with ``rospy.logerr`` and displays a ``QMessageBox`` to the user :param msg: Message to display. :type msg: str :param obj: Parent object for the ``QMessageBox`` :type obj: QObject :param title: An optional title for the `QMessageBox`` :type title: str """ rospy.logerr(msg) box = QMessageBox() box.setText(msg) box.setWindowTitle(title) box.show() obj._message_box = box