class Yasser(QDialog): def __init__(self): QDialog.__init__(self) self.vlayout = QVBoxLayout() self.setLayout(self.vlayout) #- new book project self.title_layout = QHBoxLayout() self.title_container = QWidget() self.title_container.setLayout(self.title_layout) self.book_title = QLabel("Book Title: ") self.book_title.setObjectName("book_title") self.edit_title = QLineEdit("Type book title here") self.edit_title.setObjectName("edit_title") self.edit_title.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.edit_title.setToolTip("Type book title here") self.title_layout.addWidget(self.book_title) self.title_layout.addWidget(self.edit_title) self.vlayout.addWidget(self.title_container) #- camera overview self.camera_layout = QHBoxLayout() self.camera_container = QWidget() self.camera_container.setLayout(self.camera_layout) self.right_camera = QLabel("Left pages") self.left_camera = QLabel("Right pages") self.camera_layout.addWidget(self.right_camera) self.camera_layout.addWidget(self.left_camera) self.vlayout.addWidget(self.camera_container) #- image preview self.preview_layout = QHBoxLayout() self.preview_container = QWidget() self.preview_container.setLayout(self.preview_layout) self.left_preview = ImageButton("left.png", 200) self.right_preview = ImageButton("right.png", 200) self.left_preview.image_pressed.connect( lambda: print("show next image")) self.right_preview.image_pressed.connect( lambda: print("show next image")) self.preview_layout.addWidget(self.right_preview) self.preview_layout.addWidget(self.left_preview) self.vlayout.addWidget(self.preview_container)
class AnnotationsAppearance(SizePersistedDialog): ''' Dialog for managing CSS rules, including Preview window ''' if isosx: FONT = QFont('Monaco', 12) elif iswindows: FONT = QFont('Lucida Console', 9) elif islinux: FONT = QFont('Monospace', 9) FONT.setStyleHint(QFont.TypeWriter) def __init__(self, parent, icon, prefs): self.parent = parent self.prefs = prefs self.icon = icon super(AnnotationsAppearance, self).__init__(parent, 'appearance_dialog') self.setWindowTitle(_('Modify appearance')) self.setWindowIcon(icon) self.l = QVBoxLayout(self) self.setLayout(self.l) # Add a label for description #self.description_label = QLabel(_("Descriptive text here")) #self.l.addWidget(self.description_label) # Add a group box, vertical layout for preview window self.preview_gb = QGroupBox(self) self.preview_gb.setTitle(_("Preview")) self.preview_vl = QVBoxLayout(self.preview_gb) self.l.addWidget(self.preview_gb) self.wv = QWebView() self.wv.setHtml('<p></p>') self.wv.setMinimumHeight(100) self.wv.setMaximumHeight(16777215) self.wv.setGeometry(0, 0, 200, 100) self.wv.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.preview_vl.addWidget(self.wv) # Create a group box, horizontal layout for the table self.css_table_gb = QGroupBox(self) self.css_table_gb.setTitle(_("Annotation elements")) self.elements_hl = QHBoxLayout(self.css_table_gb) self.l.addWidget(self.css_table_gb) # Add the group box to the main layout self.elements_table = AnnotationElementsTable(self, 'annotation_elements_tw') self.elements_hl.addWidget(self.elements_table) self.elements_table.initialize() # Options self.options_gb = QGroupBox(self) self.options_gb.setTitle(_("Options")) self.options_gl = QGridLayout(self.options_gb) self.l.addWidget(self.options_gb) current_row = 0 # <hr/> separator # addWidget(widget, row, col, rowspan, colspan) self.hr_checkbox = QCheckBox(_('Add horizontal rule between annotations')) self.hr_checkbox.stateChanged.connect(self.hr_checkbox_changed) self.hr_checkbox.setCheckState( JSONConfig('plugins/annotations').get('appearance_hr_checkbox', False)) self.options_gl.addWidget(self.hr_checkbox, current_row, 0, 1, 4) current_row += 1 # Timestamp self.timestamp_fmt_label = QLabel(_("Timestamp format:")) self.options_gl.addWidget(self.timestamp_fmt_label, current_row, 0) self.timestamp_fmt_le = QLineEdit( JSONConfig('plugins/annotations').get('appearance_timestamp_format', default_timestamp), parent=self) self.timestamp_fmt_le.textEdited.connect(self.timestamp_fmt_changed) self.timestamp_fmt_le.setFont(self.FONT) self.timestamp_fmt_le.setObjectName('timestamp_fmt_le') self.timestamp_fmt_le.setToolTip(_('Format string for timestamp')) self.timestamp_fmt_le.setMaximumWidth(16777215) self.timestamp_fmt_le.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) self.options_gl.addWidget(self.timestamp_fmt_le, current_row, 1) self.timestamp_fmt_reset_tb = QToolButton(self) self.timestamp_fmt_reset_tb.setToolTip(_("Reset to default")) self.timestamp_fmt_reset_tb.setIcon(QIcon(I('trash.png'))) self.timestamp_fmt_reset_tb.clicked.connect(self.reset_timestamp_to_default) self.options_gl.addWidget(self.timestamp_fmt_reset_tb, current_row, 2) self.timestamp_fmt_help_tb = QToolButton(self) self.timestamp_fmt_help_tb.setToolTip(_("Format string reference")) self.timestamp_fmt_help_tb.setIcon(QIcon(I('help.png'))) self.timestamp_fmt_help_tb.clicked.connect(self.show_help) self.options_gl.addWidget(self.timestamp_fmt_help_tb, current_row, 3) # Button box bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.l.addWidget(bb) # Spacer self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.l.addItem(self.spacerItem) # Sizing sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.resize_dialog() def hr_checkbox_changed(self, state): self.prefs.set('appearance_hr_checkbox', state) self.elements_table.preview_css() def reset_timestamp_to_default(self): from calibre_plugins.annotations.appearance import default_timestamp self.timestamp_fmt_le.setText(default_timestamp) self.timestamp_fmt_changed() def show_help(self): ''' Display strftime help file ''' hv = HelpView(self, self.icon, self.prefs, html=get_resources('help/timestamp_formats.html'), title=_("Timestamp formats")) hv.show() def sizeHint(self): return QtCore.QSize(600, 200) def timestamp_fmt_changed(self): self.prefs.set('appearance_timestamp_format', str(self.timestamp_fmt_le.text())) self.elements_table.preview_css()
class Index(QWidget): show_mainindex_sg = pyqtSignal(int, str) show_register_sg = pyqtSignal() def __init__(self, parent=None): super(Index, self).__init__(parent) self.desktop = QApplication.desktop() self.screenRect = self.desktop.screenGeometry() self.h = self.screenRect.height() self.w = self.screenRect.width() self.xr = self.w / 930 self.yr = self.h / 640 self.zr = min(self.xr, self.yr) self.top_wi = QWidget(self) self.logo_la = QLabel(self.top_wi) self.ind_wi = QWidget(self) self.login_but = QPushButton(self.ind_wi) self.joke_but = QPushButton(self.ind_wi) self.register_but = QPushButton(self.ind_wi) self.imp_la = QLabel(self.ind_wi) self.account_le = QLineEdit(self.ind_wi) self.psw_le = QLineEdit(self.ind_wi) self.loading = QLabel(self) self.gif = QMovie('./resource/image/load.gif') self.set_ui() with open('index.qss', 'r') as f: self.setStyleSheet(f.read()) def set_ui(self): self.setWindowTitle('Login') self.setObjectName('index') self.resize(self.w, self.h) self.top_wi.setObjectName('top') self.top_wi.resize(930 * self.xr, 95 * self.yr) self.logo_la.setObjectName('logo') self.logo_la.resize(65 * self.xr, 65 * self.zr) self.logo_la.move(29 * self.xr, 16 * self.yr) effect = QGraphicsDropShadowEffect() effect.setOffset(10, 10) effect.setColor(QColor(0, 0, 0, 80)) effect.setBlurRadius(20) self.ind_wi.setObjectName('login') self.ind_wi.resize(327 * self.xr, 388 * self.yr) self.ind_wi.move(300 * self.xr, 150 * self.yr) self.ind_wi.setGraphicsEffect(effect) self.joke_but.setObjectName('joke') self.joke_but.resize(130 * self.xr, 30 * self.yr) self.joke_but.move(76 * self.xr, 234 * self.yr) self.joke_but.setFlat(True) self.joke_but.setText('忘记密码?我也没办法') self.login_but.setObjectName('button') self.login_but.move(64 * self.xr, 260 * self.yr) self.login_but.resize(202 * self.xr, 45 * self.yr) self.login_but.setText('登陆') self.login_but.clicked.connect(self.login) self.register_but.setObjectName('button') self.register_but.move(64 * self.xr, 315 * self.yr) self.register_but.resize(202 * self.xr, 45 * self.yr) self.register_but.setText('注册') self.register_but.clicked.connect(self.show_register) self.imp_la.setObjectName('imp_label') self.imp_la.resize(100 * self.zr, 100 * self.zr) self.imp_la.move(115 * self.xr + 100 * (self.xr - self.zr) / 2, 15 * self.yr) self.imp_la.setStyleSheet('border-radius:{}px;'.format(self.zr * 49)) self.account_le.setObjectName('input') self.account_le.setTextMargins(20, 0, 0, 0) self.account_le.resize(213 * self.xr, 45 * self.yr) self.account_le.move(59 * self.xr, 126 * self.yr) self.account_le.setPlaceholderText('账号') self.psw_le.setObjectName('input') self.psw_le.setTextMargins(20, 0, 0, 0) self.psw_le.resize(213 * self.xr, 45 * self.yr) self.psw_le.move(59 * self.xr, 181 * self.yr) self.psw_le.setPlaceholderText('密码') self.psw_le.setEchoMode(QLineEdit.Password) self.loading.setObjectName('load') self.loading.resize(self.xr * 150, self.yr * 150) self.loading.move(self.xr * 760, self.yr * 500) self.loading.setScaledContents(True) self.loading.setMovie(self.gif) self.gif.start() self.ind_wi.setStyleSheet('#input{border-radius:' + str(self.zr * 20) + 'px;}' + '#button{border-radius:' + str( self.zr * 20) + 'px;' + 'font-size:' + str(int(self.zr * 18)) + 'px;}') def login(self): account_p = self.account_le.text() psw_p = self.psw_le.text() dic = login(account_p, psw_p) if dic['status'] == 0: self.show_mainindex_sg.emit(dic['data']['user_id'], dic['data']['token']) elif dic['status'] == 1: self.account_le.clear() self.psw_le.clear() self.account_le.setStyleSheet('border:4px solid;border-color:red;') self.account_le.setPlaceholderText('网络超时') else: self.account_le.clear() self.psw_le.clear() self.account_le.setStyleSheet('border:4px solid;border-color:red;') self.account_le.setPlaceholderText('账号不存在或密码错误') def show_register(self): self.show_register_sg.emit()
class Search(QWidget): search_sg = pyqtSignal(dict) back_sg = pyqtSignal() def __init__(self, parent=None): super(Search, self).__init__(parent) self.desktop = QApplication.desktop() self.screenRect = self.desktop.screenGeometry() self.h = self.screenRect.height() self.w = self.screenRect.width() self.xr = self.w / 930 self.yr = self.h / 640 self.zr = min(self.xr, self.yr) self.token = '' self.head = QLabel(self) self.search = QLineEdit(self) self.butt = QPushButton(self) self.but = QPushButton(self) self.set_ui() def set_ui(self): self.search.setObjectName('search') self.search.resize(self.xr * 520, self.yr * 40) self.search.move(self.xr * 205, self.yr * 300) self.search.setPlaceholderText('请输入战局ID') self.search.setTextMargins(20, 0, 0, 0) self.search.setStyleSheet('font-size:{}px;border-radius:{}px;'.format(int(self.zr * 16), self.zr * 15)) self.head.setObjectName('head') self.head.resize(self.xr * 200, self.yr * 50) self.head.move(self.xr * 360, self.yr * 240) self.head.setText('搜索战局') self.head.setAlignment(Qt.AlignCenter) self.head.setStyleSheet('font-size:{}px;'.format(int(self.zr * 25))) self.but.setObjectName('button') self.but.resize(self.xr * 130, self.yr * 40) self.but.move(self.xr * 480, self.yr * 380) self.but.setText('返回') self.but.clicked.connect(self.back_for) self.butt.setObjectName('button') self.butt.resize(self.xr * 130, self.yr * 40) self.butt.move(self.xr * 320, self.yr * 380) self.butt.setText('搜索') self.butt.clicked.connect(self.search_for) self.setStyleSheet('#button{font-size:' + str(int(self.zr * 18)) + 'px;border-radius:' + str( self.zr * 15) + 'px;background-color:#333643;color:#ffffff;}#button:hover{background-color:#575B6E;}#button:pressed{background-color:#202129;}') def search_for(self): id_p = self.search.text() self.search.clear() dic = find_info(id_p, self.token) # print(dic) if dic['status'] == 0: self.search_sg.emit(dic) else: self.search.setStyleSheet( 'font-size:{}px;border-radius:{}px;border:4px solid;border-color:red'.format(int(self.zr * 16), self.zr * 15)) self.search.clear() self.search.setPlaceholderText('ID不存在') def back_for(self): self.back_sg.emit() def get_token(self, t): self.token = t
class ParameterMeshGroupView(ParameterView): """Top-level table editor item.""" meshFileChanged = pyqtSignal(str, str, float, bool) meshGroupCheck = pyqtSignal(str, str, str) meshGroupUnCheck = pyqtSignal(str, str, str) meshChanged = pyqtSignal() """Signal: emitted when mesh is changed in the combo box.""" def __init__(self, panel, **kwargs): """ Create view. Arguments: **kwargs: Arbitrary keyword arguments. """ super(ParameterMeshGroupView, self).__init__(panel, **kwargs) self.setStretchable(True) self._mesh = QComboBox(self) self._mesh.setObjectName("MESH") self._msg = QLabel(self) self._list = QTreeWidget(self) self._list.setAllColumnsShowFocus(True) self._list.setSelectionMode(QTreeWidget.SingleSelection) self._list.setColumnCount(2) titles = [] titles.append(translate("AsterStudy", "Name")) titles.append(translate("AsterStudy", "Size")) self._list.setHeaderLabels(titles) self._list.header().setSectionResizeMode(QHeaderView.ResizeToContents) self._list.header().setStretchLastSection(True) manlabel = QLabel(translate("ParameterPanel", "Manual selection"), self) manlabel.setToolTip( translate( "ParameterPanel", "Enter manually the wanted groups if " "not present in the list")) self._manual = QLineEdit(self) self._manual.setObjectName("MANUAL_INPUT") base = self.grid() base.addWidget(self._mesh, 0, 0, 1, -1) base.addWidget(self._msg, 1, 0, 1, -1) base.addWidget(self._list, 2, 0, 1, -1) base.addWidget(manlabel, 3, 0, 1, -1) base.addWidget(self._manual, 4, 0, 1, -1) self._mesh.activated[int].connect(self._meshActivated) self._updateMeshList() self.meshFileChanged.connect(self.meshview().displayMEDFileName) self.meshGroupCheck.connect(self.meshview().displayMeshGroup) self.meshGroupUnCheck.connect(self.meshview().undisplayMeshGroup) self._list.itemChanged.connect(self.meshGroupToChange) def meshList(self): """ Gets the mesh commands list Returns: list (Command): List of commands with meshes. """ mlist = [] for i in xrange(self._mesh.count()): mlist.append(self._mesh.itemData(i).name) return mlist def setMeshList(self, meshlist): """ Sets the mesh commands list Arguments: meshlist: List of commands with meshes. """ self._mesh.clear() show_title = behavior().show_catalogue_name_in_selectors title_mask = '{n} ({t})' if show_title else '{n}' for meshcmd in meshlist: title = title_mask.format(n=meshcmd.name, t=meshcmd.title) self._mesh.addItem(title, meshcmd) def mesh(self): """ Gets the currently selected mesh command object or None in error case. Returns: Command: Current mesh command object. """ idx = self._mesh.currentIndex() return self._mesh.itemData(idx) if idx >= 0 else None def setMesh(self, mesh): """ Sets the current mesh command object if it exists in the list. Arguments: mesh: Current mesh command object. """ self._mesh.setCurrentIndex(self._mesh.findData(mesh)) def message(self): """ Gets the info message text. Returns: str: info message text. """ return self._msg.text() def setMessage(self, msg): """ Sets the info message text. Arguments: msg (str): info message text. """ self._msg.setText(msg) self._msg.setVisible(len(msg) > 0) def setMeshGroups(self, groups): """ Sets the mesh group list Arguments: groups (dict[int, list[tuple[str, int]]]): Mesh groups info. """ self._list.clear() grp_types = sorted(groups.keys()) for typ in grp_types: names = groups[typ] if not names: continue title = MeshElemType.value2str(typ) item = QTreeWidgetItem(self._list, [title]) for name, size in names: sub_item = QTreeWidgetItem(item, [name, str(size)]) sub_item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) sub_item.setCheckState(0, Qt.Unchecked) sub_item.setTextAlignment(1, Qt.AlignRight) self._list.expandAll() def inputMeshGroups(self): """ Gets the mesh group names list entered manually Returns: list (str): List of group names. """ text = self._manual.text().strip() return [i.strip() for i in text.split(",")] if len(text) > 0 else [] def setInputMeshGroups(self, groups): """ Sets the mesh group list entered manually Arguments: groups: List of mesh group names. """ self._manual.setText(",".join(groups)) def selectedMeshGroups(self): """ Gets the names of selected (checked) mesh groups. Returns: list (str): List of selected group names. """ groups = [] for i in range(self._list.topLevelItemCount()): item = self._list.topLevelItem(i) for j in xrange(item.childCount()): sub_item = item.child(j) if sub_item.checkState(0) == Qt.Checked: groups.append(sub_item.text(0)) return list(set(groups)) def setSelectedMeshGroups(self, groups): """ Sets the specified group names are selected (checked) and unchecked all other. Arguments: groups: List of selected mesh group names. """ for i in range(self._list.topLevelItemCount()): item = self._list.topLevelItem(i) for j in xrange(item.childCount()): sub_item = item.child(j) state = Qt.Checked if sub_item.text(0) in groups \ else Qt.Unchecked sub_item.setCheckState(0, state) @pyqtSlot(QTreeWidgetItem, int) def meshGroupToChange(self, item, column): """ Emits display signal whenever the user clicks a check box """ meshcmd = self._meshcmd(self._mesh.currentIndex()) if meshcmd is not None: file_name, nom_med = get_cmd_mesh(meshcmd) if file_name is not None and nom_med is not None: if item.checkState(column) == Qt.Checked: self.meshGroupCheck.emit(file_name, nom_med, item.text(0)) else: self.meshGroupUnCheck.emit(file_name, nom_med, item.text(0)) def _meshcmd(self, index): """ Returns the *Command* instance associated with the panel """ meshcmd = None if 0 <= index < self._mesh.count(): meshcmd = self._mesh.itemData(index) return meshcmd def itemValue(self, **kwargs): """ Get selected values. Returns: tuple: List with all selected mesh groups """ res = tuple(self.selectedMeshGroups() + self.inputMeshGroups()) return res if len(res) > 0 else None def setItemValue(self, values): """ Set values of child items. Arguments: values: Tuple with item values (see `childValues()`). """ grplist = [] if values is not None: if isinstance(values, (tuple, list)): grplist = list(values) else: grplist = [values] self.setSelectedMeshGroups(grplist) check = dict.fromkeys(self.selectedMeshGroups()) grplist = [grp for grp in grplist if grp not in check] self.setInputMeshGroups(grplist) self._cache = self.itemValue() def filterItem(self, text): """ Filter out the item. Arguments: text (str): Regular expression. """ regex = QRegExp(text, Qt.CaseInsensitive) for i in range(self._list.topLevelItemCount()): item = self._list.topLevelItem(i) cnt_visible = 0 for j in xrange(item.childCount()): sub_item = item.child(j) item_text = sub_item.text(0) hidden = text != "" and regex.indexIn(item_text) == -1 sub_item.setHidden(hidden) if not hidden: cnt_visible += 1 item.setHidden(cnt_visible == 0) def _updateMeshList(self): """ Updates the mesh list in the combobox """ meshlist = avail_meshes(parameterPanel(self).pendingStorage()) meshlist.reverse() self.setMeshList(meshlist) msg = "" if len(meshlist) > 1: msg = translate("ParameterPanel", "More than one mesh found") elif len(meshlist) == 0: msg = translate("ParameterPanel", "No mesh found") self.setMessage(msg) self._meshActivated(self._mesh.currentIndex()) def _meshActivated(self, index): """ Updates the mesh groups in checkable list. Invoked after mesh changing in mesh combobox. """ meshcmd = None if 0 <= index < self._mesh.count(): meshcmd = self._mesh.itemData(index) groups = {} if meshcmd is not None: group_type = self._meshGroupType() file_name, nom_med = get_cmd_mesh(meshcmd) if is_medfile(file_name) or is_reference(file_name): self.meshFileChanged.emit(file_name, nom_med, 0.1, False) try: groups = get_cmd_groups(meshcmd, group_type, with_size=True) except TypeError: pass self.setMeshGroups(groups) self.meshChanged.emit() def _meshGroupType(self): """ Get the type of the mesh group Returns: str: Mesh group type (see `MeshGroupType`). """ mgtype = -1 name = self.itemName() if name.endswith("_MA") or is_contains_word(name, "MA"): mgtype = MeshGroupType.GElement elif name.endswith("_NO") or is_contains_word(name, "NO"): mgtype = MeshGroupType.GNode return mgtype
class Register(QWidget): register_ok_sg = pyqtSignal() def __init__(self, parent=None): super(Register, self).__init__(parent) self.desktop = QApplication.desktop() self.screenRect = self.desktop.screenGeometry() self.h = self.screenRect.height() self.w = self.screenRect.width() self.xr = self.w / 930 self.yr = self.h / 640 self.zr = min(self.xr, self.yr) self.top_wi = QWidget(self) self.logo_la = QLabel(self.top_wi) self.ind_wi = QWidget(self) self.register_but = QPushButton(self.ind_wi) self.imp_la = QLabel(self.ind_wi) self.account_le = QLineEdit(self.ind_wi) self.psw_le = QLineEdit(self.ind_wi) self.name_le = QLineEdit(self.ind_wi) self.set_ui() with open('index.qss', 'r') as f: self.setStyleSheet(f.read()) def set_ui(self): self.setWindowTitle('Register') self.setObjectName('register') self.resize(self.w, self.h) self.top_wi.setObjectName('top') self.top_wi.resize(930 * self.xr, 95 * self.yr) self.logo_la.setObjectName('logo') self.logo_la.resize(65 * self.xr, 65 * self.zr) self.logo_la.move(29 * self.xr, 16 * self.yr) effect = QGraphicsDropShadowEffect() effect.setOffset(10, 10) effect.setColor(QColor(0, 0, 0, 80)) effect.setBlurRadius(20) self.ind_wi.setObjectName('login') self.ind_wi.resize(327 * self.xr, 388 * self.yr) self.ind_wi.move(300 * self.xr, 150 * self.yr) self.ind_wi.setGraphicsEffect(effect) self.register_but.setObjectName('button') self.register_but.move(64 * self.xr, 315 * self.yr) self.register_but.resize(202 * self.xr, 45 * self.yr) self.register_but.setText('注册新用户') self.register_but.clicked.connect(self.register) self.imp_la.setObjectName('imp_label') self.imp_la.resize(100 * self.zr, 100 * self.zr) self.imp_la.move(115 * self.xr + 100 * (self.xr - self.zr) / 2, 15 * self.yr) self.imp_la.setStyleSheet('border-radius:{}px;'.format(self.zr * 49)) self.account_le.setObjectName('input') self.account_le.setTextMargins(20, 0, 0, 0) self.account_le.resize(213 * self.xr, 45 * self.yr) self.account_le.move(59 * self.xr, 126 * self.yr) self.account_le.setPlaceholderText('账号') self.psw_le.setObjectName('input') self.psw_le.setTextMargins(20, 0, 0, 0) self.psw_le.resize(213 * self.xr, 45 * self.yr) self.psw_le.move(59 * self.xr, 181 * self.yr) self.psw_le.setPlaceholderText('密码') self.psw_le.setEchoMode(QLineEdit.Password) self.name_le.setObjectName('input') self.name_le.setTextMargins(20, 0, 0, 0) self.name_le.resize(213 * self.xr, 45 * self.yr) self.name_le.move(59 * self.xr, 236 * self.yr) self.name_le.setPlaceholderText('昵称') self.ind_wi.setStyleSheet('#input{border-radius:' + str(self.zr * 20) + 'px;}' + '#button{border-radius:' + str(self.zr * 20) + 'px;' + 'font-size:' + str(int(self.zr * 18)) + 'px;}') def register(self): account_p = self.account_le.text() psw_p = self.psw_le.text() # name_p = self.name_le.text() dic = register(account_p, psw_p) if dic['status'] == 1001: self.account_le.clear() self.psw_le.clear() self.account_le.setStyleSheet('border:4px solid;border-color:red;') self.account_le.setPlaceholderText('账号已存在') elif dic['status'] == 0: self.register_ok_sg.emit() else: self.account_le.clear() self.psw_le.clear() self.account_le.setStyleSheet('border:4px solid;border-color:red;') self.account_le.setPlaceholderText('未知错误')
class ConfigWidget(QWidget, Logger): # Manually managed controls when saving/restoring EXCLUDED_CONTROLS = [ 'cfg_annotations_destination_comboBox' ] #LOCATION_TEMPLATE = "{cls}:{func}({arg1}) {arg2}" WIZARD_PROFILES = { 'Annotations': { 'label': 'mm_annotations', 'datatype': 'comments', 'display': {}, 'is_multiple': False } } def __init__(self, plugin_action): self.gui = plugin_action.gui self.opts = plugin_action.opts QWidget.__init__(self) self.l = QVBoxLayout() self.setLayout(self.l) # ~~~~~~~~ Create the runtime options group box ~~~~~~~~ self.cfg_runtime_options_gb = QGroupBox(self) self.cfg_runtime_options_gb.setTitle(_('Runtime options')) self.l.addWidget(self.cfg_runtime_options_gb) self.cfg_runtime_options_qvl = QVBoxLayout(self.cfg_runtime_options_gb) # ~~~~~~~~ Disable caching checkbox ~~~~~~~~ self.cfg_disable_caching_checkbox = QCheckBox(_('Disable caching')) self.cfg_disable_caching_checkbox.setObjectName('cfg_disable_caching_checkbox') self.cfg_disable_caching_checkbox.setToolTip(_('Force reload of reader database')) self.cfg_disable_caching_checkbox.setChecked(False) self.cfg_runtime_options_qvl.addWidget(self.cfg_disable_caching_checkbox) # ~~~~~~~~ plugin logging checkbox ~~~~~~~~ self.cfg_plugin_debug_log_checkbox = QCheckBox(_('Enable debug logging for Annotations plugin')) self.cfg_plugin_debug_log_checkbox.setObjectName('cfg_plugin_debug_log_checkbox') self.cfg_plugin_debug_log_checkbox.setToolTip(_('Print plugin diagnostic messages to console')) self.cfg_plugin_debug_log_checkbox.setChecked(False) self.cfg_runtime_options_qvl.addWidget(self.cfg_plugin_debug_log_checkbox) # ~~~~~~~~ libiMobileDevice logging checkbox ~~~~~~~~ self.cfg_libimobiledevice_debug_log_checkbox = QCheckBox(_('Enable debug logging for libiMobileDevice')) self.cfg_libimobiledevice_debug_log_checkbox.setObjectName('cfg_libimobiledevice_debug_log_checkbox') self.cfg_libimobiledevice_debug_log_checkbox.setToolTip(_('Print libiMobileDevice debug messages to console')) self.cfg_libimobiledevice_debug_log_checkbox.setChecked(False) self.cfg_libimobiledevice_debug_log_checkbox.setEnabled(LIBIMOBILEDEVICE_AVAILABLE) self.cfg_runtime_options_qvl.addWidget(self.cfg_libimobiledevice_debug_log_checkbox) # ~~~~~~~~ Create the Annotations options group box ~~~~~~~~ self.cfg_annotation_options_gb = QGroupBox(self) self.cfg_annotation_options_gb.setTitle(_('Annotation options')) self.l.addWidget(self.cfg_annotation_options_gb) self.cfg_annotation_options_qgl = QGridLayout(self.cfg_annotation_options_gb) current_row = 0 # Add the label/combobox for annotations destination self.cfg_annotations_destination_label = QLabel(_('<b>Add fetched annotations to<b>')) self.cfg_annotations_destination_label.setAlignment(Qt.AlignLeft) self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_destination_label, current_row, 0) current_row += 1 self.cfg_annotations_destination_comboBox = QComboBox(self.cfg_annotation_options_gb) self.cfg_annotations_destination_comboBox.setObjectName('cfg_annotations_destination_comboBox') self.cfg_annotations_destination_comboBox.setToolTip(_('Custom field to store annotations')) self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_destination_comboBox, current_row, 0) # Populate annotations_field combobox db = self.gui.current_db all_custom_fields = db.custom_field_keys() self.custom_fields = {} for custom_field in all_custom_fields: field_md = db.metadata_for_field(custom_field) if field_md['datatype'] in ['comments']: self.custom_fields[field_md['name']] = {'field': custom_field, 'datatype': field_md['datatype']} all_fields = self.custom_fields.keys() + ['Comments'] for cf in sorted(all_fields): self.cfg_annotations_destination_comboBox.addItem(cf) # Add CC Wizard self.cfg_annotations_wizard = QToolButton() self.cfg_annotations_wizard.setIcon(QIcon(I('wizard.png'))) self.cfg_annotations_wizard.setToolTip(_("Create a custom column to store annotations")) self.cfg_annotations_wizard.clicked.connect(partial(self.launch_cc_wizard, 'Annotations')) self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_wizard, current_row, 2) current_row += 1 # ~~~~~~~~ Add a horizontal line ~~~~~~~~ self.cfg_appearance_hl = QFrame(self) self.cfg_appearance_hl.setGeometry(QRect(0, 0, 1, 3)) self.cfg_appearance_hl.setFrameShape(QFrame.HLine) self.cfg_appearance_hl.setFrameShadow(QFrame.Raised) self.cfg_annotation_options_qgl.addWidget(self.cfg_appearance_hl, current_row, 0) current_row += 1 # ~~~~~~~~ Add the Modify… button ~~~~~~~~ self.cfg_annotations_appearance_pushbutton = QPushButton(_("Modify appearance…")) self.cfg_annotations_appearance_pushbutton.clicked.connect(self.configure_appearance) self.cfg_annotation_options_qgl.addWidget(self.cfg_annotations_appearance_pushbutton, current_row, 0) current_row += 1 self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.cfg_annotation_options_qgl.addItem(self.spacerItem, current_row, 0, 1, 1) # ~~~~~~~~ Compilations group box ~~~~~~~~ self.cfg_compilation_options_gb = QGroupBox(self) self.cfg_compilation_options_gb.setTitle(_('Compilations')) self.l.addWidget(self.cfg_compilation_options_gb) self.cfg_compilation_options_qgl = QGridLayout(self.cfg_compilation_options_gb) current_row = 0 # News clippings self.cfg_news_clippings_checkbox = QCheckBox(_('Collect News clippings')) self.cfg_news_clippings_checkbox.setObjectName('cfg_news_clippings_checkbox') self.cfg_compilation_options_qgl.addWidget(self.cfg_news_clippings_checkbox, current_row, 0) self.cfg_news_clippings_lineEdit = QLineEdit() self.cfg_news_clippings_lineEdit.setObjectName('cfg_news_clippings_lineEdit') self.cfg_news_clippings_lineEdit.setToolTip(_('Title for collected news clippings')) self.cfg_compilation_options_qgl.addWidget(self.cfg_news_clippings_lineEdit, current_row, 1) # ~~~~~~~~ End of construction zone ~~~~~~~~ self.resize(self.sizeHint()) # Restore state of controls, populate annotations combobox self.controls = inventory_controls(self, dump_controls=False) restore_state(self) self.populate_annotations() # Hook changes to annotations_destination_combobox # self.connect(self.cfg_annotations_destination_comboBox, # pyqtSignal('currentIndexChanged(const QString &)'), # self.annotations_destination_changed) self.cfg_annotations_destination_comboBox.currentIndexChanged.connect(self.annotations_destination_changed) # Hook changes to diagnostic checkboxes self.cfg_disable_caching_checkbox.stateChanged.connect(self.restart_required) self.cfg_libimobiledevice_debug_log_checkbox.stateChanged.connect(self.restart_required) self.cfg_plugin_debug_log_checkbox.stateChanged.connect(self.restart_required) # Hook changes to News clippings, initialize self.cfg_news_clippings_checkbox.stateChanged.connect(self.news_clippings_toggled) self.news_clippings_toggled(self.cfg_news_clippings_checkbox.checkState()) self.cfg_news_clippings_lineEdit.editingFinished.connect(self.news_clippings_destination_changed) # Launch the annotated_books_scanner field = get_cc_mapping('annotations', 'field', 'Comments') self.annotated_books_scanner = InventoryAnnotatedBooks(self.gui, field) self.annotated_books_scanner.signal.connect(self.inventory_complete) # self.connect(self.annotated_books_scanner, self.annotated_books_scanner.signal, # self.inventory_complete) QTimer.singleShot(1, self.start_inventory) def annotations_destination_changed(self, qs_new_destination_name): ''' If the destination field changes, move all existing annotations from old to new ''' self._log_location(repr(qs_new_destination_name)) self._log("self.custom_fields: %s" % self.custom_fields) old_destination_field = get_cc_mapping('annotations', 'field', None) if old_destination_field and not (old_destination_field in self.gui.current_db.custom_field_keys() or old_destination_field == 'Comments'): return old_destination_name = get_cc_mapping('annotations', 'combobox', None) self._log("old_destination_field: %s" % old_destination_field) self._log("old_destination_name: %s" % old_destination_name) # Catch initial change from None to Comments - first run only if old_destination_field is None: return # new_destination_name = unicode(qs_new_destination_name) new_destination_name = unicode(self.cfg_annotations_destination_comboBox.currentText()) self._log("new_destination_name: %s" % new_destination_name) if old_destination_name == new_destination_name: self._log_location("old_destination_name = new_destination_name, no changes") return new_destination_field = None if new_destination_name == 'Comments': new_destination_field = 'Comments' else: new_destination_field = self.custom_fields[new_destination_name]['field'] if existing_annotations(self.opts.parent, old_destination_field): command = self.launch_new_destination_dialog(old_destination_name, new_destination_name) if command == 'move': set_cc_mapping('annotations', field=new_destination_field, combobox=new_destination_name) if self.annotated_books_scanner.isRunning(): self.annotated_books_scanner.wait() move_annotations(self, self.annotated_books_scanner.annotation_map, old_destination_field, new_destination_field) elif command == 'change': # Keep the updated destination field, but don't move annotations pass elif command == 'cancel': # Restore previous destination self.cfg_annotations_destination_comboBox.blockSignals(True) old_index = self.cfg_annotations_destination_comboBox.findText(old_destination_name) self.cfg_annotations_destination_comboBox.setCurrentIndex(old_index) self.cfg_annotations_destination_comboBox.blockSignals(False) """ # Warn user that change will move existing annotations to new field title = 'Move annotations?' msg = ("<p>Existing annotations will be moved from <b>%s</b> to <b>%s</b>.</p>" % (old_destination_name, new_destination_name) + "<p>New annotations will be added to <b>%s</b>.</p>" % new_destination_name + "<p>Proceed?</p>") d = MessageBox(MessageBox.QUESTION, title, msg, show_copy_button=False) self._log_location("QUESTION: %s" % msg) if d.exec_(): set_cc_mapping('annotations', field=new_destination_field, combobox=new_destination_name) if self.annotated_books_scanner.isRunning(): self.annotated_books_scanner.wait() move_annotations(self, self.annotated_books_scanner.annotation_map, old_destination_field, new_destination_field) else: self.cfg_annotations_destination_comboBox.blockSignals(True) old_index = self.cfg_annotations_destination_comboBox.findText(old_destination_name) self.cfg_annotations_destination_comboBox.setCurrentIndex(old_index) self.cfg_annotations_destination_comboBox.blockSignals(False) """ else: # No existing annotations, just update prefs set_cc_mapping('annotations', field=new_destination_field, combobox=new_destination_name) def configure_appearance(self): ''' ''' from calibre_plugins.annotations.appearance import default_elements from calibre_plugins.annotations.appearance import default_timestamp appearance_settings = { 'appearance_css': default_elements, 'appearance_hr_checkbox': False, 'appearance_timestamp_format': default_timestamp } # Save, hash the original settings original_settings = {} osh = hashlib.md5() for setting in appearance_settings: original_settings[setting] = plugin_prefs.get(setting, appearance_settings[setting]) osh.update(repr(plugin_prefs.get(setting, appearance_settings[setting]))) # Display the appearance dialog aa = AnnotationsAppearance(self, get_icon('images/annotations.png'), plugin_prefs) cancelled = False if aa.exec_(): # appearance_hr_checkbox and appearance_timestamp_format changed live to prefs during previews plugin_prefs.set('appearance_css', aa.elements_table.get_data()) # Generate a new hash nsh = hashlib.md5() for setting in appearance_settings: nsh.update(repr(plugin_prefs.get(setting, appearance_settings[setting]))) else: for setting in appearance_settings: plugin_prefs.set(setting, original_settings[setting]) nsh = osh # If there were changes, and there are existing annotations, offer to re-render field = get_cc_mapping('annotations', 'field', None) if osh.digest() != nsh.digest() and existing_annotations(self.opts.parent,field): title = _('Update annotations?') msg = _('<p>Update existing annotations to new appearance settings?</p>') d = MessageBox(MessageBox.QUESTION, title, msg, show_copy_button=False) self._log_location("QUESTION: %s" % msg) if d.exec_(): self._log_location("Updating existing annotations to modified appearance") if self.annotated_books_scanner.isRunning(): self.annotated_books_scanner.wait() move_annotations(self, self.annotated_books_scanner.annotation_map, field, field, window_title=_("Updating appearance")) def inventory_complete(self, msg): self._log_location(msg) def launch_cc_wizard(self, column_type): ''' ''' def _update_combo_box(comboBox, destination, previous): ''' ''' self._log_location() cb = getattr(self, comboBox) cb.blockSignals(True) all_items = [str(cb.itemText(i)) for i in range(cb.count())] if previous and previous in all_items: all_items.remove(previous) all_items.append(destination) cb.clear() cb.addItems(sorted(all_items, key=lambda s: s.lower())) # Select the new destination in the comboBox idx = cb.findText(destination) if idx > -1: cb.setCurrentIndex(idx) # Process the changed destination self.annotations_destination_changed(destination) cb.blockSignals(False) klass = os.path.join(dialog_resources_path, 'cc_wizard.py') if os.path.exists(klass): #self._log("importing CC Wizard dialog from '%s'" % klass) sys.path.insert(0, dialog_resources_path) this_dc = importlib.import_module('cc_wizard') sys.path.remove(dialog_resources_path) dlg = this_dc.CustomColumnWizard(self, column_type, self.WIZARD_PROFILES[column_type], verbose=True) dlg.exec_() if dlg.modified_column: self._log("modified_column: %s" % dlg.modified_column) destination = dlg.modified_column['destination'] label = dlg.modified_column['label'] previous = dlg.modified_column['previous'] source = dlg.modified_column['source'] self._log("destination: %s" % destination) self._log("label: %s" % label) self._log("previous: %s" % previous) self._log("source: %s" % source) if source == "Annotations": # Add/update the new destination so save_settings() can find it if destination in self.custom_fields: self.custom_fields[destination]['field'] = label else: self.custom_fields[destination] = {'field': label} _update_combo_box('cfg_annotations_destination_comboBox', destination, previous) # Save field manually in case user cancels #self.prefs.set('cfg_annotations_destination_comboBox', destination) #self.prefs.set('cfg_annotations_destination_field', label) set_cc_mapping('annotations', field=label, combobox=destination) # Inform user to restart self.restart_required('custom_column') else: self._log("ERROR: Can't import from '%s'" % klass) def launch_new_destination_dialog(self, old, new): ''' Return 'move', 'change' or 'cancel' ''' self._log_location() klass = os.path.join(dialog_resources_path, 'new_destination.py') if os.path.exists(klass): self._log("importing new destination dialog from '%s'" % klass) sys.path.insert(0, dialog_resources_path) this_dc = importlib.import_module('new_destination') sys.path.remove(dialog_resources_path) dlg = this_dc.NewDestinationDialog(self, old, new) dlg.exec_() return dlg.command def news_clippings_destination_changed(self): qs_new_destination_name = self.cfg_news_clippings_lineEdit.text() if not re.match(r'^\S+[A-Za-z0-9 ]+$', qs_new_destination_name): # Complain about News clippings title title = _('Invalid title for News clippings') msg = _("Supply a valid title for News clippings, for example 'My News Clippings'.") d = MessageBox(MessageBox.WARNING, title, msg, show_copy_button=False) self._log_location("WARNING: %s" % msg) d.exec_() def news_clippings_toggled(self, state): if state == Qt.Checked: self.cfg_news_clippings_lineEdit.setEnabled(True) else: self.cfg_news_clippings_lineEdit.setEnabled(False) def populate_annotations(self): ''' Restore annotations combobox ''' self._log_location() target = 'Comments' existing = get_cc_mapping('annotations', 'combobox') if existing: target = existing ci = self.cfg_annotations_destination_comboBox.findText(target) self.cfg_annotations_destination_comboBox.setCurrentIndex(ci) def restart_required(self, state): title = _('Restart required') msg = _('To apply changes, restart calibre.') d = MessageBox(MessageBox.WARNING, title, msg, show_copy_button=False) self._log_location("WARNING: %s" % (msg)) d.exec_() def save_settings(self): save_state(self) # Save the annotation destination field ann_dest = unicode(self.cfg_annotations_destination_comboBox.currentText()) self._log_location("INFO: ann_dest=%s" % (ann_dest)) self._log_location("INFO: self.custom_fields=%s" % (self.custom_fields)) if ann_dest == 'Comments': set_cc_mapping('annotations', field='Comments', combobox='Comments') elif ann_dest: set_cc_mapping('annotations', field=self.custom_fields[ann_dest]['field'], combobox=ann_dest) def start_inventory(self): self.annotated_books_scanner.start()
class AnnotationsAppearance(SizePersistedDialog): ''' Dialog for managing CSS rules, including Preview window ''' if isosx: FONT = QFont('Monaco', 12) elif iswindows: FONT = QFont('Lucida Console', 9) elif islinux: FONT = QFont('Monospace', 9) FONT.setStyleHint(QFont.TypeWriter) def __init__(self, parent, icon, prefs): self.opts = parent.opts self.parent = parent self.prefs = prefs self.icon = icon super(AnnotationsAppearance, self).__init__(parent, 'appearance_dialog') self.setWindowTitle('Annotations appearance') self.setWindowIcon(icon) self.l = QVBoxLayout(self) self.setLayout(self.l) # Add a label for description #self.description_label = QLabel("Descriptive text here") #self.l.addWidget(self.description_label) # Add a group box, vertical layout for preview window self.preview_gb = QGroupBox(self) self.preview_gb.setTitle("Preview") self.preview_vl = QVBoxLayout(self.preview_gb) self.l.addWidget(self.preview_gb) self.wv = QWebView() self.wv.setHtml('<p></p>') self.wv.setMinimumHeight(100) self.wv.setMaximumHeight(16777215) self.wv.setGeometry(0, 0, 200, 100) self.wv.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.preview_vl.addWidget(self.wv) # Create a group box, horizontal layout for the table self.css_table_gb = QGroupBox(self) self.css_table_gb.setTitle("Annotation elements") self.elements_hl = QHBoxLayout(self.css_table_gb) self.l.addWidget(self.css_table_gb) # Add the group box to the main layout self.elements_table = AnnotationElementsTable(self, 'annotation_elements_tw') self.elements_hl.addWidget(self.elements_table) self.elements_table.initialize() # Options self.options_gb = QGroupBox(self) self.options_gb.setTitle("Options") self.options_gl = QGridLayout(self.options_gb) self.l.addWidget(self.options_gb) current_row = 0 # <hr/> separator # addWidget(widget, row, col, rowspan, colspan) self.hr_checkbox = QCheckBox('Add horizontal rule between annotations') self.hr_checkbox.stateChanged.connect(self.hr_checkbox_changed) self.hr_checkbox.setCheckState( prefs.get('appearance_hr_checkbox', False)) self.options_gl.addWidget(self.hr_checkbox, current_row, 0, 1, 4) current_row += 1 # Timestamp self.timestamp_fmt_label = QLabel("Timestamp format:") self.options_gl.addWidget(self.timestamp_fmt_label, current_row, 0) self.timestamp_fmt_le = QLineEdit( prefs.get('appearance_timestamp_format', default_timestamp), parent=self) self.timestamp_fmt_le.textEdited.connect(self.timestamp_fmt_changed) self.timestamp_fmt_le.setFont(self.FONT) self.timestamp_fmt_le.setObjectName('timestamp_fmt_le') self.timestamp_fmt_le.setToolTip('Format string for timestamp') self.timestamp_fmt_le.setMaximumWidth(16777215) self.timestamp_fmt_le.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum) self.options_gl.addWidget(self.timestamp_fmt_le, current_row, 1) self.timestamp_fmt_reset_tb = QToolButton(self) self.timestamp_fmt_reset_tb.setToolTip("Reset to default") self.timestamp_fmt_reset_tb.setIcon(QIcon(I('trash.png'))) self.timestamp_fmt_reset_tb.clicked.connect(self.reset_timestamp_to_default) self.options_gl.addWidget(self.timestamp_fmt_reset_tb, current_row, 2) self.timestamp_fmt_help_tb = QToolButton(self) self.timestamp_fmt_help_tb.setToolTip("Format string reference") self.timestamp_fmt_help_tb.setIcon(QIcon(I('help.png'))) self.timestamp_fmt_help_tb.clicked.connect(self.show_help) self.options_gl.addWidget(self.timestamp_fmt_help_tb, current_row, 3) # Button box bb = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.l.addWidget(bb) # Spacer #self.spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) #self.l.addItem(self.spacerItem) # Sizing #sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) #sizePolicy.setHorizontalStretch(0) #sizePolicy.setVerticalStretch(0) #sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) #self.setSizePolicy(sizePolicy) self.resize_dialog() def hr_checkbox_changed(self, state): self.prefs.set('appearance_hr_checkbox', state) self.prefs.commit() self.elements_table.preview_css() def reset_timestamp_to_default(self): from calibre_plugins.marvin_manager.appearance import default_timestamp self.timestamp_fmt_le.setText(default_timestamp) self.timestamp_fmt_changed() def show_help(self): ''' Display strftime help file ''' from calibre.gui2 import open_url path = os.path.join(self.parent.resources_path, 'help/timestamp_formats.html') open_url(QUrl.fromLocalFile(path)) def sizeHint(self): return QtCore.QSize(600, 200) def timestamp_fmt_changed(self): self.prefs.set('appearance_timestamp_format', str(self.timestamp_fmt_le.text())) self.prefs.commit() self.elements_table.preview_css()
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)
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_()