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 keyPressEvent(self, event): if self._reader is not None: if event.key() == Qt.Key_PageUp and self.verticalScrollBar().value() == 0: self._reader.reverse_read(self.verticalScrollBar().pageStep() / 10) elif event.key() == Qt.Key_Home and event.modifiers() == Qt.ShiftModifier: self._reader.reverse_read(-1) QTextEdit.keyPressEvent(self, event)
def _set_parameter_layout(self): params = self.admin_app_interface.get_srv_parameters( self.current_service['parameters_detail']) is_enabled = self.current_service['enabled'] if self.params_layout_items: for item in self.params_layout_items: self.params_layout.removeWidget(item[0]) self.params_layout.removeWidget(item[1]) item[0].setParent(None) item[1].setParent(None) self.params_layout_items = [] if params: self.params_layout.setColumnStretch(1, 0) self.params_layout.setRowStretch(2, 0) for param in params.keys(): label = QLabel(param) self.params_layout.addWidget(label) value = QTextEdit(str(params[param])) value.setMaximumHeight(30) self.params_layout.addWidget(value) self.params_layout_items.append((label, value)) self._set_enable_params_layout(not is_enabled)
def keyPressEvent(self, event): ''' Enable the mouse tracking by X{setMouseTracking()} if the control key is pressed. ''' if event.key() == Qt.Key_Control or event.key() == Qt.Key_Shift: self.setMouseTracking(True) if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_7: self.commentText() elif event.modifiers( ) == Qt.ControlModifier | Qt.ShiftModifier and event.key( ) == Qt.Key_Slash: self.commentText() elif event.modifiers() == Qt.AltModifier and event.key( ) == Qt.Key_Space: ext = os.path.splitext(self.filename) if ext[1] in self.CONTEXT_FILE_EXT: menu = self._create_context_substitution_menu(False) if menu is None: menu = self._create_context_menu_for_tag() if menu: menu.exec_( self.mapToGlobal(self.cursorRect().bottomRight())) elif event.key() != Qt.Key_Escape: # handle the shifting of the block if event.modifiers() == Qt.NoModifier and event.key( ) == Qt.Key_Tab: self.shiftText() elif event.modifiers() == Qt.ControlModifier and event.key( ) == Qt.Key_Tab: self.shiftText(back=True) else: QTextEdit.keyPressEvent(self, event) else: event.accept() QTextEdit.keyPressEvent(self, event)
def keyPressEvent(self, event): ''' Enable the mouse tracking by X{setMouseTracking()} if the control key is pressed. ''' if event.key() == Qt.Key_Control or event.key() == Qt.Key_Shift: self.setMouseTracking(True) if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_7: self.commentText() elif event.modifiers() == Qt.ControlModifier | Qt.ShiftModifier and event.key() == Qt.Key_Slash: self.commentText() elif event.modifiers() == Qt.AltModifier and event.key() == Qt.Key_Space: ext = os.path.splitext(self.filename) if ext[1] in self.CONTEXT_FILE_EXT: menu = self._create_context_substitution_menu(False) if menu is None: menu = self._create_context_menu_for_tag() if menu: menu.exec_(self.mapToGlobal(self.cursorRect().bottomRight())) elif event.key() != Qt.Key_Escape: # handle the shifting of the block if event.modifiers() == Qt.NoModifier and event.key() == Qt.Key_Tab: self.shiftText() elif event.modifiers() == Qt.ShiftModifier and event.key() == Qt.Key_Backtab: self.shiftText(back=True) else: event.accept() if event.key() in [Qt.Key_Enter, Qt.Key_Return]: ident = self.getIdentOfCurretLine() QTextEdit.keyPressEvent(self, event) if event.key() in [Qt.Key_Enter, Qt.Key_Return]: self.indentCurrentLine(ident) else: event.accept() QTextEdit.keyPressEvent(self, event)
def focusInEvent(self, event): # check for file changes try: if self.filename and self.file_info: if self.file_info.lastModified() != QFileInfo( self.filename).lastModified(): self.file_info = QFileInfo(self.filename) result = MessageBox.question(self, "File changed", "File was changed, reload?", buttons=MessageBox.Yes | MessageBox.No) if result == MessageBox.Yes: f = QFile(self.filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.setText(unicode(f.readAll(), "utf-8")) self.document().setModified(False) self.textChanged.emit() else: MessageBox.critical( self, "Error", "Cannot open launch file%s" % self.filename) except: pass QTextEdit.focusInEvent(self, event)
def __init__(self, filename, parent=None): self.parent = parent QTextEdit.__init__(self, parent) self.setObjectName('Editor - %s' % filename) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_custom_context_menu) # self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.setAcceptRichText(False) font = QFont() font.setFamily("Fixed".decode("utf-8")) font.setPointSize(12) self.setFont(font) self.setLineWrapMode(QTextEdit.NoWrap) self.setTabStopWidth(25) self.setAcceptRichText(False) self.setCursorWidth(2) self.setFontFamily("courier new") self.setProperty("backgroundVisible", True) bg_style = "QTextEdit { background-color: #fffffc;}" self.setStyleSheet("%s" % (bg_style)) self.setTextColor(QColor(0, 0, 0)) self.regexp_list = [QRegExp("\\binclude\\b"), QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b"), QRegExp("\\bdefault=.*\$\(find\\b")] self.filename = filename self.file_mtime = 0 # f = QFile(filename) # if f.open(QIODevice.ReadOnly | QIODevice.Text): # self.file_info = QFileInfo(filename) # self.setText(unicode(f.readAll(), "utf-8")) self.path = '.' # enables drop events self.setAcceptDrops(True) # variables for threaded search self._search_thread = None self._stop = False self._internal_args = {} ext = os.path.splitext(filename) if self.filename: self.setText("") _, self.file_mtime, file_content = nm.nmd().file.get_file_content(filename) if ext[1] in ['.launch', '.xml']: self._internal_args = get_internal_args(file_content) self.setText(file_content) self._is_launchfile = False if ext[1] in ['.launch', '.xml', '.xacro', '.srdf', '.urdf']: if ext[1] in ['.launch']: self._is_launchfile = True self.hl = XmlHighlighter(self.document(), is_launch=False) self.cursorPositionChanged.connect(self._document_position_changed) else: self.hl = YamlHighlighter(self.document())
def keyReleaseEvent(self, event): ''' Disable the mouse tracking by X{setMouseTracking()} if the control key is released and set the cursor back to X{Qt.IBeamCursor}. ''' if event.key() == Qt.Key_Control or event.key() == Qt.Key_Shift: self.setMouseTracking(False) self.viewport().setCursor(Qt.IBeamCursor) else: QTextEdit.keyReleaseEvent(self, event)
def keyReleaseEvent(self, event): ''' Disable the mouse tracking by X{setMouseTracking()} if the control key is released and set the cursor back to X{Qt.IBeamCursor}. ''' if event.key() == Qt.Key_Control or event.key() == Qt.Key_Shift: self.setMouseTracking(False) self.viewport().setCursor(Qt.IBeamCursor) else: event.accept() QTextEdit.keyReleaseEvent(self, event)
def __init__(self, parent=None): QTextEdit.__init__(self, parent) self._reader = None self.setAutoFillBackground(False) self.setReadOnly(True) self.setUndoRedoEnabled(False) self.setAutoFormatting(QTextEdit.AutoNone) self.setAcceptRichText(False) # self.textBrowser.document().setMaximumBlockCount(100) p = QPalette() p.setColor(QPalette.Base, Qt.black) p.setColor(QPalette.Text, Qt.white) self.setPalette(p)
def keyPressEvent(self, event): ''' Enable the mouse tracking by X{setMouseTracking()} if the control key is pressed. ''' if self.isReadOnly(): if event.key() == Qt.Key_F5: nm.nmd().file.get_file_content_threaded(self.filename) else: event.accept() return if event.key() == Qt.Key_Control or event.key() == Qt.Key_Shift: self.setMouseTracking(True) if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_7: self.commentText() elif event.modifiers( ) == Qt.ControlModifier | Qt.ShiftModifier and event.key( ) == Qt.Key_Slash: self.commentText() elif event.modifiers( ) == Qt.ControlModifier | Qt.ShiftModifier and event.key() == Qt.Key_F: if isinstance(self.hl, XmlHighlighter): self.toprettyxml() else: self.toprettyyaml() elif event.modifiers() == Qt.AltModifier and event.key( ) == Qt.Key_Space: ext = os.path.splitext(self.filename) if ext[1] in self.CONTEXT_FILE_EXT: menu = self._create_context_substitution_menu(False) if menu is None: menu = self._create_context_menu_for_tag() if menu: menu.exec_( self.mapToGlobal(self.cursorRect().bottomRight())) elif event.key() != Qt.Key_Escape: # handle the shifting of the block if event.modifiers() == Qt.NoModifier and event.key( ) == Qt.Key_Tab: self.shiftText() elif event.modifiers() == Qt.ShiftModifier and event.key( ) == Qt.Key_Backtab: self.shiftText(back=True) else: event.accept() if event.key() in [Qt.Key_Enter, Qt.Key_Return]: ident = self.getIdentOfCurretLine() QTextEdit.keyPressEvent(self, event) if event.key() in [Qt.Key_Enter, Qt.Key_Return]: self.indentCurrentLine(ident - self.getIdentOfCurretLine()) else: QTextEdit.keyPressEvent(self, event)
def __init__(self, filename, parent=None): self.parent = parent QTextEdit.__init__(self, parent) self.setObjectName('Editor - %s' % filename) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_custom_context_menu) # self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.setAcceptRichText(False) font = QFont() font.setFamily('Fixed') font.setPointSize(12) self.setFont(font) self.setLineWrapMode(QTextEdit.NoWrap) self.setTabStopWidth(25) self.setAcceptRichText(False) self.setCursorWidth(2) self.setFontFamily("courier new") self.setProperty("backgroundVisible", True) bg_style = "QTextEdit { background-color: #fffffc;}" self.setStyleSheet("%s" % (bg_style)) self.setTextColor(QColor(0, 0, 0)) self.regexp_list = [ QRegExp("\\binclude\\b"), QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b"), QRegExp("\\bdefault=.*\$\(find\\b") ] self.filename = filename self.file_mtime = 0 # f = QFile(filename) # if f.open(QIODevice.ReadOnly | QIODevice.Text): # self.file_info = QFileInfo(filename) # self.setText(unicode(f.readAll(), "utf-8")) self.path = '.' # variables for threaded search self._search_thread = None self._stop = False self._internal_args = {} self._ext = os.path.splitext(filename)[1] self.setText("Loading file content ... press F5 to reload!") self.setReadOnly(True) self._to_select = [] nm.nmd().file.file_content.connect(self._apply_file_content) nm.nmd().file.error.connect(self._on_nmd_error) if self.filename: nm.nmd().file.get_file_content_threaded(filename)
def mouseMoveEvent(self, event): ''' Sets the X{Qt.PointingHandCursor} if the control key is pressed and the mouse is over the included file. ''' if event.modifiers() == Qt.ControlModifier or event.modifiers() == Qt.ShiftModifier: cursor = self.cursorForPosition(event.pos()) index = self.index(cursor.block().text()) if index > -1: self.viewport().setCursor(Qt.PointingHandCursor) else: self.viewport().setCursor(Qt.IBeamCursor) else: self.viewport().setCursor(Qt.IBeamCursor) QTextEdit.mouseMoveEvent(self, event)
def show_custom_context_menu(self, pos): if self.isReadOnly(): return menu = QTextEdit.createStandardContextMenu(self) formattext_action = None if isinstance(self.hl, XmlHighlighter): formattext_action = QAction("Format XML", self, statusTip="", triggered=self.toprettyxml) else: formattext_action = QAction("Format as YAML", self, statusTip="", triggered=self.toprettyyaml) formattext_action.setShortcuts(QKeySequence("Ctrl+Shift+F")) menu.addAction(formattext_action) # if not self.textCursor().selectedText(): # self.setTextCursor(self.cursorForPosition(pos)) submenu = self._create_context_menu_for_tag() if submenu is not None: menu.addMenu(submenu) argmenu = self._create_context_substitution_menu() if argmenu is not None: menu.addMenu(argmenu) menu.exec_(self.mapToGlobal(pos))
def __init__(self, status): super(InspectorWidget, self).__init__() self.status = status self.setWindowTitle(status.name) self.paused = False layout = QVBoxLayout() self.disp = QTextEdit() self.snapshot = QPushButton("Snapshot") self.time = TimelineWidget(self) layout.addWidget(self.disp, 1) layout.addWidget(self.time, 0) layout.addWidget(self.snapshot) self.snaps = [] self.snapshot.clicked.connect(self.take_snapshot) self.write.connect(self.write_kv) self.newline.connect(lambda: self.disp.insertPlainText('\n')) self.clear.connect(lambda: self.disp.clear()) self.setLayout(layout) self.setGeometry(0,0,300,400) self.show() self.update(status)
def __init__(self, filename, parent=None): self.parent = parent QTextEdit.__init__(self, parent) self.setObjectName(' - '.join(['Editor', filename])) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_custom_context_menu) # self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.setAcceptRichText(False) font = QFont() font.setFamily("Fixed".decode("utf-8")) font.setPointSize(12) self.setFont(font) self.setLineWrapMode(QTextEdit.NoWrap) self.setTabStopWidth(25) self.setAcceptRichText(False) self.setCursorWidth(2) self.setFontFamily("courier new") self.setProperty("backgroundVisible", True) self.regexp_list = [ QRegExp("\\binclude\\b"), QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b"), QRegExp("\\bdefault=.*\$\(find\\b") ] self.filename = filename self.file_info = None if self.filename: f = QFile(filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.file_info = QFileInfo(filename) self.setText(unicode(f.readAll(), "utf-8")) self.path = '.' # enables drop events self.setAcceptDrops(True) if filename.endswith('.launch'): self.hl = XmlHighlighter(self.document()) self.cursorPositionChanged.connect(self._document_position_changed) else: self.hl = YamlHighlighter(self.document()) # variables for threaded search self._search_thread = None self._stop = False
def create_label_textedit_pair(key, value): ''' Probabaly there should be better way to lay out param and remappings ''' name = QLabel(key) name.setToolTip(key) name.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) name.setMinimumWidth(400) name.setMaximumHeight(30) name.setWordWrap(True) textedit = QTextEdit() textedit.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) textedit.setMinimumWidth(320) textedit.setMaximumHeight(30) textedit.append(str(value)) return name, textedit
def focusInEvent(self, event): # check for file changes try: if self.filename and self.file_info: if self.file_info.lastModified() != QFileInfo(self.filename).lastModified(): self.file_info = QFileInfo(self.filename) result = MessageBox.question(self, "File changed", "File was changed, reload?", buttons=MessageBox.Yes | MessageBox.No) if result == MessageBox.Yes: f = QFile(self.filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.setText(unicode(f.readAll(), "utf-8")) self.document().setModified(False) self.textChanged.emit() else: MessageBox.critical(self, "Error", "Cannot open launch file%s" % self.filename) except: pass QTextEdit.focusInEvent(self, event)
def __init__(self, status, close_callback): """ :type status: DiagnosticStatus :param close_callback: When the instance of this class (InspectorWindow) terminates, this callback gets called. """ #TODO(Isaac) UI construction that currently is done in this method, # needs to be done in .ui file. super(InspectorWindow, self).__init__() self.status = status self._close_callback = close_callback self.setWindowTitle(status.name) self.paused = False self.layout_vertical = QVBoxLayout(self) self.disp = QTextEdit(self) self.snapshot = QPushButton("StatusSnapshot") self.timeline_pane = TimelinePane(self) self.timeline_pane.set_timeline_data(Util.SECONDS_TIMELINE, self.get_color_for_value, self.on_pause) self.layout_vertical.addWidget(self.disp, 1) self.layout_vertical.addWidget(self.timeline_pane, 0) self.layout_vertical.addWidget(self.snapshot) self.snaps = [] self.snapshot.clicked.connect(self._take_snapshot) self._sig_write.connect(self._write_key_val) self._sig_newline.connect(lambda: self.disp.insertPlainText('\n')) self._sig_clear.connect(lambda: self.disp.clear()) self._sig_close_window.connect(self._close_callback) self.setLayout(self.layout_vertical) # TODO better to be configurable where to appear. self.setGeometry(0, 0, 400, 600) self.show() self.update_status_display(status)
def __init__(self, filename, parent=None): self.parent = parent QTextEdit.__init__(self, parent) self.setObjectName(' - '.join(['Editor', filename])) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_custom_context_menu) # self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.setAcceptRichText(False) font = QFont() font.setFamily("Fixed".decode("utf-8")) font.setPointSize(12) self.setFont(font) self.setLineWrapMode(QTextEdit.NoWrap) self.setTabStopWidth(25) self.setAcceptRichText(False) self.setCursorWidth(2) self.setFontFamily("courier new") self.setProperty("backgroundVisible", True) self.regexp_list = [QRegExp("\\binclude\\b"), QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b"), QRegExp("\\bdefault=.*\$\(find\\b")] self.filename = filename self.file_info = None if self.filename: f = QFile(filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.file_info = QFileInfo(filename) self.setText(unicode(f.readAll(), "utf-8")) self.path = '.' # enables drop events self.setAcceptDrops(True) if filename.endswith('.launch'): self.hl = XmlHighlighter(self.document()) self.cursorPositionChanged.connect(self._document_position_changed) else: self.hl = YamlHighlighter(self.document()) # variables for threaded search self._search_thread = None self._stop = False
def show_custom_context_menu(self, pos): menu = QTextEdit.createStandardContextMenu(self) # if not self.textCursor().selectedText(): # self.setTextCursor(self.cursorForPosition(pos)) submenu = self._create_context_menu_for_tag() if submenu is not None: menu.addMenu(submenu) argmenu = self._create_context_substitution_menu() if argmenu is not None: menu.addMenu(argmenu) menu.exec_(self.mapToGlobal(pos))
def event(self, event): if event.type() == QEvent.ToolTip: cursor = self.cursorForPosition(event.pos()) cursor.select(QTextCursor.BlockUnderCursor) if cursor.selectedText(): for dp, np in XmlHighlighter.DEPRECATED_PARAMETER.items(): if 'name="%s"' % dp in cursor.selectedText(): QToolTip.showText(event.globalPos(), ' %s is deprecated, use %s' % (dp, np)) else: QToolTip.hideText() return True return QTextEdit.event(self, event)
def _update_item(self): widget_layout = self.arg_ver_layout item_list = self.params_list widget_list = widget_layout.parentWidget().children() while len(widget_list) > 2: added_arg_widget = widget_list.pop() widget_layout.removeWidget(added_arg_widget) added_arg_widget.setParent(None) added_arg_widget.deleteLater() #resize dialog_widget = widget_layout.parentWidget().parentWidget() dialog_widget.resize(dialog_widget.minimumSize()) for l in item_list: params_hor_sub_widget = QWidget() params_hor_layout = QHBoxLayout(params_hor_sub_widget) for k in l: param_name = k[0] param_type = k[2] name_widget = QLabel(param_name + ": ") if param_type == 'string' or param_type == 'int': k[1] = QTextEdit() k[1].setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) k[1].setMinimumSize(0, 30) k[1].append("") elif param_type == 'bool': k[1] = QTextEdit() k[1] = QComboBox() k[1].setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) k[1].setMinimumSize(0, 30) k[1].addItem("True", True) k[1].addItem("False", False) params_hor_layout.addWidget(name_widget) params_hor_layout.addWidget(k[1]) widget_layout.addWidget(params_hor_sub_widget)
def create_label_textedit_pair(key, value): param_layout = QHBoxLayout() name_widget = QLabel(key) textedit_widget = QTextEdit() textedit_widget.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) textedit_widget.setMinimumSize(0, 30) textedit_widget.append(str(value)) param_layout.addWidget(name_widget) param_layout.addWidget(textedit_widget) return param_layout
def _create_add_rocon_master_dialog(self): # dialog connect_dlg = QDialog(self._widget_main) connect_dlg.setWindowTitle("Add Ros Master") connect_dlg.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) connect_dlg.setMinimumSize(350, 0) # dlg_rect = self._connect_dlg.geometry() # dialog layout ver_layout = QVBoxLayout(connect_dlg) ver_layout.setContentsMargins(9, 9, 9, 9) # param layout text_grid_sub_widget = QWidget() text_grid_layout = QGridLayout(text_grid_sub_widget) text_grid_layout.setColumnStretch(1, 0) text_grid_layout.setRowStretch(2, 0) # param 1 title_widget1 = QLabel("MASTER_URI: ") context_widget1 = QTextEdit() context_widget1.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) context_widget1.setMinimumSize(0, 30) context_widget1.append(self.master_uri) # param 2 title_widget2 = QLabel("HOST_NAME: ") context_widget2 = QTextEdit() context_widget2.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) context_widget2.setMinimumSize(0, 30) context_widget2.append(self.host_name) # add param text_grid_layout.addWidget(title_widget1) text_grid_layout.addWidget(context_widget1) text_grid_layout.addWidget(title_widget2) text_grid_layout.addWidget(context_widget2) # add param layout ver_layout.addWidget(text_grid_sub_widget) # button layout button_hor_sub_widget = QWidget() button_hor_layout = QHBoxLayout(button_hor_sub_widget) uri_text_widget = context_widget1 host_name_text_widget = context_widget2 # button btn_call = QPushButton("Add") btn_cancel = QPushButton("Cancel") btn_call.clicked.connect(lambda: connect_dlg.done(0)) btn_call.clicked.connect(lambda: self._add_rocon_master( uri_text_widget, host_name_text_widget)) btn_cancel.clicked.connect(lambda: connect_dlg.done(0)) # add button button_hor_layout.addWidget(btn_call) button_hor_layout.addWidget(btn_cancel) # add button layout ver_layout.addWidget(button_hor_sub_widget) return connect_dlg
def __init__(self, icon, title, text, detailed_text="", buttons=Cancel | Ok, parent=None): QDialog.__init__(self, parent=parent) self.setWindowFlags(self.windowFlags() & ~Qt.WindowTitleHint) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint & ~Qt.WindowMinimizeButtonHint) self.setObjectName('MessageBox') self._use_checkbox = True self.text = text self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setContentsMargins(1, 1, 1, 1) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.horizontalLayout.setContentsMargins(1, 1, 1, 1) # create icon pixmap = None if icon == self.NoIcon: pass elif icon == self.Question: pixmap = QPixmap( QImage(":icons/question.png").scaled(56, 56, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) elif icon == self.Information: pixmap = QPixmap( QImage(":icons/info.png").scaled(56, 56, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) elif icon == self.Warning: pixmap = QPixmap( QImage(":icons/warning.png").scaled(56, 56, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) elif icon == self.Critical: pixmap = QPixmap( QImage(":icons/critical.png").scaled(56, 56, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) spacerItem = QSpacerItem(10, 60, QSizePolicy.Minimum, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.icon_label = QLabel() if pixmap is not None: self.icon_label.setPixmap(pixmap) self.icon_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.horizontalLayout.addWidget(self.icon_label) spacerItem = QSpacerItem(10, 60, QSizePolicy.Minimum, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) # add message self.message_label = QLabel(text) self.message_label.setWordWrap(True) self.message_label.setScaledContents(True) self.message_label.setOpenExternalLinks(True) self.horizontalLayout.addWidget(self.message_label) self.verticalLayout.addLayout(self.horizontalLayout) # create buttons self.buttonBox = QDialogButtonBox(self) self.buttonBox.setObjectName("buttonBox") self.buttonBox.setOrientation(Qt.Horizontal) self._accept_button = None self._reject_button = None self._buttons = buttons self._create_buttons(buttons) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.verticalLayout.addWidget(self.buttonBox) if detailed_text: self.btn_show_details = QPushButton(self.tr('Details...')) self.btn_show_details.setCheckable(True) self.btn_show_details.setChecked(True) self.btn_show_details.toggled.connect(self.on_toggled_details) self.buttonBox.addButton(self.btn_show_details, QDialogButtonBox.ActionRole) # create area for detailed text self.textEdit = textEdit = QTextEdit(self) textEdit.setObjectName("textEdit") textEdit.setReadOnly(True) textEdit.setText(detailed_text) # textEdit.setVisible(False) self.verticalLayout.addWidget(self.textEdit) self.resize(480, self.verticalLayout.totalSizeHint().height()) buttons_in_box = self.buttonBox.buttons() if buttons_in_box: self.buttonBox.buttons()[0].setFocus()
class InspectorWindow(AbstractStatusWidget): _sig_write = Signal(str, str) _sig_newline = Signal() _sig_close_window = Signal() _sig_clear = Signal() def __init__(self, status, close_callback): """ @todo: UI construction that currently is done in this method, needs to be done in .ui file. @param status: DiagnosticStatus @param close_callback: When the instance of this class (InspectorWindow) terminates, this callback gets called. """ super(InspectorWindow, self).__init__() self.status = status self._close_callback = close_callback self.setWindowTitle(status.name) self.paused = False self.layout_vertical = QVBoxLayout(self) self.disp = QTextEdit(self) self.snapshot = QPushButton("Snapshot") self.timeline_pane = TimelinePane(self, Util._SECONDS_TIMELINE, self._cb, self.get_color_for_value) self.layout_vertical.addWidget(self.disp, 1) self.layout_vertical.addWidget(self.timeline_pane, 0) self.layout_vertical.addWidget(self.snapshot) self.snaps = [] self.snapshot.clicked.connect(self._take_snapshot) self._sig_write.connect(self._write_key_val) self._sig_newline.connect(lambda: self.disp.insertPlainText('\n')) self._sig_clear.connect(lambda: self.disp.clear()) self._sig_close_window.connect(self._close_callback) self.setLayout(self.layout_vertical) self.setGeometry( 0, 0, 400, 600) # TODO better to be configurable where to appear. self.show() self.update_status_display(status) def get_color_for_value(self, queue_diagnostic, color_index): rospy.logdebug( 'InspectorWindow get_color_for_value ' + 'queue_diagnostic=%d, color_index=%d', len(queue_diagnostic), color_index) lv_index = queue_diagnostic[color_index - 1].level return Util._COLOR_DICT[lv_index] ''' Delegated from super class. @author: Isaac Saito ''' def closeEvent(self, event): # emit signal that should be slotted by StatusItem self._sig_close_window.emit() self.close() def _write_key_val(self, k, v): self.disp.setFontWeight(75) self.disp.insertPlainText(k) self.disp.insertPlainText(': ') self.disp.setFontWeight(50) self.disp.insertPlainText(v) self.disp.insertPlainText('\n') def pause(self, msg): """ @todo: Create a superclass for this and RobotMonitorWidget that has pause func. """ rospy.logdebug('InspectorWin pause PAUSED') self.paused = True self.update_status_display(msg) def unpause(self, msg): rospy.logdebug('InspectorWin pause UN-PAUSED') self.paused = False #self.update_status_display(msg); def _cb(self, msg, is_forced=False): """ @param status: DiagnosticsStatus Overriden """ if not self.paused: #if is_forced: self.update_status_display(msg) rospy.logdebug('InspectorWin _cb len of queue=%d self.paused=%s', len(self.timeline_pane._queue_diagnostic), self.paused) else: if is_forced: self.update_status_display(msg, True) rospy.logdebug('@@@InspectorWin _cb PAUSED window updated') else: rospy.logdebug('@@@InspectorWin _cb PAUSED not updated') def update_status_display(self, status, is_forced=False): """ @param status: DiagnosticsStatus """ if not self.paused or (self.paused and is_forced): self.timeline_pane.new_diagnostic(status) rospy.logdebug('InspectorWin update_status_display 1') self.status = status self._sig_clear.emit() self._sig_write.emit("Full Name", status.name) self._sig_write.emit("Component", status.name.split('/')[-1]) self._sig_write.emit("Hardware ID", status.hardware_id) self._sig_write.emit("Level", str(status.level)) self._sig_write.emit("Message", status.message) self._sig_newline.emit() for v in status.values: self._sig_write.emit(v.key, v.value) def _take_snapshot(self): snap = Snapshot(self.status) self.snaps.append(snap) def enable(self): #wx.Panel.Enable(self) #self._timeline.enable() self.setEnabled(True) self.timeline_pane.enable() self.timeline_pane.pause_button.setDown(False) def disable(self): """Supposed to be called upon pausing.""" #wx.Panel.Disable(self) #self._timeline.Disable() self.setEnable(False) self.timeline_pane.disable() self.pause_button.Disable() self.unpause() self.timeline_pane.pause_button.setDown(True)
def __init__(self): QTextEdit.__init__(self) self.setReadOnly(True)
class Widgetti(QWidget): dead_update = Signal() pose_update = Signal() def __init__(self): super(Widgetti, self).__init__() self.layout = QVBoxLayout() self.control_layout = QVBoxLayout() self.button_layout = QHBoxLayout() self.map_layout = QHBoxLayout() self.console_layout = QVBoxLayout() self.text_layout = QHBoxLayout() self.tf = tf.TransformListener() self.dead_update.connect(self.update_dead) self.pose_update.connect(self.update_pose_in_map) self.pirates = [] self.dead_pirates = [] self.dead_pirate_objects = [] self.pirate_update = True self.dead_pirate_update = False self.pose = None self.waiting = False #self.pirate_detector = pirate_detector() #Initializing pirate detector self.setWindowTitle('GUI for Pioneer P3-DX') self.gui_publisher = rospy.Publisher('gui_plan', Path) self.actionclient = actionlib.SimpleActionClient('move_base', MoveBaseAction) #self.notificationPub = rospy.Publisher('notification', RideNotification) self.actionclient.wait_for_server() self.debug_stream = QTextEdit(self) self.taskplanner = TaskPlanner(parent = self) self.robomap = RoboMap(tf = self.tf, parent=self) self.left = QPushButton('Spin left') self.left.clicked.connect(self.spin_left) self.right = QPushButton('Spin right') self.right.clicked.connect(self.spin_right) self.point_move = QPushButton('Move to point') self.point_move.clicked.connect(self.point_go) self.control_layout.addWidget(self.left) self.control_layout.addWidget(self.right) self.control_layout.addWidget(self.point_move) # task planner stuff self.open_manip = QPushButton('Open manipulator') self.open_manip.clicked.connect(self.taskplanner.openManipulator) self.close_manip = QPushButton('Close manipulator') self.close_manip.clicked.connect(self.taskplanner.closeManipulator) self.taskplanning = QPushButton('Execute Mission') self.taskplanning.clicked.connect(self.taskplanner.execute) self.button_layout.addWidget(self.open_manip) self.button_layout.addWidget(self.close_manip) self.button_layout.addWidget(self.taskplanning) self.button_layout.addWidget(self.open_manip) self.button_layout.addWidget(self.close_manip) self.map_layout.addWidget(self.robomap) self.console_layout.addLayout(self.map_layout) self.console_layout.addLayout(self.control_layout) self.text_layout.addWidget(self.debug_stream) self.layout.addLayout(self.console_layout) self.layout.addLayout(self.button_layout) self.layout.addLayout(self.text_layout) self.layout.addWidget(QLabel('Graphical interface to visualize stuff')) self.setLayout(self.layout) self.timer = 0 self.pose_sub = rospy.Subscriber('RosAria/pose', Odometry, self.pose_callback) # Pirate detector subscribers self.pirates_sub = rospy.Subscriber('/Pirates', Path, self.pirate_callback) self.dead_pirates_sub = rospy.Subscriber('/Dead', Path, self.dead_pirate_callback) self.pirate_update = True self.dead_pirate_update = True self.pose_update_timer = 0 self.point_goal = None def spin_left(self): r = rospy.Rate(1.0) # 1 Hz movement = Twist() movement.angular.z = 3.14 # ~45 deg/s for i in range(32): self.taskplanner.driver.publish(movement) r.sleep() self.taskplanner.driver.publish(Twist()) def spin_right(self): r = rospy.Rate(1.0) # 1 Hz movement = Twist() movement.angular.z = -3.14 # ~45 deg/s for i in range(320): self.taskplanner.driver.publish(movement) r.sleep() self.taskplanner.driver.publish(Twist()) def point_go(self): if self.robomap.point: w = self.robomap.w res = self.robomap.resolution org = self.robomap.origin tmp = self.robomap.point.rect().center() x1 = (w - tmp.x()) * res + org[0] y1 = tmp.y() * res + org[1] x2 = (w - tmp.x()) * res + org[0] y2 = tmp.y() * res + org[1] quaternion = quaternion_from_euler(0, 0, math.atan2(y2 - y1, x2 - x1)) pose = PoseStamped() pose.header.stamp = rospy.Time.now() pose.header.frame_id = "map" pose.pose.position.x = x1 pose.pose.position.y = y1 pose.pose.orientation.w = quaternion[3] pose.pose.orientation.z = quaternion[2] self.point_goal = MoveBaseGoal(target_pose=pose) self.actionclient.send_goal(self.point_goal, feedback_cb=self.point_feedback) else: self.update_textbox('CANNOT EXECUTE MOVE: ', 'NO POINT SELECTED') def point_feedback(self, feedback): pose_stamp = feedback.base_position self.timer += 1 if self.pose_update_timer > 20: self.update_pose_in_map() self.pose_update_timer = 0 if self.point_goal and self.distance(self.point_goal, pose_stamp) < 0.2: self.timer = 0 #print str(self.distance(self.pirate_detector.move_goal, pose_stamp)) # this check cancels the goal if the robot is "close enough" # move_base will endlessly spin sometimes without this code self.actionclient.cancel_goal() rospy.sleep(1.0) self.point_goal = None if self.timer > 500: self.actionclient.cancel_goal() #self.update_textbox('Could not reach target: ', 'Timeout') self.pose_update_timer += 1 def pirate_callback(self, data): if self.pirate_update: for z in data.poses: self.pirates.append(z) self.pirate_update = False print self.pirates # Explorer callback #self.taskplanner.explorer.detector_callback(data) def dead_pirate_callback(self, data): if self.dead_pirate_update: for z in data.poses: self.dead_pirates.append(z) self.dead_pirate_update = False self.dead_update.emit() def update_dead(self): print 'Adding dead to map' if self.dead_pirate_objects: self.clear_dead() self.robomap.update_map(self.dead_pirates) #self.update_textbox('DEAD FOUND IN TOTAL: ', str(len(self.dead_pirates))) def clear_dead(self): for z in self.dead_pirate_objects: self.robomap.scene.removeItem(z) return True def update_textbox(self, header, txt): self.debug_stream.insertPlainText(header + '\n') self.debug_stream.insertPlainText(txt+'\n') def pose_callback(self, data): self.pose = data def update_pose_in_map(self): if self.robomap.point: self.robomap.scene.removeItem(self.robomap.point) self.robomap.point = None x = self.pose.pose.pose.position.x y = self.pose.pose.pose.position.y #transform pose coordinates to map coordinates map_y = (y - self.robomap.origin[1])/self.robomap.resolution map_x = -((x - self.robomap.origin[0])/self.robomap.resolution) + self.robomap.w self.robomap.point = self.robomap.draw_point(map_x, map_y, color=Qt.blue, rad=3.0) def done_callback(self, status, result): if status is GoalStatus.RECALLED: print 'recalled' elif status is GoalStatus.SUCCEEDED: print 'success' elif status is GoalStatus.REJECTED: print 'rejected' elif status is GoalStatus.ABORTED: print 'aborted' else: print 'sumthing else' print goal_states.get(status) def feedback(self, feedback): pose_stamp = feedback.base_position self.timer += 1 print 'in feedback' if self.pose_update_timer > 20: print 'omg' self.pose_update.emit() self.pose_update_timer = 0 if self.taskplanner.move_goal and self.distance(self.taskplanner.move_goal, pose_stamp) < 0.2: self.timer = 0 #print str(self.distance(self.pirate_detector.move_goal, pose_stamp)) # this check cancels the goal if the robot is "close enough" # move_base will endlessly spin sometimes without this code self.actionclient.cancel_goal() if self.taskplanner.state == -1: self.pirate_update = True self.dead_pirate_update = True rospy.sleep(1.0) self.goal = None print 'Moving to next state from ' + str(self.taskplanner.state) self.taskplanner.state = self.taskplanner.state + 1 self.waiting = False #self.taskplanner.explorer_pub = rospy.Publisher('explore_next_point', String, latch=False) if self.timer > 500: print 'wtf?' self.actionclient.cancel_goal() self.goal = None self.taskplanner.state = self.taskplanner.state + 1 self.waiting = False self.timer = 0 self.pose_update_timer += 1 def feedback2(self, feedback): pose_stamp = feedback.base_position self.timer += 1 print 'in feedback2' if self.taskplanner.move_goal and self.distance(self.taskplanner.move_goal, pose_stamp) < 0.2: self.timer = 0 #print str(self.distance(self.pirate_detector.move_goal, pose_stamp)) # this check cancels the goal if the robot is "close enough" # move_base will endlessly spin sometimes without this code self.actionclient.cancel_goal() rospy.sleep(1.0) self.taskplanner.move_goal = None luku = randint(0,2) r = rospy.Rate(1.0) # 1 Hz movement = Twist() if luku == 0: movement.angular.z = 0 if luku == 1: movement.angular.z = 3.14/2 # ~45 deg/s if luku == 2: movement.angular.z = -3.14/2 # ~45 deg/s self.taskplanner.driver.publish(movement) r.sleep() self.taskplanner.driver.publish(Twist()) rospy.sleep(2.0) self.pirate_update = True self.dead_pirate_update = True rospy.sleep(2.0) self.last_pirate = None if self.timer > 500: print 'wtf?' self.actionclient.cancel_goal() def distance(self, t1, t2): """ Given two PoseStamped's, determine the distance """ out = 0 for dimension in ('x', 'y'): out += math.pow(getattr(t1.target_pose.pose.position, dimension) - getattr(t2.pose.position, dimension), 2) return math.sqrt(out)
class TextEdit(QTextEdit): ''' The XML editor to handle the included files. If an included file in the opened launch file is detected, this can be open by STRG+(mouse click) in a new editor. ''' load_request_signal = Signal(str) ''' @ivar: A signal for request to open a configuration file''' 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. ''' SUBSTITUTION_ARGS = ['env', 'optenv', 'find', 'anon', 'arg'] CONTEXT_FILE_EXT = ['.launch', '.test', '.xml'] YAML_VALIDATION_FILES = ['.yaml', '.iface', '.sync'] def __init__(self, filename, parent=None): self.parent = parent QTextEdit.__init__(self, parent) self.setObjectName(' - '.join(['Editor', filename])) self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_custom_context_menu) # self.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.setAcceptRichText(False) font = QFont() font.setFamily("Fixed".decode("utf-8")) font.setPointSize(12) self.setFont(font) self.setLineWrapMode(QTextEdit.NoWrap) self.setTabStopWidth(25) self.setAcceptRichText(False) self.setCursorWidth(2) self.setFontFamily("courier new") self.setProperty("backgroundVisible", True) self.regexp_list = [ QRegExp("\\binclude\\b"), QRegExp("\\btextfile\\b"), QRegExp("\\bfile\\b"), QRegExp("\\bvalue=.*pkg:\/\/\\b"), QRegExp("\\bvalue=.*package:\/\/\\b"), QRegExp("\\bvalue=.*\$\(find\\b"), QRegExp("\\bargs=.*\$\(find\\b"), QRegExp("\\bdefault=.*\$\(find\\b") ] self.filename = filename self.file_info = None if self.filename: f = QFile(filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.file_info = QFileInfo(filename) self.setText(unicode(f.readAll(), "utf-8")) self.path = '.' # enables drop events self.setAcceptDrops(True) if filename.endswith('.launch'): self.hl = XmlHighlighter(self.document()) self.cursorPositionChanged.connect(self._document_position_changed) else: self.hl = YamlHighlighter(self.document()) # variables for threaded search self._search_thread = None self._stop = False def _document_position_changed(self): if isinstance(self.hl, XmlHighlighter) and nm.settings().highlight_xml_blocks: # import time # start_time = time.time() self.hl.mark_block(self.textCursor().block(), self.textCursor().positionInBlock()) # print("--- mark_tag_block %.6f seconds ---" % (time.time() - start_time)) def save(self, force=False): ''' Saves changes to the file. :return: saved, errors, msg :rtype: bool, bool, str ''' if force or self.document().isModified() or not QFileInfo( self.filename).exists(): f = QFile(self.filename) if f.open(QIODevice.WriteOnly | QIODevice.Text): f.write(self.toPlainText().encode('utf-8')) self.document().setModified(False) self.file_info = QFileInfo(self.filename) ext = os.path.splitext(self.filename) # validate the xml structure of the launch files if ext[1] in self.CONTEXT_FILE_EXT: imported = False try: from lxml import etree imported = True parser = etree.XMLParser() etree.fromstring(self.toPlainText().encode('utf-8'), parser) except Exception as e: if imported: self.markLine(e.position[0]) return True, True, "%s" % e # validate the yaml structure of yaml files elif ext[1] in self.YAML_VALIDATION_FILES: try: import yaml yaml.load(self.toPlainText().encode('utf-8')) except yaml.MarkedYAMLError as e: return True, True, "%s" % e return True, False, '' else: return False, True, "Cannot write XML file" return False, False, '' def markLine(self, no): try: cursor = self.textCursor() cursor.setPosition(0, QTextCursor.MoveAnchor) while (cursor.block().blockNumber() + 1 < no): cursor.movePosition(QTextCursor.NextBlock, QTextCursor.MoveAnchor) cursor.movePosition(QTextCursor.EndOfBlock, QTextCursor.KeepAnchor) self.setTextCursor(cursor) except: pass def setCurrentPath(self, path): ''' Sets the current working path. This path is to open the included files, which contains the relative path. @param path: the path of the current opened file (without the file) @type path: C{str} ''' self.path = path def index(self, text): ''' Searches in the given text for key indicates the including of a file and return their index. @param text: text to find @type text: C{str} @return: the index of the including key or -1 @rtype: C{int} ''' for pattern in self.regexp_list: index = pattern.indexIn(text) if index > -1: return index return -1 def includedFiles(self): ''' Returns all included files in the document. ''' result = [] b = self.document().begin() while b != self.document().end(): text = b.text() index = self.index(text) if index > -1: startIndex = text.find('"', index) if startIndex > -1: endIndex = text.find('"', startIndex + 1) fileName = text[startIndex + 1:endIndex] if len(fileName) > 0: try: path = interpret_path(fileName) f = QFile(path) ext = os.path.splitext(path) if f.exists() and ext[1] in nm.settings( ).SEARCH_IN_EXT: result.append(path) except: import traceback print traceback.format_exc(1) b = b.next() return result def focusInEvent(self, event): # check for file changes try: if self.filename and self.file_info: if self.file_info.lastModified() != QFileInfo( self.filename).lastModified(): self.file_info = QFileInfo(self.filename) result = QMessageBox.question( self, "File changed", "File was changed, reload?", QMessageBox.Yes | QMessageBox.No) if result == QMessageBox.Yes: f = QFile(self.filename) if f.open(QIODevice.ReadOnly | QIODevice.Text): self.setText(unicode(f.readAll(), "utf-8")) self.document().setModified(False) self.textChanged.emit() else: QMessageBox.critical( self, "Error", "Cannot open launch file%s" % self.filename) except: pass QTextEdit.focusInEvent(self, event) def mouseReleaseEvent(self, event): ''' Opens the new editor, if the user clicked on the included file and sets the default cursor. ''' if event.modifiers() == Qt.ControlModifier or event.modifiers( ) == Qt.ShiftModifier: cursor = self.cursorForPosition(event.pos()) inc_files = LaunchConfig.included_files(cursor.block().text(), recursive=False) if inc_files: try: qf = QFile(inc_files[0]) if not qf.exists(): # create a new file, if it does not exists result = QMessageBox.question( self, "File not found", '\n\n'.join(["Create a new file?", qf.fileName()]), QMessageBox.Yes | QMessageBox.No) if result == QMessageBox.Yes: d = os.path.dirname(qf.fileName()) if not os.path.exists(d): os.makedirs(d) with open(qf.fileName(), 'w') as f: if qf.fileName().endswith('.launch'): f.write('<launch>\n\n</launch>') event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) else: event.setAccepted(True) self.load_request_signal.emit(qf.fileName()) except Exception, e: WarningMessageBox(QMessageBox.Warning, "File not found %s" % inc_files[0], str(e)).exec_() QTextEdit.mouseReleaseEvent(self, event)
def contextMenuEvent(self, event): QTextEdit.contextMenuEvent(self, event)
class InspectorWidget(QWidget): write = pyqtSignal(str, str) newline = pyqtSignal() clear = pyqtSignal() def __init__(self, status): super(InspectorWidget, self).__init__() self.status = status self.setWindowTitle(status.name) self.paused = False layout = QVBoxLayout() self.disp = QTextEdit() self.snapshot = QPushButton("Snapshot") self.time = TimelineWidget(self) layout.addWidget(self.disp, 1) layout.addWidget(self.time, 0) layout.addWidget(self.snapshot) self.snaps = [] self.snapshot.clicked.connect(self.take_snapshot) self.write.connect(self.write_kv) self.newline.connect(lambda: self.disp.insertPlainText('\n')) self.clear.connect(lambda: self.disp.clear()) self.setLayout(layout) self.setGeometry(0,0,300,400) self.show() self.update(status) def write_kv(self, k, v): self.disp.setFontWeight(75) self.disp.insertPlainText(k) self.disp.insertPlainText(': ') self.disp.setFontWeight(50) self.disp.insertPlainText(v) self.disp.insertPlainText('\n') def pause(self, msg): self.update(msg); self.paused = True def unpause(self): self.paused = False def update(self, status): if not self.paused: self.status = status self.time.add_message(status) self.clear.emit() self.write.emit("Full Name", status.name) self.write.emit("Component", status.name.split('/')[-1]) self.write.emit("Hardware ID", status.hardware_id) self.write.emit("Level", str(status.level)) self.write.emit("Message", status.message) self.newline.emit() for v in status.values: self.write.emit(v.key, v.value) def take_snapshot(self): snap = Snapshot(self.status) self.snaps.append(snap)
def __init__(self): super(Widgetti, self).__init__() self.layout = QVBoxLayout() self.control_layout = QVBoxLayout() self.button_layout = QHBoxLayout() self.map_layout = QHBoxLayout() self.console_layout = QVBoxLayout() self.text_layout = QHBoxLayout() self.tf = tf.TransformListener() self.dead_update.connect(self.update_dead) self.pose_update.connect(self.update_pose_in_map) self.pirates = [] self.dead_pirates = [] self.dead_pirate_objects = [] self.pirate_update = True self.dead_pirate_update = False self.pose = None self.waiting = False #self.pirate_detector = pirate_detector() #Initializing pirate detector self.setWindowTitle('GUI for Pioneer P3-DX') self.gui_publisher = rospy.Publisher('gui_plan', Path) self.actionclient = actionlib.SimpleActionClient('move_base', MoveBaseAction) #self.notificationPub = rospy.Publisher('notification', RideNotification) self.actionclient.wait_for_server() self.debug_stream = QTextEdit(self) self.taskplanner = TaskPlanner(parent = self) self.robomap = RoboMap(tf = self.tf, parent=self) self.left = QPushButton('Spin left') self.left.clicked.connect(self.spin_left) self.right = QPushButton('Spin right') self.right.clicked.connect(self.spin_right) self.point_move = QPushButton('Move to point') self.point_move.clicked.connect(self.point_go) self.control_layout.addWidget(self.left) self.control_layout.addWidget(self.right) self.control_layout.addWidget(self.point_move) # task planner stuff self.open_manip = QPushButton('Open manipulator') self.open_manip.clicked.connect(self.taskplanner.openManipulator) self.close_manip = QPushButton('Close manipulator') self.close_manip.clicked.connect(self.taskplanner.closeManipulator) self.taskplanning = QPushButton('Execute Mission') self.taskplanning.clicked.connect(self.taskplanner.execute) self.button_layout.addWidget(self.open_manip) self.button_layout.addWidget(self.close_manip) self.button_layout.addWidget(self.taskplanning) self.button_layout.addWidget(self.open_manip) self.button_layout.addWidget(self.close_manip) self.map_layout.addWidget(self.robomap) self.console_layout.addLayout(self.map_layout) self.console_layout.addLayout(self.control_layout) self.text_layout.addWidget(self.debug_stream) self.layout.addLayout(self.console_layout) self.layout.addLayout(self.button_layout) self.layout.addLayout(self.text_layout) self.layout.addWidget(QLabel('Graphical interface to visualize stuff')) self.setLayout(self.layout) self.timer = 0 self.pose_sub = rospy.Subscriber('RosAria/pose', Odometry, self.pose_callback) # Pirate detector subscribers self.pirates_sub = rospy.Subscriber('/Pirates', Path, self.pirate_callback) self.dead_pirates_sub = rospy.Subscriber('/Dead', Path, self.dead_pirate_callback) self.pirate_update = True self.dead_pirate_update = True self.pose_update_timer = 0 self.point_goal = None
def _setting_service(self): if self.is_setting_dlg_live: print "Dialog is live!!" self._setting_dlg.done(0) #dialog self._setting_dlg = QDialog(self._widget) self._setting_dlg.setWindowTitle("Seting Configuration") self._setting_dlg.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) self._setting_dlg.setMinimumSize(500, 0) dlg_rect = self._setting_dlg.geometry() #dialog layout ver_layout = QVBoxLayout(self._setting_dlg) ver_layout.setContentsMargins(9, 9, 9, 9) #param layout text_grid_sub_widget = QWidget() text_grid_layout = QGridLayout(text_grid_sub_widget) text_grid_layout.setColumnStretch(1, 0) text_grid_layout.setRowStretch(2, 0) #param 1 name = u"" title_widget1 = QLabel("Param1: ") context_widget1 = QTextEdit() context_widget1.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) context_widget1.setMinimumSize(0, 30) context_widget1.append("") #param 2 cancel = False title_widget2 = QLabel("Param2: ") context_widget2 = QTextEdit() context_widget2.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) context_widget2.setMinimumSize(0, 30) context_widget2.append("") #param 3 cancel = False title_widget3 = QLabel("Param2: ") context_widget3 = QTextEdit() context_widget3.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored) context_widget3.setMinimumSize(0, 30) context_widget3.append("") #add param text_grid_layout.addWidget(title_widget1) text_grid_layout.addWidget(context_widget1) text_grid_layout.addWidget(title_widget2) text_grid_layout.addWidget(context_widget2) text_grid_layout.addWidget(title_widget3) text_grid_layout.addWidget(context_widget3) #add param layout ver_layout.addWidget(text_grid_sub_widget) #button layout button_hor_sub_widget = QWidget() button_hor_layout = QHBoxLayout(button_hor_sub_widget) params = {} params['param1'] = context_widget1 params['param2'] = context_widget2 params['param3'] = context_widget3 #button btn_call = QPushButton("Set") btn_cancel = QPushButton("Cancel") btn_call.clicked.connect(lambda: self._setting_dlg.done(0)) btn_call.clicked.connect(lambda: self._set_configuration(params)) btn_cancel.clicked.connect(lambda: self._setting_dlg.done(0)) #add button button_hor_layout.addWidget(btn_call) button_hor_layout.addWidget(btn_cancel) #add button layout ver_layout.addWidget(button_hor_sub_widget) self._setting_dlg.setVisible(True) self._setting_dlg.finished.connect(self._destroy_setting_dlg) self.is_setting_dlg_live = True pass
class InspectorWindow(AbstractStatusWidget): _sig_write = Signal(str, str) _sig_newline = Signal() _sig_close_window = Signal() _sig_clear = Signal() def __init__(self, status, close_callback): """ :type status: DiagnosticStatus :param close_callback: When the instance of this class (InspectorWindow) terminates, this callback gets called. """ #TODO(Isaac) UI construction that currently is done in this method, # needs to be done in .ui file. super(InspectorWindow, self).__init__() self.status = status self._close_callback = close_callback self.setWindowTitle(status.name) self.paused = False self.layout_vertical = QVBoxLayout(self) self.disp = QTextEdit(self) self.snapshot = QPushButton("StatusSnapshot") self.timeline_pane = TimelinePane(self) self.timeline_pane.set_timeline_data(Util.SECONDS_TIMELINE, self.get_color_for_value, self.on_pause) self.layout_vertical.addWidget(self.disp, 1) self.layout_vertical.addWidget(self.timeline_pane, 0) self.layout_vertical.addWidget(self.snapshot) self.snaps = [] self.snapshot.clicked.connect(self._take_snapshot) self._sig_write.connect(self._write_key_val) self._sig_newline.connect(lambda: self.disp.insertPlainText('\n')) self._sig_clear.connect(lambda: self.disp.clear()) self._sig_close_window.connect(self._close_callback) self.setLayout(self.layout_vertical) # TODO better to be configurable where to appear. self.setGeometry(0, 0, 400, 600) self.show() self.update_status_display(status) def closeEvent(self, event): # emit signal that should be slotted by StatusItem self._sig_close_window.emit() self.close() def _write_key_val(self, k, v): self.disp.setFontWeight(75) self.disp.insertPlainText(k) self.disp.insertPlainText(': ') self.disp.setFontWeight(50) self.disp.insertPlainText(v) self.disp.insertPlainText('\n') def pause(self, msg): rospy.logdebug('InspectorWin pause PAUSED') self.paused = True self.update_status_display(msg) def unpause(self, msg): rospy.logdebug('InspectorWin pause UN-PAUSED') self.paused = False def new_diagnostic(self, msg, is_forced=False): """ Overridden from AbstractStatusWidget :type status: DiagnosticsStatus """ if not self.paused: self.update_status_display(msg) rospy.logdebug('InspectorWin _cb len of queue=%d self.paused=%s', len(self.timeline_pane._queue_diagnostic), self.paused) else: if is_forced: self.update_status_display(msg, True) rospy.logdebug('@@@InspectorWin _cb PAUSED window updated') else: rospy.logdebug('@@@InspectorWin _cb PAUSED not updated') def update_status_display(self, status, is_forced=False): """ :type status: DiagnosticsStatus """ if not self.paused or (self.paused and is_forced): scroll_value = self.disp.verticalScrollBar().value() self.timeline_pane.new_diagnostic(status) rospy.logdebug('InspectorWin update_status_display 1') self.status = status self._sig_clear.emit() self._sig_write.emit("Full Name", status.name) self._sig_write.emit("Component", status.name.split('/')[-1]) self._sig_write.emit("Hardware ID", status.hardware_id) self._sig_write.emit("Level", str(status.level)) self._sig_write.emit("Message", status.message) self._sig_newline.emit() for v in status.values: self._sig_write.emit(v.key, v.value) if self.disp.verticalScrollBar().maximum() < scroll_value: scroll_value = self.disp.verticalScrollBar().maximum() self.disp.verticalScrollBar().setValue(scroll_value) def _take_snapshot(self): snap = StatusSnapshot(self.status) self.snaps.append(snap) def get_color_for_value(self, queue_diagnostic, color_index): """ Overridden from AbstractStatusWidget. :type color_index: int """ rospy.logdebug( 'InspectorWindow get_color_for_value ' + 'queue_diagnostic=%d, color_index=%d', len(queue_diagnostic), color_index) lv_index = queue_diagnostic[color_index - 1].level return Util.COLOR_DICT[lv_index]
def focusInEvent(self, event): # check for file changes if self.filename and self.file_mtime: nm.nmd().file.check_for_changed_files_threaded( {self.filename: self.file_mtime}) QTextEdit.focusInEvent(self, event)
def wheelEvent(self, event): if self._reader is not None: lines = event.angleDelta().y() / 40 if lines > 0 and self.verticalScrollBar().value() == 0: self._reader.reverse_read(lines) QTextEdit.wheelEvent(self, event)
def mouseReleaseEvent(self, event): ''' Opens the new editor, if the user clicked on the included file and sets the default cursor. ''' if self.isReadOnly(): event.accept() return if event.modifiers() == Qt.ControlModifier or event.modifiers( ) == Qt.ShiftModifier: cursor = self.cursorForPosition(event.pos()) try: textblock = self._strip_bad_parts(cursor.block().text(), cursor.positionInBlock()) for inc_file in find_included_files(textblock, False, False, search_in_ext=[]): aval = inc_file.raw_inc_path aitems = aval.split("'") for search_for in aitems: if not search_for: continue try: rospy.logdebug("try to interpret: %s" % search_for) args_in_name = get_arg_names(search_for) resolved_args = {} # if found arg in the name, try to detect values if args_in_name: rospy.logdebug( " args %s in filename found, try to resolve..." % args_in_name) resolved_args = self.parent.graph_view.get_include_args( args_in_name, search_for, self.filename) if resolved_args: params = {} self._internal_args # create parameter dialog for key, val in resolved_args.items(): values = list(val) # add args defined in current file if key in self._internal_args and self._internal_args[ key] not in values: values.append(self._internal_args[key]) params[key] = { ':type': 'string', ':value': values } dia = ParameterDialog( params, store_geometry="open_launch_on_click") dia.setFilterVisible(False) dia.setWindowTitle('Select Parameter') if dia.exec_(): params = dia.getKeywords() search_for = replace_arg( search_for, params) else: # canceled -> cancel interpretation QTextEdit.mouseReleaseEvent(self, event) return # now resolve find-statements rospy.logdebug( " send interpret request to daemon: %s" % search_for) inc_files = nm.nmd().launch.get_interpreted_path( self.filename, text=[search_for]) for path, exists in inc_files: try: rospy.logdebug( " received interpret request from daemon: %s, exists: %d" % (path, exists)) if exists: event.setAccepted(True) self.load_request_signal.emit(path) else: _filename, file_extension = os.path.splitext( path) if file_extension in nm.settings( ).launch_view_file_ext: # create a new file, if it does not exists result = MessageBox.question( self, "File not exists", '\n\n'.join([ "Create a new file?", path ]), buttons=MessageBox.Yes | MessageBox.No) if result == MessageBox.Yes: content = '<launch>\n\n</launch>' if path.endswith( '.launch') else '' nm.nmd().file.save_file( path, content.encode(), 0) event.setAccepted(True) self.load_request_signal.emit( path) except Exception as e: MessageBox.critical(self, "Error", "File not found %s" % path, detailed_text=utf8(e)) except exceptions.ResourceNotFound as not_found: MessageBox.critical( self, "Error", "Resource not found %s" % search_for, detailed_text=utf8(not_found.error)) except Exception as err: print(traceback.format_exc()) MessageBox.critical(self, "Error", "Error while request included file %s" % self.filename, detailed_text=utf8(err)) QTextEdit.mouseReleaseEvent(self, event)