예제 #1
0
class CodeEdit(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self, parent)

        self._text_edit = CodeTextEdit(self)
        self._output_pane = QTextBrowser(self)
        self._output_pane.document().setDefaultFont(QFont('Courier', pointSize=7))
        self._output_pane.setWordWrapMode(QTextOption.NoWrap)

        self._output_pane_container = QWidget(self)
        self._output_pane_layout = QGridLayout(self._output_pane_container)
        self._output_pane_layout.setContentsMargins(0, 16, 0, 0)
        self._output_pane_layout.addWidget(QLabel(self.tr('Script Output')), 0, 0)
        self._output_pane_layout.addWidget(self._output_pane)

        self._splitter = QSplitter(Qt.Vertical, self)

        self._splitter.addWidget(self._text_edit)
        self._splitter.addWidget(self._output_pane_container)
        self._splitter.setStretchFactor(0, 3)
        self._splitter.setStretchFactor(1, 1)

        self._layout = QGridLayout(self)
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.addWidget(self._splitter, 0, 0)

        self._text_edit.editComplete.connect(self.editComplete)
   
    editComplete = pyqtSignal(str)

    @property
    def textEdit(self):
        return self._text_edit
    
    @property
    def outputPane(self):
        return self._output_pane
    
    def setFontSize(self, font_size):
        self._text_edit.document().setDefaultFont(QFont('Courier', pointSize=font_size))
        self._output_pane.document().setDefaultFont(QFont('Courier', pointSize=font_size))
        self._text_edit.setTabStopWidth(font_size * 2)
        self._output_pane.setTabStopWidth(font_size * 2)

    def setModel(self, model):
        self._text_edit.setPlainText(model.text)
        model.textChanged.connect(self._set_text(self._text_edit))
        if hasattr(model, 'output'):
            self._output_pane.setPlainText(model.output)
            model.outputChanged.connect(self._set_text(self._output_pane, True))
            self._output_pane.setVisible(True)
        else:
            self._output_pane_container.setVisible(False)
        self.editComplete.connect(self._handle_text_changed(model))
        model.validationMessageChanged.connect(self._handle_validation_message)
    
    def _set_text(self, widget, scroll_to_end=False):
        def _(text):
            if widget.toPlainText() != text:
                widget.setPlainText(text)
                if scroll_to_end:
                    widget.verticalScrollBar().setSliderPosition(widget.verticalScrollBar().maximum())
        return _

    def _handle_text_changed(self, model):
        def _setter(value):
            model.text = value
        return _setter

    def _handle_validation_message(self, message):
        if message:
            palette = self.palette()
            invalid_color = QColor(Qt.red)
            invalid_color.setAlphaF(0.2)
            palette.setColor(QPalette.Base, invalid_color)
        else:
            palette = self.style().standardPalette()
        self._text_edit.setPalette(palette)
        self._text_edit.setToolTip(message or None)
class PlotToolbarOptions(QWidget):
    def __init__(self,
                 parent,
                 series_style,
                 theme_manager,
                 plot,
                 options=None,
                 legend_control=None,
                 right_padding=0.0,
                 has_extra_tools=False):
        QWidget.__init__(self, parent)
        self._theme_manager = theme_manager
        self._plot = plot
        self._toolbar_container = ToolbarContainer(plot)

        self._background_color_qt = _to_qt_color(
            series_style.get_color_from_key('axes_background'))
        self._foreground_color_qt = _to_qt_color(
            series_style.get_color_from_key('axes_foreground'))
        interpolation = interpolate_rgb(self._background_color_qt,
                                        self._foreground_color_qt, 3)
        self._icon_hover_color = interpolation[1]

        self._toolbar = PlotToolbarWidget(self._toolbar_container, plot,
                                          self._foreground_color_qt,
                                          self._icon_hover_color)
        self._toolbar.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self._layout = QGridLayout(self)
        self._layout.setContentsMargins(0, 0, 0, 0)
        self._layout.setSpacing(0)
        self._layout.addWidget(plot, 0, 0, 1, 3)
        self._background_opacity = 0.8
        plot.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        if options is not None:
            if isinstance(options, PlotOptionsView):
                plot.setOptionsView(options)
            self._options = self._add_popout(ToolType.options, options)
        else:
            self._options = None

        if legend_control is not None:
            if isinstance(legend_control, LegendControlView):
                plot.setLegendControl(legend_control)
            self._legend_control = self._add_popout(ToolType.legend,
                                                    legend_control)
            legend_control.hasHiddenSeriesChanged.connect(
                self._handle_has_hidden_series_changed)
        else:
            self._legend_control = None

        self._toolbar_layout = QVBoxLayout(self._toolbar_container)
        self._toolbar_layout.addWidget(self._toolbar, Qt.AlignTop)

        self._layout.addWidget(self._toolbar_container, 0, 1,
                               Qt.AlignRight | Qt.AlignTop)
        self._layout.setColumnStretch(0, 1)
        self._layout.setColumnStretch(1, 0)
        if right_padding > 0:
            self._padding_widget = QWidget(self)
            self._padding_widget.setVisible(False)
            self._layout.addWidget(self._padding_widget, 0, 2)
            self._layout.setColumnMinimumWidth(2, right_padding)
        else:
            self._padding_widget = None

        if not has_extra_tools:
            self._toolbar_layout.addStretch()

    def _handle_has_hidden_series_changed(self, has_hidden):
        color = None if not has_hidden else self._theme_manager.get_color(
            'highlight')
        self._toolbar.setColor(ToolType.legend, color)

    def _handle_tool_activated(self, tool_type, view):
        def _(tool, active):
            if tool == tool_type:
                view.setVisible(active)
                if self._padding_widget:
                    self._padding_widget.setVisible(active)
                if active:
                    self._toolbar_container.setStyleSheet(
                        "ToolbarContainer {{ background-color: {} }}".format(
                            format_color(self._background_color_qt,
                                         ColorFormat.rgba_string_256,
                                         self._background_opacity)))
                    self._layout.setAlignment(self._toolbar_container,
                                              Qt.AlignRight)
                    if self._padding_widget:
                        self._padding_widget.setStyleSheet(
                            "QWidget {{ background-color: {} }}".format(
                                format_color(self._background_color_qt,
                                             ColorFormat.rgba_string_256,
                                             self._background_opacity)))
                else:
                    self._layout.setAlignment(self._toolbar_container,
                                              Qt.AlignRight | Qt.AlignTop)
                    self._toolbar_container.setStyleSheet("")
                    if self._padding_widget:
                        self._padding_widget.setStyleSheet("")

        return _

    def addTool(self, tool_widget):
        self._toolbar_layout.addWidget(HLine(self._plot), Qt.AlignTop)
        self._toolbar_layout.addWidget(tool_widget,
                                       Qt.AlignTop | Qt.AlignCenter)
        self._toolbar_layout.addStretch()

    @property
    def icon_color(self):
        return self._foreground_color_qt

    @property
    def icon_hover_color(self):
        return self._icon_hover_color

    @property
    def toolbar(self):
        return self._toolbar

    def _add_popout(self, tool_type, view):
        popout = PopoutWidget(self, view, self._background_color_qt,
                              self._foreground_color_qt,
                              self._background_opacity)
        popout.setVisible(False)
        self._layout.addWidget(popout, 0, 0, Qt.AlignRight)
        self._toolbar.toolActivated.connect(
            self._handle_tool_activated(tool_type, popout))
        return popout
예제 #3
0
class MainWidget(QWidget):
    '''
    class MainWidget
    '''
    def __init__(self, parent = None):
        super(MainWidget, self).__init__(parent)

        # member variables
        self._lTheorySpd = 0
        self._rTheorySpd = 0
        self._serialSend = SerialSend()

        # mainWindow properties
        self.setObjectName('MainWidget')
        self.setWindowIcon(QIcon(':/image/default/app.icon'))
        self.setWindowTitle('%s V%s' % (
                            qApp.applicationDisplayName(),
                            qApp.applicationVersion()))
        self.resize(800, 480)

        # mainWindow layout

        # top

        self.groupBoxTop = QGroupBox(self)
        self.groupBoxTop.setObjectName('groupBoxTop')

        # command dashboard
        buttonLeftPower = JSwitchButton(parent = self.groupBoxTop)
        buttonRightPower = JSwitchButton(parent = self.groupBoxTop)
        buttonSettings = QPushButton(self.groupBoxTop)
        buttonHistory = QPushButton(self.groupBoxTop)
        buttonQuit = QPushButton(self.groupBoxTop)

        buttonLeftPower.setObjectName('buttonLeftPower')
        buttonRightPower.setObjectName('buttonRightPower')
        buttonSettings.setObjectName('buttonSettings')
        buttonHistory.setObjectName('buttonHistory')
        buttonQuit.setObjectName('buttonQuit')

        areaPortState = QWidget(self)
        areaPortState.setObjectName('areaPortState')
        areaPortState.setStyleSheet('QWidget#areaPortState{border-radius:3px;'
                                    'border:1px solid #505050;'
                                    'background-color:rgba(64,64,64,50);}')
        vertLayoutPortState = QVBoxLayout(areaPortState)
        vertLayoutPortState.setContentsMargins(50, 2, 50, 2)
        vertLayoutPortState.setSpacing(3)

        buttonPortState = JSwitchButton(pixmap = QPixmap(':/carmonitor/image/button-port-state.png'), parent = areaPortState)
        buttonPortState.setObjectName('buttonPortState')
        vertLayoutPortState.addWidget(QLabel('串口', areaPortState), 0, Qt.AlignHCenter)
        vertLayoutPortState.addWidget(buttonPortState)

        #
        horiLayoutTop = QHBoxLayout(self.groupBoxTop)
        horiLayoutTop.setContentsMargins(0, 0, 0, 0)
        horiLayoutTop.addSpacing(25)
        horiLayoutTop.addWidget(buttonSettings, 0, Qt.AlignLeft)
        horiLayoutTop.addSpacing(20)
        horiLayoutTop.addWidget(buttonHistory, 0, Qt.AlignLeft)
        horiLayoutTop.addSpacing(65)
        horiLayoutTop.addWidget(buttonLeftPower)
        horiLayoutTop.addWidget(QLabel('左电源开关', self.groupBoxTop))
        horiLayoutTop.addStretch()
        horiLayoutTop.addWidget(areaPortState, 0, Qt.AlignTop)
        horiLayoutTop.addStretch()
        horiLayoutTop.addWidget(QLabel('右电源开关', self.groupBoxTop))
        horiLayoutTop.addWidget(buttonRightPower)
        horiLayoutTop.addSpacing(150)
        horiLayoutTop.addWidget(buttonQuit, 0, Qt.AlignRight)
        horiLayoutTop.addSpacing(25)

        # middle

        # curves
        self.curveLBP = CurveWidget(title = '左刹车压力(MPa)', parent = self)
        self.curveLRP = CurveWidget(title = '左转速(r/min)', parent = self)
        self.curveRBP = CurveWidget(title = '右刹车压力(MPa)', parent = self)
        self.curveRRP = CurveWidget(title = '右转速(r/min)', parent = self)

        self.curveLBP.setObjectName('curveLBP')
        self.curveLRP.setObjectName('curveLRP')
        self.curveRBP.setObjectName('curveRBP')
        self.curveRRP.setObjectName('curveRRP')

        # self.curveLBP.setAxisScale(QwtPlot.yLeft, 0, 30, 5)

        # areaMiddle
        self.areaMiddle = QWidget(self)
        self.areaMiddle.setObjectName('areaMiddle')
        self.areaMiddle.setFixedWidth(280)

        #
        groupBoxStatus = QGroupBox(self)
        groupBoxStatus.setObjectName('groupBoxStatus')

        # status-view
        gridLayoutStatus = QGridLayout(groupBoxStatus)
        gridLayoutStatus.setContentsMargins(5, 5, 5, 5)
        gridLayoutStatus.setHorizontalSpacing(8)
        gridLayoutStatus.setVerticalSpacing(3)

        # Brake-Command
        editLeftBrakeCmd = QLineEdit(groupBoxStatus)
        editRightBrakeCmd = QLineEdit(groupBoxStatus)
        editLeftBrakeCmd.setObjectName('editLeftBrakeCmd')
        editRightBrakeCmd.setObjectName('editRightBrakeCmd')
        editLeftBrakeCmd.setReadOnly(True)
        editRightBrakeCmd.setReadOnly(True)
        gridLayoutStatus.addWidget(QLabel('刹车指令:', groupBoxStatus),
                                   0, 0, 1, 2, Qt.AlignCenter)
        gridLayoutStatus.addWidget(editLeftBrakeCmd, 1, 0, 1, 1)
        gridLayoutStatus.addWidget(editRightBrakeCmd, 1, 1, 1, 1)

        # Major Brake Pressure
        self.editMLeftBrakeP = QLineEdit(groupBoxStatus)
        self.editMRightBrakeP = QLineEdit(groupBoxStatus)
        self.editMLeftBrakeP.setObjectName('editMLeftBrakeP')
        self.editMRightBrakeP.setObjectName('editMRightBrakeP')
        self.editMLeftBrakeP.setReadOnly(True)
        self.editMRightBrakeP.setReadOnly(True)
        gridLayoutStatus.addWidget(QLabel('主刹车压力:', groupBoxStatus),
                                   2, 0, 1, 2, Qt.AlignCenter)
        gridLayoutStatus.addWidget(self.editMLeftBrakeP, 3, 0, 1, 1)
        gridLayoutStatus.addWidget(self.editMRightBrakeP, 3, 1, 1, 1)

        # Assistant Brake Pressure
        self.editALeftBrakeP = QLineEdit(groupBoxStatus)
        self.editARightBrakeP = QLineEdit(groupBoxStatus)
        self.editALeftBrakeP.setObjectName('editALeftBrakeP')
        self.editARightBrakeP.setObjectName('editARightBrakeP')
        self.editALeftBrakeP.setReadOnly(True)
        self.editARightBrakeP.setReadOnly(True)
        gridLayoutStatus.addWidget(QLabel('副刹车压力:', groupBoxStatus),
                                   4, 0, 1, 2, Qt.AlignCenter)
        gridLayoutStatus.addWidget(self.editALeftBrakeP, 5, 0, 1, 1)
        gridLayoutStatus.addWidget(self.editARightBrakeP, 5, 1, 1, 1)

        # Rotation Rate
        self.editLeftRotateRate = QLineEdit(groupBoxStatus)
        self.editRightRotateRate = QLineEdit(groupBoxStatus)
        self.editLeftRotateRate.setObjectName('editLeftRotateRate')
        self.editRightRotateRate.setObjectName('editRightRotateRate')
        gridLayoutStatus.addWidget(QLabel('实际转速:', groupBoxStatus),
                                   6, 0, 1, 2, Qt.AlignCenter)
        gridLayoutStatus.addWidget(self.editLeftRotateRate, 7, 0, 1, 1)
        gridLayoutStatus.addWidget(self.editRightRotateRate, 7, 1, 1, 1)

        # Theory Rotation Rate
        self.editTheoryLeftRotateRate = QLineEdit(groupBoxStatus)
        self.editTheoryRightRotateRate = QLineEdit(groupBoxStatus)
        self.editTheoryLeftRotateRate.setObjectName('editTheoryLeftRotateRate')
        self.editTheoryRightRotateRate.setObjectName('editTheoryRightRotateRate')
        gridLayoutStatus.addWidget(QLabel('理论转速:', groupBoxStatus),
                                   8, 0, 1, 2, Qt.AlignCenter)
        gridLayoutStatus.addWidget(self.editTheoryLeftRotateRate, 9, 0, 1, 1)
        gridLayoutStatus.addWidget(self.editTheoryRightRotateRate, 9, 1, 1, 1)

        #
        groupBoxCtrl = QGroupBox(self)
        groupBoxCtrl.setObjectName('groupBoxCtrl')

        # status-view
        gridLayoutCtrl = QGridLayout(groupBoxCtrl)
        gridLayoutCtrl.setContentsMargins(5, 5, 5, 5)
        gridLayoutCtrl.setSpacing(20)

        # left-button
        buttonLeftDashboard = JDashButton('左指令旋钮', groupBoxCtrl)
        buttonLeftSpeedGain = JDashButton('左转速增益', groupBoxCtrl)
        buttonLeftSpeedKnob = JDashButton('左转速增益', groupBoxCtrl)
        buttonLeftTracksip = JTracksipButton(parent = groupBoxCtrl)
        buttonLeftDashboard.setObjectName('buttonLeftDashboard')
        buttonLeftSpeedGain.setObjectName('buttonLeftSpeedGain')
        buttonLeftSpeedKnob.setObjectName('buttonLeftSpeedKnob')
        buttonLeftTracksip.setObjectName('buttonLeftTracksip')
        buttonLeftTracksip.setFixedSize(110, 45)

        # right-button
        buttonRightDashboard = JDashButton('右指令旋钮', groupBoxCtrl)
        buttonRightSpeedGain = JDashButton('右转速增益', groupBoxCtrl)
        buttonRightSpeedKnob = JDashButton('右转速增益', groupBoxCtrl)
        buttonRightTracksip = JTracksipButton(parent = groupBoxCtrl)
        buttonRightDashboard.setObjectName('buttonRightDashboard')
        buttonRightSpeedGain.setObjectName('buttonRightSpeedGain')
        buttonRightSpeedKnob.setObjectName('buttonRightSpeedKnob')
        buttonRightTracksip.setObjectName('buttonRightTracksip')
        buttonRightTracksip.setFixedSize(110, 45)

        horiLayoutTracksip = QHBoxLayout()
        horiLayoutTracksip.setContentsMargins(0, 0, 0, 0)
        horiLayoutTracksip.setSpacing(5)
        horiLayoutTracksip.addWidget(buttonLeftTracksip)
        horiLayoutTracksip.addWidget(QLabel('打滑', self), 0, Qt.AlignHCenter)
        horiLayoutTracksip.addWidget(buttonRightTracksip)
        gridLayoutCtrl.addLayout(horiLayoutTracksip, 0, 0, 1, 2)

        horiLayoutDashboard = QHBoxLayout()
        horiLayoutDashboard.setContentsMargins(0, 0, 0, 0)
        horiLayoutDashboard.setSpacing(5)
        horiLayoutDashboard.addWidget(buttonLeftDashboard)
        horiLayoutDashboard.addWidget(QLabel('    ', self), 0, Qt.AlignHCenter)
        horiLayoutDashboard.addWidget(buttonRightDashboard)
        gridLayoutCtrl.addLayout(horiLayoutDashboard, 1, 0, 1, 2)

        horiLayoutSpeedGain = QHBoxLayout()
        horiLayoutSpeedGain.setContentsMargins(0, 0, 0, 0)
        horiLayoutSpeedGain.setSpacing(5)
        horiLayoutSpeedGain.addWidget(buttonLeftSpeedGain)
        horiLayoutSpeedGain.addWidget(QLabel('(粗调)', self), 0, Qt.AlignHCenter)
        horiLayoutSpeedGain.addWidget(buttonRightSpeedGain)
        gridLayoutCtrl.addLayout(horiLayoutSpeedGain, 2, 0, 1, 2)


        horiLayoutSpeedKnob = QHBoxLayout()
        horiLayoutSpeedKnob.setContentsMargins(0, 0, 0, 0)
        horiLayoutSpeedKnob.setSpacing(5)
        horiLayoutSpeedKnob.addWidget(buttonLeftSpeedKnob)
        horiLayoutSpeedKnob.addWidget(QLabel('(细调)', self), 0, Qt.AlignHCenter)
        horiLayoutSpeedKnob.addWidget(buttonRightSpeedKnob)
        gridLayoutCtrl.addLayout(horiLayoutSpeedKnob, 3, 0, 1, 2)

        #
        vertLayoutMid = QVBoxLayout(self.areaMiddle)
        vertLayoutMid.setContentsMargins(0, 0, 0, 0)
        vertLayoutMid.setSpacing(0)
        vertLayoutMid.addWidget(groupBoxStatus)
        vertLayoutMid.addWidget(groupBoxCtrl)
        vertLayoutMid.addSpacing(20)

        #
        gridLayoutBottom = QGridLayout()
        gridLayoutBottom.setContentsMargins(0, 0, 0, 0)
        gridLayoutBottom.setSpacing(1)
        gridLayoutBottom.addWidget(self.curveLBP, 0, 0, 1, 1)
        gridLayoutBottom.addWidget(self.curveLRP, 1, 0, 1, 1)
        gridLayoutBottom.addWidget(self.areaMiddle, 0, 1, 2, 1)
        gridLayoutBottom.addWidget(self.curveRBP, 0, 2, 1, 1)
        gridLayoutBottom.addWidget(self.curveRRP, 1, 2, 1, 1)

        # main-layout
        vertLayoutMain = QVBoxLayout(self)
        vertLayoutMain.setContentsMargins(5, 5, 5, 5)
        vertLayoutMain.addWidget(self.groupBoxTop)
        vertLayoutMain.addLayout(gridLayoutBottom)

        # global properties
        qApp.setProperty('MainWidget', self)
        self._serialProxy = SerialPortProxy(self)
        self._serialProxy._serialSimulate = SerialSimulate(self._serialProxy)  #
        qApp.setProperty('SerialProxy', self._serialProxy)

        #
        buttonSettings.clicked.connect(self.onButtonSettingsClicked)
        buttonHistory.clicked.connect(self.onButtonHistoryClicked)
        buttonPortState.clicked.connect(self.onButtonPortStateClicked)
        buttonQuit.clicked.connect(self.onButtonQuitClicked)

        # curves
        self.curveLBP.doubleClicked.connect(self.onCurveDoubleClicked)
        self.curveLRP.doubleClicked.connect(self.onCurveDoubleClicked)
        self.curveRBP.doubleClicked.connect(self.onCurveDoubleClicked)
        self.curveRRP.doubleClicked.connect(self.onCurveDoubleClicked)

        # switch-power
        buttonLeftPower.stateChanged.connect(self.onButtonLeftPowerStateChanged)
        buttonRightPower.stateChanged.connect(self.onButtonRightPowerStateChanged)

        # switch-tracksip
        buttonLeftTracksip.stateChanged.connect(self.onButtonLeftTracksipStateChanged)
        buttonRightTracksip.stateChanged.connect(self.onButtonRightTracksipStateChanged)

        self._serialProxy.stateChanged.connect(self.onSerialStateChanged)
        self._serialProxy.serialPortError.connect(self.onSerialPortError)
        self._serialProxy.displayRespond.connect(self.onSerialDisplayRespond)

        #
        buttonLeftSpeedGain.clicked.connect(self.execSliderWidget)
        buttonLeftSpeedKnob.clicked.connect(self.execSliderWidget)
        buttonRightSpeedGain.clicked.connect(self.execSliderWidget)
        buttonRightSpeedKnob.clicked.connect(self.execSliderWidget)

        # final initialization

        self.editMLeftBrakeP.setText('0 MPa')
        self.editMRightBrakeP.setText('0 MPa')
        self.editALeftBrakeP.setText('0 MPa')
        self.editARightBrakeP.setText('0 MPa')

        self.editLeftRotateRate.setText('0 r/min')
        self.editRightRotateRate.setText('0 r/min')
        self.editTheoryLeftRotateRate.setText('0 r/min')
        self.editTheoryRightRotateRate.setText('0 r/min')

        #
        c_memset(self._serialSend, 0, ctypes.sizeof(self._serialSend))

        # SQL
        sqlName = applicationDirPath() \
            + '/../data/cm-' \
            + QDateTime.currentDateTime().toLocalTime().toString('yyyy-MM-dd-HH-mm-ss') \
            + '.db'
        if not DatabaseMgr().create(sqlName):
            assert(False)

        # start serialport
        self._serialProxy.start()

        #
        buttonLeftTracksip.setState(self._serialSend.ctrlWord.lTracksip)
        buttonRightTracksip.setState(self._serialSend.ctrlWord.lTracksip)

    def onButtonSettingsClicked(self):
        self._serialProxy.save()
        #
        settingsWidget = SettingsWidget(self)
        settingsWidget.exec_()

        self._serialProxy.restore()

    def onButtonHistoryClicked(self):
        self._serialProxy.save()
        DatabaseMgr().save()
        #
        historyWidget = HistoryWidget(self)
        historyWidget.showMaximized()
        historyWidget.exec_()

        DatabaseMgr().restore()
        self._serialProxy.restore()

    def onButtonPortStateClicked(self, checked):
        if checked:
            self._serialProxy.start()
        else:
            self._serialProxy.stop()

    def onButtonQuitClicked(self):
        if QMessageBox.warning(self, '警告', '你确定要退出软件吗?',
                               QMessageBox.Ok | QMessageBox.No) == QMessageBox.Ok:
            self.close()

    def onCurveDoubleClicked(self, checked):
        objectName = self.sender().objectName()
        if objectName == 'curveLBP':
            self.groupBoxTop.setVisible(checked)
            self.areaMiddle.setVisible(checked)
            self.curveLRP.setVisible(checked)
            self.curveRBP.setVisible(checked)
            self.curveRRP.setVisible(checked)
        elif objectName == 'curveLRP':
            self.groupBoxTop.setVisible(checked)
            self.areaMiddle.setVisible(checked)
            self.curveLBP.setVisible(checked)
            self.curveRBP.setVisible(checked)
            self.curveRRP.setVisible(checked)
        elif objectName == 'curveRBP':
            self.groupBoxTop.setVisible(checked)
            self.areaMiddle.setVisible(checked)
            self.curveLBP.setVisible(checked)
            self.curveLRP.setVisible(checked)
            self.curveRRP.setVisible(checked)
        elif objectName == 'curveRRP':
            self.groupBoxTop.setVisible(checked)
            self.areaMiddle.setVisible(checked)
            self.curveLBP.setVisible(checked)
            self.curveLRP.setVisible(checked)
            self.curveRBP.setVisible(checked)

    def onButtonLeftPowerStateChanged(self, checked):
        self._serialSend.ctrlWord.lPowerSw = checked
        self._serialSend.sum = SerialPortProxy.serialPortSendSum(self._serialSend)
        self._serialProxy.writeData(self._serialSend)

    def onButtonRightPowerStateChanged(self, checked):
        self._serialSend.ctrlWord.rPowerSw = checked
        self._serialSend.sum = SerialPortProxy.serialPortSendSum(self._serialSend)
        self._serialProxy.writeData(self._serialSend)

    def onButtonLeftTracksipStateChanged(self, checked):
        self._serialSend.ctrlWord.lTracksip = checked
        self._serialSend.sum = SerialPortProxy.serialPortSendSum(self._serialSend)
        self._serialProxy.writeData(self._serialSend)

    def onButtonRightTracksipStateChanged(self, checked):
        self._serialSend.ctrlWord.rTracksip = checked
        self._serialSend.sum = SerialPortProxy.serialPortSendSum(self._serialSend)
        self._serialProxy.writeData(self._serialSend)

    def onSerialStateChanged(self, info):
        text = '串口: [%s] %s' % (self._serialProxy.config().__str__(), info)
        print(text)

    def onSerialDisplayRespond(self, data, dateTime):
        # Major Brake Pressure
        suffix = self.editMLeftBrakeP.text().split(' ')[1]
        self.editMLeftBrakeP.setText('%.2f %s' % (data.lMBrakeP * 1.0, suffix))
        suffix = self.editMRightBrakeP.text().split(' ')[1]
        self.editMRightBrakeP.setText('%.2f %s' % (data.rMBrakeP * 1.0, suffix))
        # Minor Brake Pressure
        suffix = self.editALeftBrakeP.text().split(' ')[1]
        self.editALeftBrakeP.setText('%.2f %s' % (data.lABrakeP * 1.0, suffix))
        suffix = self.editARightBrakeP.text().split(' ')[1]
        self.editARightBrakeP.setText('%.2f %s' % (data.rABrakeP * 1.0, suffix))
        # Rotation Rate
        suffix = self.editLeftRotateRate.text().split(' ')[1]
        self.editLeftRotateRate.setText('%d %s' % (data.lWheelSpd * 1.0, suffix))
        suffix = self.editRightRotateRate.text().split(' ')[1]
        self.editRightRotateRate.setText('%d %s' % (data.rWheelSpd * 1.0, suffix))

        # curves
        timeT = dateTime.toMSecsSinceEpoch()

        # curve - LBP
        self.curveLBP.curve(0).sheft(QPoint(timeT, data.lMBrakeP))
        self.curveLBP.curve(1).sheft(QPoint(timeT, data.lABrakeP))
        # curve - LRP
        self.curveLRP.curve(0).sheft(QPoint(timeT, data.lWheelSpd))
        self.curveLRP.curve(1).sheft(QPoint(timeT, self._lTheorySpd))
        # curve - RBP
        self.curveRBP.curve(0).sheft(QPoint(timeT, data.rMBrakeP))
        self.curveRBP.curve(1).sheft(QPoint(timeT, data.rABrakeP))
        # curve - RRP
        self.curveRRP.curve(0).sheft(QPoint(timeT, data.rWheelSpd))
        self.curveRRP.curve(1).sheft(QPoint(timeT, self._rTheorySpd))

        if not DatabaseMgr().write(data, self._lTheorySpd, self._rTheorySpd, timeT):
            assert(False)

    def onSerialPortError(self, error, info):
        buttonPortState = self.findChild(JSwitchButton, 'buttonPortState')
        if not buttonPortState:
            return
        if error == QSerialPort.NoError:
            buttonPortState.setState(True)
        else:
            buttonPortState.setState(False)
        text = '串口: [%s] %s' % (self._serialProxy.config().__str__(), info)
        print(text)

    def execSliderWidget(self):
        sliderWidget = SliderWidget(self.sender().text(), self)
        objName = self.sender().objectName()
        if objName == 'buttonLeftSpeedGain':
            lineEdit = self.findChild(QLineEdit, 'editTheoryLeftRotateRate')
            text = lineEdit.text().split(' ')
            suffix = ' ' + text[1]
            curValue = float(text[0])
            sliderWidget.setRange(0, 3000)
            # sliderWidget.setDecimals(2)
            # sliderWidget.setSingleStep(0.01)
            sliderWidget.setSuffix(suffix)
            sliderWidget.setValue(curValue)

            def valueChanged(value):
                self._lTheorySpd = value
                buttonLeftSpeedSwitch = self.findChild(QPushButton, 'buttonLeftSpeedSwitch')
                if buttonLeftSpeedSwitch:
                    buttonLeftSpeedSwitch.setText('左转速关' if value == 0.0 else '左转速开');
                lineEdit.setText(('%.2f' % value) + suffix)

                # send
                self._serialSend.index += 1
                self._serialSend.lWheelSpd = int(value * 42.94967296)
                self._serialSend.sum = SerialPortProxy.serialPortSendSum(self._serialSend)
                self._serialProxy.writeData(self._serialSend)

            sliderWidget.valueChanged.connect(valueChanged)

        elif objName == 'buttonRightSpeedGain':
            lineEdit = self.findChild(QLineEdit, 'editTheoryRightRotateRate')
            text = lineEdit.text().split(' ')
            suffix = ' ' + text[1]
            curValue = float(text[0])
            sliderWidget.setRange(0, 3000)
            # sliderWidget.setDecimals(2)
            # sliderWidget.setSingleStep(0.01)
            sliderWidget.setSuffix(suffix)
            sliderWidget.setValue(curValue)

            def valueChanged(value):
                self._rTheorySpd = value
                buttonRightSpeedSwitch = self.findChild(QPushButton, 'buttonRightSpeedSwitch')
                if buttonRightSpeedSwitch:
                    buttonRightSpeedSwitch.setText('右转速关' if value == 0.0 else '右转速开')
                lineEdit.setText(('%.2f' % value) + suffix)

                # send
                self._serialSend.index += 1
                self._serialSend.rWheelSpd = int(value * 42.94967296)
                self._serialSend.sum = SerialPortProxy.serialPortSendSum(self._serialSend)
                self._serialProxy.writeData(self._serialSend)

            sliderWidget.valueChanged.connect(valueChanged)

        elif objName == 'buttonLeftSpeedKnob':
            lineEdit = self.findChild(QLineEdit, 'editTheoryLeftRotateRate')
            text = lineEdit.text().split(' ')
            suffix = ' ' + text[1]
            curValue = float(text[0])
            minValue = max(0, curValue - 50)
            maxValue = min(3000, curValue + 50)
            if maxValue < 100:
                maxValue = minValue + 100
            if minValue > 3000 - 100:
                minValue = maxValue - 100
            sliderWidget.setRange(minValue, maxValue)
            # sliderWidget.setDecimals(2)
            # sliderWidget.setSingleStep(0.01)
            sliderWidget.setSuffix(suffix)
            sliderWidget.setValue(curValue)

            def valueChanged(value):
                self._lTheorySpd = value
                buttonLeftSpeedSwitch = self.findChild(QPushButton, 'buttonLeftSpeedSwitch')
                if buttonLeftSpeedSwitch:
                    buttonLeftSpeedSwitch.setText('左转速关' if value == 0.0 else '左转速开')
                lineEdit.setText(('%.2f' % value) + suffix)

                # send
                self._serialSend.index += 1
                self._serialSend.lWheelSpd = int(value * 42.94967296)
                self._serialSend.sum = SerialPortProxy.serialPortSendSum(self._serialSend)
                self._serialProxy.writeData(self._serialSend)

            sliderWidget.valueChanged.connect(valueChanged)

        elif objName == 'buttonRightSpeedKnob':
            lineEdit = self.findChild(QLineEdit, 'editTheoryRightRotateRate')
            text = lineEdit.text().split(' ')
            suffix = ' ' + text[1]
            curValue = float(text[0])
            minValue = max(0, curValue - 50)
            maxValue = min(3000, curValue + 50)
            if maxValue < 100:
                maxValue = minValue + 100
            if minValue > 3000 - 100:
                minValue = maxValue - 100
            sliderWidget.setRange(minValue, maxValue)
            # sliderWidget.setDecimals(2)
            # sliderWidget.setSingleStep(0.01)
            sliderWidget.setSuffix(suffix)
            sliderWidget.setValue(curValue)

            def valueChanged(value):
                self._rTheorySpd = value
                buttonRightSpeedSwitch = self.findChild(QPushButton, 'buttonRightSpeedSwitch')
                if buttonRightSpeedSwitch:
                    buttonRightSpeedSwitch.setText('右转速关' if value == 0.0 else '右转速开');
                lineEdit.setText(('%.2f' % value) + suffix)

                # send
                self._serialSend.index += 1
                self._serialSend.rWheelSpd = int(value * 42.94967296)
                self._serialSend.sum = SerialPortProxy.serialPortSendSum(self._serialSend)
                self._serialProxy.writeData(self._serialSend)

            sliderWidget.valueChanged.connect(valueChanged)

        else:
            pass

        sliderWidget.exec_()