コード例 #1
0
    def __init__(self, metadata, parent=None):
        QDialog.__init__(self, parent=parent)

        self.setWindowFlags(Qt.Window)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Close)

        origbrowser = QTextBrowser()
        origbrowser.setText('')
        origbrowser.setReadOnly(True)

        browser = QTextBrowser()
        browser.setText('')
        browser.setReadOnly(True)

        gpbox2 = QGroupBox('Metadata: Original')
        lay2 = QHBoxLayout()
        gpbox2.setLayout(lay2)
        lay2.addWidget(origbrowser)

        gpbox4 = QGroupBox('Metadata: After scrambling')
        lay4 = QHBoxLayout()
        gpbox4.setLayout(lay4)
        lay4.addWidget(browser)

        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(gpbox2)
        splitter.addWidget(gpbox4)
        splitter.setMinimumHeight(500)
        splitter.setMinimumWidth(1000)

        lay = QVBoxLayout()
        self.setLayout(lay)
        lay.addWidget(splitter)
        lay.addWidget(buttonBox)

        # create connect signals/slots
        buttonBox.rejected.connect(self.reject)

        metaorig = metadata.get('orig', '')
        metaorig = re.sub(r'\n\s*', r'\n     ', metaorig)
        origbrowser.setText(metaorig)
        browser.setText(metadata.get('scramb', ''))

        self.setWindowTitle('%s: Metadata' % CAPTION)
        if not 'scramb' in metadata:
            gpbox4.setVisible(False)
コード例 #2
0
ファイル: unpack_book.py プロジェクト: AtulKumar2/calibre
class UnpackBook(QDialog):

    def __init__(self, parent, book_id, fmts, db):
        QDialog.__init__(self, parent)
        self.setWindowIcon(QIcon(I('unpack-book.png')))
        self.book_id, self.fmts, self.db_ref = book_id, fmts, weakref.ref(db)
        self._exploded = None
        self._cleanup_dirs = []
        self._cleanup_files = []

        self.setup_ui()
        self.setWindowTitle(_('Unpack Book') + ' - ' + db.title(book_id,
            index_is_id=True))

        button = self.fmt_choice_buttons[0]
        button_map = {unicode(x.text()):x for x in self.fmt_choice_buttons}
        of = prefs['output_format'].upper()
        df = tweaks.get('default_tweak_format', None)
        lf = gprefs.get('last_tweak_format', None)
        if df and df.lower() == 'remember' and lf in button_map:
            button = button_map[lf]
        elif df and df.upper() in button_map:
            button = button_map[df.upper()]
        elif of in button_map:
            button = button_map[of]
        button.setChecked(True)

        self.init_state()
        for button in self.fmt_choice_buttons:
            button.toggled.connect(self.init_state)

    def init_state(self, *args):
        self._exploded = None
        self.preview_button.setEnabled(False)
        self.rebuild_button.setEnabled(False)
        self.explode_button.setEnabled(True)

    def setup_ui(self):  # {{{
        self._g = g = QHBoxLayout(self)
        self.setLayout(g)
        self._l = l = QVBoxLayout()
        g.addLayout(l)

        fmts = sorted(x.upper() for x in self.fmts)
        self.fmt_choice_box = QGroupBox(_('Choose the format to unpack:'), self)
        self._fl = fl = QHBoxLayout()
        self.fmt_choice_box.setLayout(self._fl)
        self.fmt_choice_buttons = [QRadioButton(y, self) for y in fmts]
        for x in self.fmt_choice_buttons:
            fl.addWidget(x, stretch=10 if x is self.fmt_choice_buttons[-1] else
                    0)
        l.addWidget(self.fmt_choice_box)
        self.fmt_choice_box.setVisible(len(fmts) > 1)

        self.help_label = QLabel(_('''\
            <h2>About Unpack Book</h2>
            <p>Unpack Book allows you to fine tune the appearance of an ebook by
            making small changes to its internals. In order to use Unpack Book,
            you need to know a little bit about HTML and CSS, technologies that
            are used in ebooks. Follow the steps:</p>
            <br>
            <ol>
            <li>Click "Explode Book": This will "explode" the book into its
            individual internal components.<br></li>
            <li>Right click on any individual file and select "Open with..." to
            edit it in your favorite text editor.<br></li>
            <li>When you are done: <b>close the file browser window
            and the editor windows you used to make your tweaks</b>. Then click
            the "Rebuild Book" button, to update the book in your calibre
            library.</li>
            </ol>'''))
        self.help_label.setWordWrap(True)
        self._fr = QFrame()
        self._fr.setFrameShape(QFrame.VLine)
        g.addWidget(self._fr)
        g.addWidget(self.help_label)

        self._b = b = QGridLayout()
        left, top, right, bottom = b.getContentsMargins()
        top += top
        b.setContentsMargins(left, top, right, bottom)
        l.addLayout(b, stretch=10)

        self.explode_button = QPushButton(QIcon(I('wizard.png')), _('&Explode Book'))
        self.preview_button = QPushButton(QIcon(I('view.png')), _('&Preview Book'))
        self.cancel_button  = QPushButton(QIcon(I('window-close.png')), _('&Cancel'))
        self.rebuild_button = QPushButton(QIcon(I('exec.png')), _('&Rebuild Book'))

        self.explode_button.setToolTip(
                _('Explode the book to edit its components'))
        self.preview_button.setToolTip(
                _('Preview the result of your changes'))
        self.cancel_button.setToolTip(
                _('Abort without saving any changes'))
        self.rebuild_button.setToolTip(
            _('Save your changes and update the book in the calibre library'))

        a = b.addWidget
        a(self.explode_button, 0, 0, 1, 1)
        a(self.preview_button, 0, 1, 1, 1)
        a(self.cancel_button,  1, 0, 1, 1)
        a(self.rebuild_button, 1, 1, 1, 1)

        for x in ('explode', 'preview', 'cancel', 'rebuild'):
            getattr(self, x+'_button').clicked.connect(getattr(self, x))

        self.msg = QLabel('dummy', self)
        self.msg.setVisible(False)
        self.msg.setStyleSheet('''
        QLabel {
            text-align: center;
            background-color: white;
            color: black;
            border-width: 1px;
            border-style: solid;
            border-radius: 20px;
            font-size: x-large;
            font-weight: bold;
        }
        ''')

        self.resize(self.sizeHint() + QSize(40, 10))
    # }}}

    def show_msg(self, msg):
        self.msg.setText(msg)
        self.msg.resize(self.size() - QSize(50, 25))
        self.msg.move((self.width() - self.msg.width())//2,
                (self.height() - self.msg.height())//2)
        self.msg.setVisible(True)

    def hide_msg(self):
        self.msg.setVisible(False)

    def explode(self):
        self.show_msg(_('Exploding, please wait...'))
        if len(self.fmt_choice_buttons) > 1:
            gprefs.set('last_tweak_format', self.current_format.upper())
        QTimer.singleShot(5, self.do_explode)

    def ask_question(self, msg):
        return question_dialog(self, _('Are you sure?'), msg)

    def do_explode(self):
        from calibre.ebooks.tweak import get_tools, Error, WorkerError
        tdir = PersistentTemporaryDirectory('_tweak_explode')
        self._cleanup_dirs.append(tdir)
        det_msg = None
        try:
            src = self.db.format(self.book_id, self.current_format,
                    index_is_id=True, as_path=True)
            self._cleanup_files.append(src)
            exploder = get_tools(self.current_format)[0]
            opf = exploder(src, tdir, question=self.ask_question)
        except WorkerError as e:
            det_msg = e.orig_tb
        except Error as e:
            return error_dialog(self, _('Failed to unpack'),
                (_('Could not explode the %s file.')%self.current_format) + ' '
                + as_unicode(e), show=True)
        except:
            import traceback
            det_msg = traceback.format_exc()
        finally:
            self.hide_msg()

        if det_msg is not None:
            return error_dialog(self, _('Failed to unpack'),
                _('Could not explode the %s file. Click "Show Details" for '
                    'more information.')%self.current_format, det_msg=det_msg,
                show=True)

        if opf is None:
            # The question was answered with No
            return

        self._exploded = tdir
        self.explode_button.setEnabled(False)
        self.preview_button.setEnabled(True)
        self.rebuild_button.setEnabled(True)
        open_local_file(tdir)

    def rebuild_it(self):
        from calibre.ebooks.tweak import get_tools, WorkerError
        src_dir = self._exploded
        det_msg = None
        of = PersistentTemporaryFile('_tweak_rebuild.'+self.current_format.lower())
        of.close()
        of = of.name
        self._cleanup_files.append(of)
        try:
            rebuilder = get_tools(self.current_format)[1]
            rebuilder(src_dir, of)
        except WorkerError as e:
            det_msg = e.orig_tb
        except:
            import traceback
            det_msg = traceback.format_exc()
        finally:
            self.hide_msg()

        if det_msg is not None:
            error_dialog(self, _('Failed to rebuild file'),
                    _('Failed to rebuild %s. For more information, click '
                        '"Show details".')%self.current_format,
                    det_msg=det_msg, show=True)
            return None

        return of

    def preview(self):
        self.show_msg(_('Rebuilding, please wait...'))
        QTimer.singleShot(5, self.do_preview)

    def do_preview(self):
        rebuilt = self.rebuild_it()
        if rebuilt is not None:
            self.parent().iactions['View']._view_file(rebuilt)

    def rebuild(self):
        self.show_msg(_('Rebuilding, please wait...'))
        QTimer.singleShot(5, self.do_rebuild)

    def do_rebuild(self):
        rebuilt = self.rebuild_it()
        if rebuilt is not None:
            fmt = os.path.splitext(rebuilt)[1][1:].upper()
            with open(rebuilt, 'rb') as f:
                self.db.add_format(self.book_id, fmt, f, index_is_id=True)
            self.accept()

    def cancel(self):
        self.reject()

    def cleanup(self):
        if isosx and self._exploded:
            try:
                import appscript
                self.finder = appscript.app('Finder')
                self.finder.Finder_windows[os.path.basename(self._exploded)].close()
            except:
                pass

        for f in self._cleanup_files:
            try:
                os.remove(f)
            except:
                pass

        for d in self._cleanup_dirs:
            try:
                shutil.rmtree(d)
            except:
                pass

    @property
    def db(self):
        return self.db_ref()

    @property
    def current_format(self):
        for b in self.fmt_choice_buttons:
            if b.isChecked():
                return unicode(b.text())
コード例 #3
0
ファイル: unpack_book.py プロジェクト: zwlistu/calibre
class UnpackBook(QDialog):
    def __init__(self, parent, book_id, fmts, db):
        QDialog.__init__(self, parent)
        self.setWindowIcon(QIcon(I('unpack-book.png')))
        self.book_id, self.fmts, self.db_ref = book_id, fmts, weakref.ref(db)
        self._exploded = None
        self._cleanup_dirs = []
        self._cleanup_files = []

        self.setup_ui()
        self.setWindowTitle(
            _('Unpack book') + ' - ' + db.title(book_id, index_is_id=True))

        button = self.fmt_choice_buttons[0]
        button_map = {
            unicode_type(x.text()): x
            for x in self.fmt_choice_buttons
        }
        of = prefs['output_format'].upper()
        df = tweaks.get('default_tweak_format', None)
        lf = gprefs.get('last_tweak_format', None)
        if df and df.lower() == 'remember' and lf in button_map:
            button = button_map[lf]
        elif df and df.upper() in button_map:
            button = button_map[df.upper()]
        elif of in button_map:
            button = button_map[of]
        button.setChecked(True)

        self.init_state()
        for button in self.fmt_choice_buttons:
            button.toggled.connect(self.init_state)

    def init_state(self, *args):
        self._exploded = None
        self.preview_button.setEnabled(False)
        self.rebuild_button.setEnabled(False)
        self.explode_button.setEnabled(True)

    def setup_ui(self):  # {{{
        self._g = g = QHBoxLayout(self)
        self.setLayout(g)
        self._l = l = QVBoxLayout()
        g.addLayout(l)

        fmts = sorted(x.upper() for x in self.fmts)
        self.fmt_choice_box = QGroupBox(_('Choose the format to unpack:'),
                                        self)
        self._fl = fl = QHBoxLayout()
        self.fmt_choice_box.setLayout(self._fl)
        self.fmt_choice_buttons = [QRadioButton(y, self) for y in fmts]
        for x in self.fmt_choice_buttons:
            fl.addWidget(x,
                         stretch=10 if x is self.fmt_choice_buttons[-1] else 0)
        l.addWidget(self.fmt_choice_box)
        self.fmt_choice_box.setVisible(len(fmts) > 1)

        self.help_label = QLabel(
            _('''\
            <h2>About Unpack book</h2>
            <p>Unpack book allows you to fine tune the appearance of an e-book by
            making small changes to its internals. In order to use Unpack book,
            you need to know a little bit about HTML and CSS, technologies that
            are used in e-books. Follow the steps:</p>
            <br>
            <ol>
            <li>Click "Explode book": This will "explode" the book into its
            individual internal components.<br></li>
            <li>Right click on any individual file and select "Open with..." to
            edit it in your favorite text editor.<br></li>
            <li>When you are done: <b>close the file browser window
            and the editor windows you used to make your tweaks</b>. Then click
            the "Rebuild book" button, to update the book in your calibre
            library.</li>
            </ol>'''))
        self.help_label.setWordWrap(True)
        self._fr = QFrame()
        self._fr.setFrameShape(QFrame.VLine)
        g.addWidget(self._fr)
        g.addWidget(self.help_label)

        self._b = b = QGridLayout()
        left, top, right, bottom = b.getContentsMargins()
        top += top
        b.setContentsMargins(left, top, right, bottom)
        l.addLayout(b, stretch=10)

        self.explode_button = QPushButton(QIcon(I('wizard.png')),
                                          _('&Explode book'))
        self.preview_button = QPushButton(QIcon(I('view.png')),
                                          _('&Preview book'))
        self.cancel_button = QPushButton(QIcon(I('window-close.png')),
                                         _('&Cancel'))
        self.rebuild_button = QPushButton(QIcon(I('exec.png')),
                                          _('&Rebuild book'))

        self.explode_button.setToolTip(
            _('Explode the book to edit its components'))
        self.preview_button.setToolTip(_('Preview the result of your changes'))
        self.cancel_button.setToolTip(_('Abort without saving any changes'))
        self.rebuild_button.setToolTip(
            _('Save your changes and update the book in the calibre library'))

        a = b.addWidget
        a(self.explode_button, 0, 0, 1, 1)
        a(self.preview_button, 0, 1, 1, 1)
        a(self.cancel_button, 1, 0, 1, 1)
        a(self.rebuild_button, 1, 1, 1, 1)

        for x in ('explode', 'preview', 'cancel', 'rebuild'):
            getattr(self, x + '_button').clicked.connect(getattr(self, x))

        self.msg = QLabel('dummy', self)
        self.msg.setVisible(False)
        self.msg.setStyleSheet('''
        QLabel {
            text-align: center;
            background-color: white;
            color: black;
            border-width: 1px;
            border-style: solid;
            border-radius: 20px;
            font-size: x-large;
            font-weight: bold;
        }
        ''')

        self.resize(self.sizeHint() + QSize(40, 10))

    # }}}

    def show_msg(self, msg):
        self.msg.setText(msg)
        self.msg.resize(self.size() - QSize(50, 25))
        self.msg.move((self.width() - self.msg.width()) // 2,
                      (self.height() - self.msg.height()) // 2)
        self.msg.setVisible(True)

    def hide_msg(self):
        self.msg.setVisible(False)

    def explode(self):
        self.show_msg(_('Exploding, please wait...'))
        if len(self.fmt_choice_buttons) > 1:
            gprefs.set('last_tweak_format', self.current_format.upper())
        QTimer.singleShot(5, self.do_explode)

    def ask_question(self, msg):
        return question_dialog(self, _('Are you sure?'), msg)

    def do_explode(self):
        from calibre.ebooks.tweak import get_tools, Error, WorkerError
        tdir = PersistentTemporaryDirectory('_tweak_explode')
        self._cleanup_dirs.append(tdir)
        det_msg = None
        try:
            src = self.db.format(self.book_id,
                                 self.current_format,
                                 index_is_id=True,
                                 as_path=True)
            self._cleanup_files.append(src)
            exploder = get_tools(self.current_format)[0]
            opf = exploder(src, tdir, question=self.ask_question)
        except WorkerError as e:
            det_msg = e.orig_tb
        except Error as e:
            return error_dialog(
                self,
                _('Failed to unpack'),
                (_('Could not explode the %s file.') % self.current_format) +
                ' ' + as_unicode(e),
                show=True)
        except:
            import traceback
            det_msg = traceback.format_exc()
        finally:
            self.hide_msg()

        if det_msg is not None:
            return error_dialog(
                self,
                _('Failed to unpack'),
                _('Could not explode the %s file. Click "Show Details" for '
                  'more information.') % self.current_format,
                det_msg=det_msg,
                show=True)

        if opf is None:
            # The question was answered with No
            return

        self._exploded = tdir
        self.explode_button.setEnabled(False)
        self.preview_button.setEnabled(True)
        self.rebuild_button.setEnabled(True)
        open_local_file(tdir)

    def rebuild_it(self):
        from calibre.ebooks.tweak import get_tools, WorkerError
        src_dir = self._exploded
        det_msg = None
        of = PersistentTemporaryFile('_tweak_rebuild.' +
                                     self.current_format.lower())
        of.close()
        of = of.name
        self._cleanup_files.append(of)
        try:
            rebuilder = get_tools(self.current_format)[1]
            rebuilder(src_dir, of)
        except WorkerError as e:
            det_msg = e.orig_tb
        except:
            import traceback
            det_msg = traceback.format_exc()
        finally:
            self.hide_msg()

        if det_msg is not None:
            error_dialog(self,
                         _('Failed to rebuild file'),
                         _('Failed to rebuild %s. For more information, click '
                           '"Show details".') % self.current_format,
                         det_msg=det_msg,
                         show=True)
            return None

        return of

    def preview(self):
        self.show_msg(_('Rebuilding, please wait...'))
        QTimer.singleShot(5, self.do_preview)

    def do_preview(self):
        rebuilt = self.rebuild_it()
        if rebuilt is not None:
            self.parent().iactions['View']._view_file(rebuilt)

    def rebuild(self):
        self.show_msg(_('Rebuilding, please wait...'))
        QTimer.singleShot(5, self.do_rebuild)

    def do_rebuild(self):
        rebuilt = self.rebuild_it()
        if rebuilt is not None:
            fmt = os.path.splitext(rebuilt)[1][1:].upper()
            with open(rebuilt, 'rb') as f:
                self.db.add_format(self.book_id, fmt, f, index_is_id=True)
            self.accept()

    def cancel(self):
        self.reject()

    def cleanup(self):
        if isosx and self._exploded:
            try:
                import appscript
                self.finder = appscript.app('Finder')
                self.finder.Finder_windows[os.path.basename(
                    self._exploded)].close()
            except:
                pass

        for f in self._cleanup_files:
            try:
                os.remove(f)
            except:
                pass

        for d in self._cleanup_dirs:
            try:
                shutil.rmtree(d)
            except:
                pass

    @property
    def db(self):
        return self.db_ref()

    @property
    def current_format(self):
        for b in self.fmt_choice_buttons:
            if b.isChecked():
                return unicode_type(b.text())
コード例 #4
0
    def __init__(self, ebook, orig, is_scrambled, fmap, parent=None):
        QDialog.__init__(self, parent=parent)

        self.setWindowFlags(Qt.Window)

        self.orig = orig
        self.ebook = ebook
        self.revfmap = {v: k for (k, v) in iteritems(fmap)}

        # create widgets
        lay = QVBoxLayout()
        self.setLayout(lay)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Close)

        self.webview_orig = Webview()
        self.webview_scram = Webview()
        settings = self.webview_orig.settings()
        if hasattr(settings, 'setUserStyleSheetUrl'):
            # QWebView from QtWebKit
            style = 'body {%s}' % CSSBG
            cssurl = 'data:text/css;charset=utf-8;base64,'
            cssurl += as_base64_unicode(style)
            self.webview_orig.settings().setUserStyleSheetUrl(QUrl(cssurl))
            self.webview_scram.settings().setUserStyleSheetUrl(QUrl(cssurl))
        elif hasattr(self.webview_orig, 'setStyleSheet'):
            # QWebEngineView from QtWebEngine
            # setStyleSheet doesn't seem to work at the moment
            self.webview_orig.setStyleSheet('Webview {%s}' % CSSBG)
            self.webview_scram.setStyleSheet('Webview {%s}' % CSSBG)

        dummytext = '<body><p>*** Text content could not be displayed ...</p></body>'
        self.webview_orig.setHtml(dummytext)
        self.webview_scram.setHtml(dummytext)

        self.htmlList_orig = QListWidget()
        self.htmlList_scram = QListWidget()
        self.htmlList_orig.setMinimumWidth(300)
        self.htmlList_scram.setMinimumWidth(300)

        gpbox1 = QGroupBox()
        lay1 = QHBoxLayout()
        gpbox1.setLayout(lay1)
        lay1.addWidget(self.htmlList_orig)

        gpbox3 = QGroupBox()
        lay3 = QHBoxLayout()
        gpbox3.setLayout(lay3)
        lay3.addWidget(self.htmlList_scram)

        gpbox2 = QGroupBox('Original text content:')
        lay2 = QHBoxLayout()
        gpbox2.setLayout(lay2)
        lay2.addWidget(self.webview_orig)

        gpbox4 = QGroupBox('Original text content:')
        lay4 = QHBoxLayout()
        gpbox4.setLayout(lay4)
        lay4.addWidget(self.webview_scram)

        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(gpbox1)
        splitter.addWidget(gpbox2)
        splitter.addWidget(gpbox3)
        splitter.addWidget(gpbox4)

        lay.addWidget(splitter)
        lay.addWidget(buttonBox)

        # create connect signals/slots
        buttonBox.rejected.connect(self.reject)
        self.htmlList_scram.currentRowChanged.connect(
            self.htmlList_currentRowChanged)
        self.htmlList_scram.itemDoubleClicked.connect(
            self.htmlList_itemDoubleClicked)

        self.htmlList_orig.setEnabled(False)
        self.htmlnames_scram = get_textnames(self.ebook)
        self.htmlnames_orig = tuple(
            [self.revfmap.get(an, an) for an in self.htmlnames_scram])

        gpbox1.setTitle('Original HTML files: %s' % len(self.htmlnames_orig))
        gpbox3.setTitle('Original HTML files: %s' % len(self.htmlnames_scram))
        self.htmlList_orig.clear()
        self.htmlList_orig.addItems(self.htmlnames_orig)
        self.htmlList_scram.clear()
        self.htmlList_scram.addItems(self.htmlnames_scram)

        if not self.revfmap:
            gpbox1.setVisible(False)

        msg = '%s Preview: Original' % CAPTION
        if not is_scrambled:
            self.setWindowTitle(msg)
            gpbox1.setVisible(False)
            gpbox2.setVisible(False)
        else:
            self.setWindowTitle(msg + ' vs. Scrambled')
            gpbox3.setTitle('Scrambled HTML files: %s' %
                            len(self.htmlnames_scram))
            gpbox4.setTitle('Scrambled text content:')

        self.htmlList_scram.setCurrentRow(0)
コード例 #5
0
    def __init__(self,
                 pathtoebook,
                 book_id=None,
                 from_calibre=False,
                 dsettings={},
                 calibre_libpaths=[],
                 parent=None):
        QDialog.__init__(self, parent=parent)
        self.gui = parent
        self.pathtoebook = pathtoebook
        self.book_id = book_id
        self.from_calibre = from_calibre
        self.calibre_libpaths = calibre_libpaths
        self.dsettings = MR_SETTINGS.copy()
        self.dsettings.update(dsettings)

        self.ebook = None
        self.eborig = None
        self.cleanup_dirs = []
        self.cleanup_files = []
        self.log = []

        self.rename_file_map = {}
        self.meta, self.errors = {}, {}
        self.is_scrambled = False
        self.dummyimg = None
        self.dummysvg = ''

        self.setWindowTitle(CAPTION)
        self.setWindowIcon(get_icons('images/plugin_icon.png'))

        # create widgets
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Save
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.button(
            QDialogButtonBox.Save).setText('Save scrambled ebook && Exit')

        self.browser = QTextBrowser()
        self.browser.setText('')
        self.browser.setLineWrapMode(QTextBrowser.NoWrap)
        self.browser.setMinimumWidth(600)
        self.browser.setMinimumHeight(150)
        self.browser.setReadOnly(True)

        self.savefile = QLineEdit()
        self.savefile.setReadOnly(True)

        self.sourcefile = QLineEdit()
        self.sourcefile.setMinimumWidth(100)
        self.sourcefile.setReadOnly(True)

        self.browsesource = QPushButton('...')
        self.browsesource.setMaximumWidth(30)

        about_button = QPushButton('About', self)
        self.runButton = QPushButton('Scramble now')
        previewButton = QPushButton('Preview content')
        if Webview is None:
            previewButton.setEnabled(False)
            previewButton.setToolTip(
                'Preview not currently available for this book')

        configButton = QPushButton('Change rules *')
        configButton.setToolTip(
            'Only available in standalone version, not calibre plugin')
        metadataButton = QPushButton('View metadata *')
        metadataButton.setToolTip(
            'Only available in standalone version, not calibre plugin')
        errorsButton = QPushButton('View errors *')
        errorsButton.setToolTip(
            'Only available in standalone version, not calibre plugin')

        # layout widgets
        gpsource = QGroupBox('Source ebook:')
        laysource = QGridLayout()
        gpsource.setLayout(laysource)
        laysource.addWidget(self.sourcefile, 0, 0)
        laysource.addWidget(self.browsesource, 0, 1)

        gptarget = QGroupBox('Scrambled ebook:')
        laytarget = QGridLayout()
        gptarget.setLayout(laytarget)
        laytarget.addWidget(self.savefile, 0, 0)

        gpaction = QGroupBox('Actions:')
        layaction = QVBoxLayout()
        gpaction.setLayout(layaction)
        layaction.addWidget(self.runButton)
        layaction.addStretch()
        layaction.addWidget(previewButton)
        layaction.addStretch()

        gpextras = QGroupBox('Extras:')
        layaction2 = QVBoxLayout()
        gpextras.setLayout(layaction2)
        layaction2.addWidget(configButton)
        layaction2.addWidget(metadataButton)
        layaction2.addWidget(errorsButton)

        layaction3 = QVBoxLayout()
        layaction3.addWidget(about_button)
        layaction3.addStretch()
        layaction3.addWidget(gpextras)

        grid = QGridLayout()
        grid.addWidget(self.browser, 0, 0)
        grid.addLayout(layaction3, 0, 1)
        grid.addWidget(gpsource, 2, 0)
        grid.addWidget(gptarget, 3, 0)
        grid.addWidget(gpaction, 2, 1, 2, 1)
        grid.addWidget(self.buttonBox, 5, 0, 1, 2)
        self.setLayout(grid)

        # create connect signals/slots
        about_button.clicked.connect(self.about_button_clicked)
        self.runButton.clicked.connect(self.create_scramble_book)
        previewButton.clicked.connect(self.preview_ebook)
        configButton.clicked.connect(self.change_rules)
        metadataButton.clicked.connect(self.view_metadata)
        errorsButton.clicked.connect(self.view_errors)
        self.browsesource.clicked.connect(self.choose_source_ebook)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

        if self.from_calibre:
            gpextras.setVisible(
                False)  # Extras not available in calibre plugin
            self.browsesource.setVisible(
                False)  # ebook file selection done by calibre

        self.initialise_new_file(self.pathtoebook)
コード例 #6
0
ファイル: main_widget.py プロジェクト: iclosure/carmonitor
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_()