class TracebackWidget(QWidget): """ Represents a python traceback """ def __init__(self, traceback_msg): QWidget.__init__(self) vbox = QVBoxLayout(self) self._editor = QPlainTextEdit() vbox.addWidget(QLabel(translations.TR_TRACEBACK)) vbox.addWidget(self._editor) self._editor.setReadOnly(True) self._editor.setLineWrapMode(0) self._editor.insertPlainText(traceback_msg) self._editor.selectAll()
class TagHelpViewer( QWidget ): """ The tag help viewer widget """ def __init__( self, parent = None ): QWidget.__init__( self, parent ) self.__isEmpty = True self.__copyAvailable = False self.__clearButton = None self.__textEdit = None self.__header = None self.__copyButton = None self.__selectAllButton = None self.__createLayout( parent ) # create the context menu self.__menu = QMenu( self ) self.__selectAllMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'selectall.png' ), 'Select All', self.__textEdit.selectAll ) self.__copyMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'copytoclipboard.png' ), 'Copy', self.__textEdit.copy ) self.__menu.addSeparator() self.__clearMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'trash.png' ), 'Clear', self.__clear ) self.__textEdit.setContextMenuPolicy( Qt.CustomContextMenu ) self.__textEdit.customContextMenuRequested.connect( self.__handleShowContextMenu ) self.__textEdit.copyAvailable.connect( self.__onCopyAvailable ) self.__updateToolbarButtons() return def __createLayout( self, parent ): " Helper to create the viewer layout " # __textEdit list area self.__textEdit = QPlainTextEdit( parent ) self.__textEdit.setLineWrapMode( QPlainTextEdit.NoWrap ) self.__textEdit.setFont( QFont( GlobalData().skin.baseMonoFontFace ) ) self.__textEdit.setReadOnly( True ) # Default font size is good enough for most of the systems. # 12.0 might be good only in case of the XServer on PC (Xming). # self.__textEdit.setFontPointSize( 12.0 ) # Buttons self.__selectAllButton = QAction( PixmapCache().getIcon( 'selectall.png' ), 'Select all', self ) self.__selectAllButton.triggered.connect(self.__textEdit.selectAll ) self.__copyButton = QAction( PixmapCache().getIcon( 'copytoclipboard.png' ), 'Copy to clipboard', self ) self.__copyButton.triggered.connect( self.__textEdit.copy ) spacer = QWidget() spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding ) self.__clearButton = QAction( PixmapCache().getIcon( 'trash.png' ), 'Clear all', self ) self.__clearButton.triggered.connect( self.__clear ) # Toolbar toolbar = QToolBar() toolbar.setOrientation( Qt.Vertical ) toolbar.setMovable( False ) toolbar.setAllowedAreas( Qt.LeftToolBarArea ) toolbar.setIconSize( QSize( 16, 16 ) ) toolbar.setFixedWidth( 28 ) toolbar.setContentsMargins( 0, 0, 0, 0 ) toolbar.addAction( self.__selectAllButton ) toolbar.addAction( self.__copyButton ) toolbar.addWidget( spacer ) toolbar.addAction( self.__clearButton ) self.__header = QLabel( "Signature: none" ) self.__header.setFrameStyle( QFrame.StyledPanel ) self.__header.setSizePolicy( QSizePolicy.Ignored, QSizePolicy.Fixed ) self.__header.setAutoFillBackground( True ) headerPalette = self.__header.palette() headerBackground = headerPalette.color( QPalette.Background ) headerBackground.setRgb( min( headerBackground.red() + 30, 255 ), min( headerBackground.green() + 30, 255 ), min( headerBackground.blue() + 30, 255 ) ) headerPalette.setColor( QPalette.Background, headerBackground ) self.__header.setPalette( headerPalette ) verticalLayout = QVBoxLayout() verticalLayout.setContentsMargins( 2, 2, 2, 2 ) verticalLayout.setSpacing( 2 ) verticalLayout.addWidget( self.__header ) verticalLayout.addWidget( self.__textEdit ) # layout layout = QHBoxLayout() layout.setContentsMargins( 0, 0, 0, 0 ) layout.setSpacing( 0 ) layout.addWidget( toolbar ) layout.addLayout( verticalLayout ) self.setLayout( layout ) return def __handleShowContextMenu( self, coord ): """ Show the context menu """ self.__selectAllMenuItem.setEnabled( not self.__isEmpty ) self.__copyMenuItem.setEnabled( self.__copyAvailable ) self.__clearMenuItem.setEnabled( not self.__isEmpty ) self.__menu.popup( QCursor.pos() ) return def __calltipDisplayable( self, calltip ): " True if calltip is displayable " if calltip is None: return False if calltip.strip() == "": return False return True def __docstringDisplayable( self, docstring ): " True if docstring is displayable " if docstring is None: return False if isinstance( docstring, dict ): if docstring[ "docstring" ].strip() == "": return False return True if docstring.strip() == "": return False return True def display( self, calltip, docstring ): " Displays the given help information " calltipDisplayable = self.__calltipDisplayable( calltip ) docstringDisplayable = self.__docstringDisplayable( docstring ) self.__isEmpty = True if calltipDisplayable or docstringDisplayable: self.__isEmpty = False if calltipDisplayable: if '\n' in calltip: calltip = calltip.split( '\n' )[ 0 ] self.__header.setText( "Signature: " + calltip.strip() ) else: self.__header.setText( "Signature: n/a" ) self.__textEdit.clear() if docstringDisplayable: if isinstance( docstring, dict ): docstring = docstring[ "docstring" ] self.__textEdit.insertPlainText( docstring ) self.__updateToolbarButtons() QApplication.processEvents() return def __updateToolbarButtons( self ): " Contextually updates toolbar buttons " self.__selectAllButton.setEnabled( not self.__isEmpty ) self.__copyButton.setEnabled( self.__copyAvailable ) self.__clearButton.setEnabled( not self.__isEmpty ) return def __clear( self ): " Triggers when the clear function is selected " self.__isEmpty = True self.__copyAvailable = False self.__header.setText( "Signature: none" ) self.__textEdit.clear() self.__updateToolbarButtons() return def __onCopyAvailable( self, isAvailable ): " Triggers on the copyAvailable signal " self.__copyAvailable = isAvailable self.__updateToolbarButtons() return
class BluetoothWindow(QMainWindow): def __init__(self, inbuf, outbuf,parent=None): super(BluetoothWindow, self).__init__(parent) self.sendbuf=outbuf self.receivebuf=inbuf self.output=QPlainTextEdit() self.output.setReadOnly(True) self.output.setLineWrapMode(QPlainTextEdit.WidgetWidth) self.hor = QHBoxLayout() self.ver = QVBoxLayout() def updateValue(key, value): pidvalues[key] = float(value) print key, "updated to", value for k, v in pidvalues.iteritems(): label = QLabel(k) edit = QLineEdit(str(v)) button = QPushButton("Update") l = QHBoxLayout() l.addWidget(label, 2) l.addWidget(edit, 5) l.addWidget(button, 2) self.ver.addLayout(l) button.clicked.connect(lambda clicked, label=label, edit=edit: updateValue(label.text(), edit.text())) self.hor.addWidget(self.output) self.hor.addLayout(self.ver) w = QWidget() w.setLayout(self.hor) self.setCentralWidget(w) SampleTimeInSec = (pidvalues["PID_SAMPLE_TIME"]) / 1000.0 for i in range(4): pid_params.append(pid_params_typedef()) pid_params[pidvalues["PID_THROTTLE"]].kp = pidvalues["KP_THROTTLE"]; pid_params[pidvalues["PID_THROTTLE"]].ki = pidvalues["KI_THROTTLE"] * SampleTimeInSec; pid_params[pidvalues["PID_THROTTLE"]].kd = pidvalues["KD_THROTTLE"] / SampleTimeInSec; pid_params[pidvalues["PID_THROTTLE"]].min = pidvalues["MIN_THROTTLE"]; pid_params[pidvalues["PID_THROTTLE"]].max = pidvalues["MAX_THROTTLE"]; pid_params[pidvalues["PID_PITCH"]].kp = pidvalues["KP_PITCH"]; pid_params[pidvalues["PID_PITCH"]].ki = pidvalues["KI_PITCH"] * SampleTimeInSec; pid_params[pidvalues["PID_PITCH"]].kd = pidvalues["KD_PITCH"] / SampleTimeInSec; pid_params[pidvalues["PID_PITCH"]].min = pidvalues["MIN_PITCH"]; pid_params[pidvalues["PID_PITCH"]].max = pidvalues["MAX_PITCH"]; pid_params[pidvalues["PID_ROLL"]].kp = pidvalues["KP_ROLL"]; pid_params[pidvalues["PID_ROLL"]].ki = pidvalues["KI_ROLL"] * SampleTimeInSec; pid_params[pidvalues["PID_ROLL"]].kd = pidvalues["KD_ROLL"] / SampleTimeInSec; pid_params[pidvalues["PID_ROLL"]].min = pidvalues["MIN_ROLL"]; pid_params[pidvalues["PID_ROLL"]].max = pidvalues["MAX_ROLL"]; pid_params[pidvalues["PID_YAW"]].kp = pidvalues["KP_YAW"]; pid_params[pidvalues["PID_YAW"]].ki = pidvalues["KI_YAW"] * SampleTimeInSec; pid_params[pidvalues["PID_YAW"]].kd = pidvalues["KD_YAW"] / SampleTimeInSec; pid_params[pidvalues["PID_YAW"]].min = pidvalues["MIN_YAW"]; pid_params[pidvalues["PID_YAW"]].max = pidvalues["MAX_YAW"]; for i in pid_params: print i def receiveText(self): # | 2-5 | Roll | [-pi, pi] | # | 6-9 | Pitch | [-pi, pi] | # | 10-13 | Yaw | [-pi, pi] | # | 14-17 | Height | [0, 10m] | # | 18-21 | Battery | [0, 100%] | rolldata="" pitchdata="" yawdata="" heightdata="" batterydata="" for i in range(4): rolldata+=self.receivebuf.pop(0) for i in range(4): pitchdata+=self.receivebuf.pop(0) for i in range(4): yawdata+=self.receivebuf.pop(0) for i in range(4): heightdata+=self.receivebuf.pop(0) for i in range(4): batterydata+=self.receivebuf.pop(0) roll=struct.unpack('f', rolldata) pitch=struct.unpack('f', pitchdata) yaw=struct.unpack('f', yawdata) self.output.appendPlainText("p "+str(pitch[0])+", r "+str(roll[0])+", y "+str(yaw[0])) ## pids data.pitch = pitch[0] data.roll = roll[0] data.yaw = yaw[0] global lastThrottle pid_output.throttle = self.pid_compute(pidvalues["PID_THROTTLE"], lastThrottle, command.throttle); pid_output.pitch = self.pid_compute(pidvalues["PID_PITCH"], data.pitch, command.pitch); pid_output.roll = self.pid_compute(pidvalues["PID_ROLL"], data.roll, command.roll); pid_output.yaw = self.pid_compute(pidvalues["PID_YAW"], data.yaw, command.yaw); #Save last throttle value lastThrottle = pid_output.throttle * 2 * ( pidvalues["MAX_THROTTLE"] / MOTOR_SPEED_MAX) - pidvalues["MIN_THROTTLE"]; #Add offset to throttle pid_output.throttle += MOTOR_SPEED_HALF; self.motors_pid_apply() ## update gui self.repaint() def motor_name(self, motor): if (motor == MOTOR_RIGHT_BACK): return "RIGHT__BACK" elif (motor == MOTOR_LEFT_BACK): return "LEFT___BACK" elif (motor == MOTOR_RIGHT_FRONT): return "RIGHT_FRONT" elif (motor == MOTOR_LEFT_FRONT): return "LEFT__FRONT" else: return "UNKNOWN" def motors_set_speed(self, motor, value): self.output.appendPlainText("motor "+str(self.motor_name(motor))+", value "+str(int(value))) def motors_pid_apply(self): self.motors_set_speed(MOTOR_RIGHT_FRONT, pid_output.throttle - pid_output.pitch - pid_output.roll - pid_output.yaw); self.motors_set_speed(MOTOR_LEFT_FRONT, pid_output.throttle - pid_output.pitch + pid_output.roll + pid_output.yaw); self.motors_set_speed(MOTOR_RIGHT_BACK, pid_output.throttle + pid_output.pitch - pid_output.roll + pid_output.yaw); self.motors_set_speed(MOTOR_LEFT_BACK, pid_output.throttle + pid_output.pitch + pid_output.roll - pid_output.yaw); def pid_compute(self, index, input, setpoint): pid = pid_params[index] retVal = 0 #Compute all the working error variables*/ error = setpoint - input; pid.iterm += pid.ki * error; if (pid.iterm > pid.max) : pid.iterm = pid.max; else: if (pid.iterm < pid.min): pid.iterm = pid.min; dInput = (input - pid.lastInput); #Compute PID Output*/ retVal = (pid.kp * error + pid.iterm - pid.kd * dInput); if (retVal > pid.max): retVal = pid.max; else: if (retVal < pid.min): retVal = pid.min; #Remember some variables for next time*/ pid.lastInput = input; pid_params[index] = pid return retVal def reset(self): self.output.clear()
class LogViewer(QWidget): """ The log (+stdout, +stderr) viewer widget """ def __init__(self, parent=None): QWidget.__init__(self, parent) self.__isEmpty = True self.__copyAvailable = False self.clearButton = None self.messages = None self.copyButton = None self.selectAllButton = None self.__createLayout(parent) # create the context menu self.__menu = QMenu(self) self.__selectAllMenuItem = self.__menu.addAction( PixmapCache().getIcon('selectall.png'), 'Select All', self.messages.selectAll) self.__copyMenuItem = self.__menu.addAction( PixmapCache().getIcon('copytoclipboard.png'), 'Copy', self.messages.copy) self.__menu.addSeparator() self.__clearMenuItem = self.__menu.addAction( PixmapCache().getIcon('trash.png'), 'Clear', self.__clear) self.messages.setContextMenuPolicy(Qt.CustomContextMenu) self.messages.customContextMenuRequested.connect( self.__handleShowContextMenu) self.messages.copyAvailable.connect(self.__onCopyAvailable) self.cNormalFormat = self.messages.currentCharFormat() self.cErrorFormat = self.messages.currentCharFormat() self.cErrorFormat.setForeground(QBrush(QColor(Qt.red))) self.__updateToolbarButtons() return def __createLayout(self, parent): " Helper to create the viewer layout " # Messages list area self.messages = QPlainTextEdit(parent) self.messages.setLineWrapMode(QPlainTextEdit.NoWrap) self.messages.setFont(QFont(GlobalData().skin.baseMonoFontFace)) self.messages.setReadOnly(True) self.messages.setMaximumBlockCount(MAX_LINES) # Default font size is good enough for most of the systems. # 12.0 might be good only in case of the XServer on PC (Xming). # self.messages.setFontPointSize( 12.0 ) # Buttons self.selectAllButton = QAction(PixmapCache().getIcon('selectall.png'), 'Select all', self) self.selectAllButton.triggered.connect(self.messages.selectAll) self.copyButton = QAction(PixmapCache().getIcon('copytoclipboard.png'), 'Copy to clipboard', self) self.copyButton.triggered.connect(self.messages.copy) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear all', self) self.clearButton.triggered.connect(self.__clear) # Toolbar self.toolbar = QToolBar() self.toolbar.setOrientation(Qt.Vertical) self.toolbar.setMovable(False) self.toolbar.setAllowedAreas(Qt.LeftToolBarArea) self.toolbar.setIconSize(QSize(16, 16)) self.toolbar.setFixedWidth(28) self.toolbar.setContentsMargins(0, 0, 0, 0) self.toolbar.addAction(self.selectAllButton) self.toolbar.addAction(self.copyButton) self.toolbar.addWidget(spacer) self.toolbar.addAction(self.clearButton) # layout layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self.toolbar) layout.addWidget(self.messages) self.setLayout(layout) return def __handleShowContextMenu(self, coord): """ Show the context menu """ self.__selectAllMenuItem.setEnabled(not self.__isEmpty) self.__copyMenuItem.setEnabled(self.__copyAvailable) self.__clearMenuItem.setEnabled(not self.__isEmpty) self.__menu.popup(QCursor.pos()) return def __appendText(self, txt, isError): " Append the text " if len(txt) == 0: return self.__isEmpty = False cursor = self.messages.textCursor() cursor.movePosition(QTextCursor.End) self.messages.setTextCursor(cursor) if isError: self.messages.setCurrentCharFormat(self.cErrorFormat) else: self.messages.setCurrentCharFormat(self.cNormalFormat) self.messages.insertPlainText(txt) self.messages.insertPlainText('\n') self.messages.ensureCursorVisible() self.__updateToolbarButtons() return def appendMessage(self, txt): " Append the regular message " self.__appendText(txt, False) #QApplication.processEvents() return def appendError(self, txt): " Append the error message " self.__appendText(txt, True) #QApplication.processEvents() return def append(self, txt): " Decides what the message is - error or not - and append it then " if txt.startswith( 'CRITICAL' ) or \ txt.startswith( 'ERROR' ) or \ txt.startswith( 'WARNING' ): self.appendError(txt) else: self.appendMessage(txt) return def __updateToolbarButtons(self): " Contextually updates toolbar buttons " self.selectAllButton.setEnabled(not self.__isEmpty) self.copyButton.setEnabled(self.__copyAvailable) self.clearButton.setEnabled(not self.__isEmpty) return def __clear(self): " Triggers when the clear function is selected " self.__isEmpty = True self.__copyAvailable = False self.messages.clear() self.__updateToolbarButtons() return def __onCopyAvailable(self, isAvailable): " Triggers on the copyAvailable signal " self.__copyAvailable = isAvailable self.__updateToolbarButtons() return def getText(self): " Provides the content as a plain text " return self.messages.toPlainText()
class LogViewer( QWidget ): """ The log (+stdout, +stderr) viewer widget """ def __init__( self, parent = None ): QWidget.__init__( self, parent ) self.__isEmpty = True self.__copyAvailable = False self.clearButton = None self.messages = None self.copyButton = None self.selectAllButton = None self.__createLayout( parent ) # create the context menu self.__menu = QMenu( self ) self.__selectAllMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'selectall.png' ), 'Select All', self.messages.selectAll ) self.__copyMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'copytoclipboard.png' ), 'Copy', self.messages.copy ) self.__menu.addSeparator() self.__clearMenuItem = self.__menu.addAction( PixmapCache().getIcon( 'trash.png' ), 'Clear', self.__clear ) self.messages.setContextMenuPolicy( Qt.CustomContextMenu ) self.messages.customContextMenuRequested.connect( self.__handleShowContextMenu ) self.messages.copyAvailable.connect( self.__onCopyAvailable ) self.cNormalFormat = self.messages.currentCharFormat() self.cErrorFormat = self.messages.currentCharFormat() self.cErrorFormat.setForeground( QBrush( QColor( Qt.red ) ) ) self.__updateToolbarButtons() return def __createLayout( self, parent ): " Helper to create the viewer layout " # Messages list area self.messages = QPlainTextEdit( parent ) self.messages.setLineWrapMode( QPlainTextEdit.NoWrap ) self.messages.setFont( QFont( GlobalData().skin.baseMonoFontFace ) ) self.messages.setReadOnly( True ) self.messages.setMaximumBlockCount( MAX_LINES ) # Default font size is good enough for most of the systems. # 12.0 might be good only in case of the XServer on PC (Xming). # self.messages.setFontPointSize( 12.0 ) # Buttons self.selectAllButton = QAction( PixmapCache().getIcon( 'selectall.png' ), 'Select all', self ) self.selectAllButton.triggered.connect( self.messages.selectAll ) self.copyButton = QAction( PixmapCache().getIcon( 'copytoclipboard.png' ), 'Copy to clipboard', self ) self.copyButton.triggered.connect( self.messages.copy ) spacer = QWidget() spacer.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Expanding ) self.clearButton = QAction( PixmapCache().getIcon( 'trash.png' ), 'Clear all', self ) self.clearButton.triggered.connect( self.__clear ) # Toolbar self.toolbar = QToolBar() self.toolbar.setOrientation( Qt.Vertical ) self.toolbar.setMovable( False ) self.toolbar.setAllowedAreas( Qt.LeftToolBarArea ) self.toolbar.setIconSize( QSize( 16, 16 ) ) self.toolbar.setFixedWidth( 28 ) self.toolbar.setContentsMargins( 0, 0, 0, 0 ) self.toolbar.addAction( self.selectAllButton ) self.toolbar.addAction( self.copyButton ) self.toolbar.addWidget( spacer ) self.toolbar.addAction( self.clearButton ) # layout layout = QHBoxLayout() layout.setContentsMargins( 0, 0, 0, 0 ) layout.setSpacing( 0 ) layout.addWidget( self.toolbar ) layout.addWidget( self.messages ) self.setLayout( layout ) return def __handleShowContextMenu( self, coord ): """ Show the context menu """ self.__selectAllMenuItem.setEnabled( not self.__isEmpty ) self.__copyMenuItem.setEnabled( self.__copyAvailable ) self.__clearMenuItem.setEnabled( not self.__isEmpty ) self.__menu.popup( QCursor.pos() ) return def __appendText( self, txt, isError ): " Append the text " if len( txt ) == 0: return self.__isEmpty = False cursor = self.messages.textCursor() cursor.movePosition( QTextCursor.End ) self.messages.setTextCursor( cursor ) if isError: self.messages.setCurrentCharFormat( self.cErrorFormat ) else: self.messages.setCurrentCharFormat( self.cNormalFormat ) self.messages.insertPlainText( txt ) self.messages.insertPlainText( '\n' ) self.messages.ensureCursorVisible() self.__updateToolbarButtons() return def appendMessage( self, txt ): " Append the regular message " self.__appendText( txt, False ) #QApplication.processEvents() return def appendError( self, txt ): " Append the error message " self.__appendText( txt, True ) #QApplication.processEvents() return def append( self, txt ): " Decides what the message is - error or not - and append it then " if txt.startswith( 'CRITICAL' ) or \ txt.startswith( 'ERROR' ) or \ txt.startswith( 'WARNING' ): self.appendError( txt ) else: self.appendMessage( txt ) return def __updateToolbarButtons( self ): " Contextually updates toolbar buttons " self.selectAllButton.setEnabled( not self.__isEmpty ) self.copyButton.setEnabled( self.__copyAvailable ) self.clearButton.setEnabled( not self.__isEmpty ) return def __clear( self ): " Triggers when the clear function is selected " self.__isEmpty = True self.__copyAvailable = False self.messages.clear() self.__updateToolbarButtons() return def __onCopyAvailable( self, isAvailable ): " Triggers on the copyAvailable signal " self.__copyAvailable = isAvailable self.__updateToolbarButtons() return def getText( self ): " Provides the content as a plain text " return self.messages.toPlainText()
class TagHelpViewer(QWidget): """ The tag help viewer widget """ def __init__(self, parent=None): QWidget.__init__(self, parent) self.__isEmpty = True self.__copyAvailable = False self.__clearButton = None self.__textEdit = None self.__header = None self.__copyButton = None self.__selectAllButton = None self.__createLayout(parent) # create the context menu self.__menu = QMenu(self) self.__selectAllMenuItem = self.__menu.addAction( PixmapCache().getIcon('selectall.png'), 'Select All', self.__textEdit.selectAll) self.__copyMenuItem = self.__menu.addAction( PixmapCache().getIcon('copytoclipboard.png'), 'Copy', self.__textEdit.copy) self.__menu.addSeparator() self.__clearMenuItem = self.__menu.addAction( PixmapCache().getIcon('trash.png'), 'Clear', self.__clear) self.__textEdit.setContextMenuPolicy(Qt.CustomContextMenu) self.__textEdit.customContextMenuRequested.connect( self.__handleShowContextMenu) self.__textEdit.copyAvailable.connect(self.__onCopyAvailable) self.__updateToolbarButtons() return def __createLayout(self, parent): " Helper to create the viewer layout " # __textEdit list area self.__textEdit = QPlainTextEdit(parent) self.__textEdit.setLineWrapMode(QPlainTextEdit.NoWrap) self.__textEdit.setFont(QFont(GlobalData().skin.baseMonoFontFace)) self.__textEdit.setReadOnly(True) # Default font size is good enough for most of the systems. # 12.0 might be good only in case of the XServer on PC (Xming). # self.__textEdit.setFontPointSize( 12.0 ) # Buttons self.__selectAllButton = QAction( PixmapCache().getIcon('selectall.png'), 'Select all', self) self.__selectAllButton.triggered.connect(self.__textEdit.selectAll) self.__copyButton = QAction( PixmapCache().getIcon('copytoclipboard.png'), 'Copy to clipboard', self) self.__copyButton.triggered.connect(self.__textEdit.copy) spacer = QWidget() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.__clearButton = QAction(PixmapCache().getIcon('trash.png'), 'Clear all', self) self.__clearButton.triggered.connect(self.__clear) # Toolbar toolbar = QToolBar() toolbar.setOrientation(Qt.Vertical) toolbar.setMovable(False) toolbar.setAllowedAreas(Qt.LeftToolBarArea) toolbar.setIconSize(QSize(16, 16)) toolbar.setFixedWidth(28) toolbar.setContentsMargins(0, 0, 0, 0) toolbar.addAction(self.__selectAllButton) toolbar.addAction(self.__copyButton) toolbar.addWidget(spacer) toolbar.addAction(self.__clearButton) self.__header = QLabel("Signature: none") self.__header.setFrameStyle(QFrame.StyledPanel) self.__header.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed) self.__header.setAutoFillBackground(True) headerPalette = self.__header.palette() headerBackground = headerPalette.color(QPalette.Background) headerBackground.setRgb(min(headerBackground.red() + 30, 255), min(headerBackground.green() + 30, 255), min(headerBackground.blue() + 30, 255)) headerPalette.setColor(QPalette.Background, headerBackground) self.__header.setPalette(headerPalette) verticalLayout = QVBoxLayout() verticalLayout.setContentsMargins(2, 2, 2, 2) verticalLayout.setSpacing(2) verticalLayout.addWidget(self.__header) verticalLayout.addWidget(self.__textEdit) # layout layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(toolbar) layout.addLayout(verticalLayout) self.setLayout(layout) return def __handleShowContextMenu(self, coord): """ Show the context menu """ self.__selectAllMenuItem.setEnabled(not self.__isEmpty) self.__copyMenuItem.setEnabled(self.__copyAvailable) self.__clearMenuItem.setEnabled(not self.__isEmpty) self.__menu.popup(QCursor.pos()) return def __calltipDisplayable(self, calltip): " True if calltip is displayable " if calltip is None: return False if calltip.strip() == "": return False return True def __docstringDisplayable(self, docstring): " True if docstring is displayable " if docstring is None: return False if isinstance(docstring, dict): if docstring["docstring"].strip() == "": return False return True if docstring.strip() == "": return False return True def display(self, calltip, docstring): " Displays the given help information " calltipDisplayable = self.__calltipDisplayable(calltip) docstringDisplayable = self.__docstringDisplayable(docstring) self.__isEmpty = True if calltipDisplayable or docstringDisplayable: self.__isEmpty = False if calltipDisplayable: if '\n' in calltip: calltip = calltip.split('\n')[0] self.__header.setText("Signature: " + calltip.strip()) else: self.__header.setText("Signature: n/a") self.__textEdit.clear() if docstringDisplayable: if isinstance(docstring, dict): docstring = docstring["docstring"] self.__textEdit.insertPlainText(docstring) self.__updateToolbarButtons() QApplication.processEvents() return def __updateToolbarButtons(self): " Contextually updates toolbar buttons " self.__selectAllButton.setEnabled(not self.__isEmpty) self.__copyButton.setEnabled(self.__copyAvailable) self.__clearButton.setEnabled(not self.__isEmpty) return def __clear(self): " Triggers when the clear function is selected " self.__isEmpty = True self.__copyAvailable = False self.__header.setText("Signature: none") self.__textEdit.clear() self.__updateToolbarButtons() return def __onCopyAvailable(self, isAvailable): " Triggers on the copyAvailable signal " self.__copyAvailable = isAvailable self.__updateToolbarButtons() return