def __init__(self, parentWidget): QWidget.__init__(self, parentWidget) self.formatManager = FormatManager() self.formatManager.loadFormats() self.editView = StylableTextEdit(self, self.formatManager) self.editView.navigate.connect(self.navigate) self.editView.objectSelectionChanged.connect(self.objectSelectionChanged) toolbar = QWidget(self) layout = QHBoxLayout() layout.setContentsMargins(0,0,0,0) toolbar.setLayout(layout) self.actionsSelector = ActionSelector(self) layout.addWidget(self.actionsSelector) self.textFormatSelector = TextStyleSelector(self) self.textFormatSelector.styleChanged.connect(self.editView.applyTextFormat) self.editView.updateCharFormat.connect(self.textFormatSelector.setCurrentStyle) layout.addWidget(self.textFormatSelector) self.styleSelector = BlockStyleSelector(self) self.styleSelector.styleChanged.connect(self.editView.applyBlockStyle) self.styleSelector.indentLess.connect(self.editView.indentLess) self.styleSelector.indentMore.connect(self.editView.indentMore) self.styleSelector.insertTable.connect(self.insertTable) self.editView.updateBlockFormat.connect(self.styleSelector.setCurrentStyle) layout.addWidget(self.styleSelector) searchMarker = self.formatManager.getFormat( ('searchMarker', None, None) ) self.findWidget = FindWidget(self, searchMarker.getCharFormat(), self.editView) self.findWidget.hide() self.editMathWidget = MathEditWidget(self) self.editMathWidget.apply.connect(self.applyMathFormula) self.editMathWidget.hide() #horizontalSpacer = QSpacerItem(0, 0) # 40, 20) # , QSizePolicy.Expanding, QSizePolicy.Minimum) #layout.addItem(horizontalSpacer) hLayout = QVBoxLayout(self) hLayout.setContentsMargins(0, 0, 0, 0) hLayout.addWidget(toolbar) hLayout.addWidget(self.findWidget) hLayout.addWidget(self.editView) hLayout.addWidget(self.editMathWidget) # The toolbar should take the minimum space and the edit view the remaining space hLayout.setStretch(0, 0) hLayout.setStretch(1, 0) hLayout.setStretch(2, 1) hLayout.setStretch(3, 0.1)
def __init__(self): super().__init__() # Data storage self.driverMap = {} self.gunnerMap = {} self.dProfileMapXbox = [{}] self.dProfileMapJoystick = [{}] self.gProfileMapXbox = [{}] self.gProfileMapJoystick = [{}] # Init interface mainLayout = QHBoxLayout() leftHalf = QGroupBox('Controller Info') rightHalf = QGroupBox('Assigned Maps') vertLeft = QVBoxLayout() vertLeft.setStretch(0, 0) vertLeft.setSpacing(2) vertLeft.addWidget(QLabel('Profile Name')) self.profileName = QLineEdit() self.profileName.textEdited.connect(self.update_submit) vertLeft.addWidget(self.profileName) typeChoosers = QHBoxLayout() self.pilot = QComboBox() self.pilot.addItems(['Driver', 'Gunner']) typeChoosers.addWidget(self.pilot) self.controller = QComboBox() self.controller.addItems(['Xbox Compatible', 'Joystick']) typeChoosers.addWidget(self.controller) vertLeft.addLayout(typeChoosers) keyConfig = QHBoxLayout() keys = QVBoxLayout() keys.addWidget(QLabel('Key')) self.key = QLineEdit() self.key.textEdited.connect(self.update_submit) keys.addWidget(self.key) ports = QVBoxLayout() ports.addWidget(QLabel('Port')) self.port = QSpinBox() self.port.setFixedWidth(110) ports.addWidget(self.port) keyConfig.addLayout(keys) keyConfig.addLayout(ports) vertLeft.addLayout(keyConfig) vertLeft.addStretch() importJSON = QPushButton() importJSON.setText('Import from JSON') importJSON.clicked.connect(self.import_json) self.submit = QPushButton() self.submit.setText('Add Entry to List') self.submit.clicked.connect(self.process_data) self.submit.setEnabled(False) vertLeft.addWidget(self.submit) vertLeft.addWidget(importJSON) leftHalf.setLayout(vertLeft) mainLayout.addWidget(leftHalf) self.profileList = QTableWidget(0, 2) rightVert = QVBoxLayout() rightVert.setSpacing(2) self.profiles = QComboBox() self.profiles.addItems(self.get_profile_names('driver')) self.profiles.currentTextChanged.connect(self.update_list) self.profiles.setEnabled(False) listSelectors = QHBoxLayout() listSelectors.addWidget(self.profiles) self.pilotSource = QComboBox() self.pilotSource.addItems(['Driver', 'Gunner']) self.pilotSource.currentTextChanged.connect(self.update_profiles) self.controllerSource = QComboBox() self.controllerSource.addItems(['Xbox Compatible', 'Joystick']) self.controllerSource.currentTextChanged.connect(self.update_list) rightVert.addWidget(self.pilotSource) listSelectors.addWidget(self.controllerSource) rightVert.addLayout(listSelectors) # Table self.reset_table() rightVert.addWidget(self.profileList) rightVert.addStretch() listControls = QHBoxLayout() self.removeItem = QPushButton('Remove Entry') self.removeItem.setDisabled(True) self.removeItem.clicked.connect(self.remove_list_item) listControls.addWidget(self.removeItem) self.removeProfile = QPushButton('Remove Profile') self.removeProfile.setDisabled(True) self.removeProfile.clicked.connect(self.remove_profile) listControls.addWidget(self.removeProfile) self.export = QPushButton("Export to JSON") self.export.clicked.connect(self.export_json) self.export.setEnabled(True) rightVert.addLayout(listControls) rightVert.addWidget(self.export) rightHalf.setLayout(rightVert) mainLayout.addWidget(rightHalf) self.init_gui(mainLayout)
class ObjectFactory(QWidget): """Enables creation of new type instances.""" def __init__(self, *args): """Constructor.""" super().__init__(*args) # Cache. self.types = TypeCacheModel() self.init_types() # Set size and position. screen = QtWidgets.QDesktopWidget().screenGeometry(0) self.resize(int(screen.width() * 0.7), int(screen.height() * 0.7)) self.move(int(screen.width() * 0.15), int(screen.height() * 0.15)) # Set window type. flags = QtCore.Qt.WindowFlags(QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint) self.setWindowFlags(flags) self.layout = QVBoxLayout() self.layout.setContentsMargins(50, 50, 50, 50) # Pinned types. self.hotbar = QToolBar() self.hotbar.setStyleSheet("QToolBar { }") for index in range(self.types.pinned_count()): t = self.types.pinned_type(index) url = urlparse(t.icon) icon = QIcon(url.path) action = QAction(icon, t.name, qApp) self.hotbar.addAction(action) self.layout.addWidget(self.hotbar) # Search bar. self.omnibox = QHBoxLayout() self.omnibox.setContentsMargins(20, 20, 20, 20) self.omnitext = QLineEdit() self.omnitext.setStyleSheet( "QLineEdit { font-size: 20px; padding: 12px; border: none; border-radius: 10px; }" ) self.omnitext.setFrame(False) # Doesn't seem to do anything' self.omnitext.setAttribute(QtCore.Qt.WA_MacShowFocusRect, False) self.omnitext.setPlaceholderText("Search ...") self.omnitext.setClearButtonEnabled(True) self.omnitext.setTextMargins(20, 20, 20, 20) self.omnibox.addWidget(self.omnitext) self.layout.addLayout(self.omnibox) # Unfiltered types, MRU order (?) self.object_table = QVBoxLayout() self.object_table.setContentsMargins(20, 20, 20, 20) row1 = QLabel("line") self.object_table.addWidget(row1) self.layout.addLayout(self.object_table) self.layout.setStretch(2, 100) self.setLayout(self.layout) self.hide() return def init_types(self): """Initialize types collection.""" # List of known types, with index by name, by last use, and by # keyword from their description. Each type has a name, icon, and # a description. # # There's also an ordered list of "pinned" types. text = Type() text.name = "Text" text.description = "Unformatted Unicode document" text.impl = "file:///Users/d/work/personal/darqos/darq/types/text.py" text.icon = "file:///Users/d/work/personal/darqos/darq/icons/txt.png" self.types.add_type(text) self.types.append_pinned_type("Text") book = Type() book.name = "Book Details" book.description = "Catalog data for a book" book.impl = "" book.icon = "file:///Users/d/work/personal/darqos/darq/icons/book.png" self.types.add_type(book) self.types.append_pinned_type("Book Details") return def on_create(self): o = TextTypeView() self.hide() return
class YouDao(QMainWindow): def __init__(self): super().__init__() self.initUI() def iconActivated(self, reason): # reason 没有 QSystemTrayIcon.DoubleClick if self.isHidden(): self.show() else: self.hide() def closeEvent(self, event): self.hide() event.ignore() def open(self): self.show() def clearTextClicked(self): self.textEdit.clear() self.preview.clear() def keyPressEvent(self, event): if event.key() == Qt.Key_Return: self.confirmClicked() else: super(YouDao, self).keyPressEvent(event) def confirmClicked(self): q = self.textEdit.toPlainText() # 要翻译的内容为空 if not q.strip(): alert = QMessageBox(self) alert.setText("你什么也没有输入!!!") alert.exec() return data = translate(q) # 没有数据就用本地词典 if not data: key, value = localtran(q) if key and value: self.preview.setHtml('<i>翻译:</i>{}'.format(value)) else: alert = QMessageBox(self) alert.setText("出错了") alert.exec() return usPhonetic = '' ukPhonetic = '' translation = '' web = '' html = ''' <html> <head></head> <body> <p>{translation}</p> {uk-phonetic} {us-phonetic} {web} </body> </html> ''' if data.get('translation'): translation = '<i>翻译:</i>' + \ ''.join(data.get('translation')) + '<br>' if data.get('basic'): translation += '<br>'.join(data.get('basic').get('explains')) if data.get('basic').get('us-phonetic'): usPhonetic = '<h6>英音:<span>[{}]</span></h6>'.format( data.get('basic').get('us-phonetic')) if data.get('basic').get('uk-phonetic'): ukPhonetic = '<h6>美音:<span>[{}]</span></h6>'.format( data.get('basic').get('uk-phonetic')) if data.get('web'): web = '网络释义:' + '<br>'.join(','.join(value.get('value')) for value in data.get('web')) values = { 'translation': translation, 'us-phonetic': usPhonetic, 'uk-phonetic': ukPhonetic, 'web': web } self.preview.setHtml(html.format(**values)) def initUI(self): # 系统托盘 self.trayIcon = QSystemTrayIcon(self) self.trayIcon.setIcon(QIcon(os.path.join(baseDir, "youdao.png"))) self.openAction = QAction(QIcon(os.path.join(baseDir, "search.png")), "查单词", self) self.openAction.triggered.connect(self.open) self.settingAction = QAction( QIcon(os.path.join(baseDir, "setting.png")), "设置", self) self.quitAction = QAction("退出", self) self.quitAction.triggered.connect(QCoreApplication.quit) self.qMenu = QMenu(self) self.qMenu.addAction(self.openAction) self.qMenu.addAction(self.settingAction) self.qMenu.addSeparator() self.qMenu.addAction(self.quitAction) self.trayIcon.setContextMenu(self.qMenu) self.trayIcon.activated[QSystemTrayIcon.ActivationReason].connect( self.iconActivated) self.centralWidget = QWidget(self) self.header = QWidget(self) self.textEdit = QPlainTextEdit(self.header) self.textEdit.setPlaceholderText('请输入') self.textEdit.setStyleSheet( "QWidget{font-size: 18px;background: #f2f2f2}") def enterKeyPressEvent(event): if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter: self.confirmClicked() else: QPlainTextEdit.keyPressEvent(self.textEdit, event) # 重写QPlainTextEdit的enter事件,enter确认 self.textEdit.keyPressEvent = enterKeyPressEvent self.clearText = QPushButton("清除") self.clearText.setStyleSheet("QPushButton{background: #ffffff;}") self.clearText.clicked.connect(self.clearTextClicked) self.confirm = QPushButton("翻译") self.confirm.clicked.connect(self.confirmClicked) self.confirm.setStyleSheet( "QPushButton{background: #e02433;color: #ffffff}") grid = QGridLayout() grid.setSpacing(5) grid.setContentsMargins(0, 0, 0, 0) # 控件, 第几行,第几列,占几行,占几列 grid.addWidget(self.textEdit, 0, 0, 1, 2) grid.addWidget(self.clearText, 1, 0, 1, 1) grid.addWidget(self.confirm, 1, 1, 1, 1) self.header.setLayout(grid) self.preview = QTextEdit() self.preview.setReadOnly(True) self.preview.setPlaceholderText('这里什么都没有。。。') self.hbox = QVBoxLayout(self.centralWidget) self.hbox.setContentsMargins(6, 6, 6, 6) self.hbox.addWidget(self.header) self.hbox.addWidget(self.preview) self.hbox.setStretch(0, 1) self.hbox.setStretch(1, 2) self.setCentralWidget(self.centralWidget) self.setWindowTitle('有道词典') self.setWindowIcon(QIcon(os.path.join(baseDir, 'youdao.png'))) self.setFixedSize(350, 400) self.center() # self.setFocusPolicy(Qt.StrongFocus) self.show() self.trayIcon.show() def center(self): screen = QDesktopWidget().screenGeometry() size = self.geometry() self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)
def __init__(self): QWidget.__init__(self) self.resize(1080, 720) #上方布局 #left(up_l) up_l = QVBoxLayout() self.btn_local = QPushButton("从文件打开") self.btn_db = QPushButton("从数据库打开") up_l.addWidget(self.btn_local) up_l.addWidget(self.btn_db) #middle self.progress = Progress() #right self.btn_run = QPushButton("运行") self.btn_run.clicked.connect(self.run) self.btn_clear = QPushButton("Clear") self.btn_clear.clicked.connect(self.on_btn_clear_clicked) self.btn_exit = QPushButton("退出") self.btn_exit.clicked.connect(QCoreApplication.quit) self.btn_local.clicked.connect(self.data_local) #下方布局 #left(down_l) down_l = QVBoxLayout() self.label_in = QLabel("输入数据") self.label_in.setAlignment(Qt.AlignCenter) self.label_in.setContentsMargins(5, 5, 5, 0) self.list_in = List() self.label_out = QLabel("输出数据") self.label_out.setAlignment(Qt.AlignCenter) #居中对齐 self.list_out = List() self.list_in.update_.connect(self.on_listItem_click) self.list_out.update_.connect(self.on_listOutItem_click) down_l.addWidget(self.label_in) down_l.addWidget(self.list_in) down_l.addWidget(self.label_out) down_l.addWidget(self.list_out) down_l.setStretch(0, 1) down_l.setStretch(1, 7) down_l.setStretch(2, 1) down_l.setStretch(3, 7) down_l.setSpacing(0) #middle(tabs) self.tabs = Tabs() #right self.oprea = OperateList() self.oprea.clickBtn_.connect(self.operateChoose) #设置UI上下方布局为水平布局 #up layout_up = QHBoxLayout() layout_up.addLayout(up_l) layout_up.addWidget(self.progress) layout_up.addWidget(self.btn_run) # layout_up.addWidget(self.btn_clear) layout_up.addWidget(self.btn_exit) layout_up.setStretch(0, 2) layout_up.setStretch(1, 8) layout_up.setStretch(2, 1) layout_up.setStretch(3, 1) layout_up.setStretch(4, 1) #down layout_down = QHBoxLayout() # layout_down.addWidget(text_test_down) layout_down.addLayout(down_l) layout_down.addWidget(self.tabs) layout_down.addWidget(self.oprea) layout_down.setStretch(0, 1) layout_down.setStretch(1, 3) layout_down.setStretch(2, 1) #设置UI总体布局 layout_main = QVBoxLayout() layout_main.addLayout(layout_up) layout_main.addLayout(layout_down) layout_main.setStretch(0, 1) layout_main.setStretch(1, 10) self.setLayout(layout_main)
def initUI(self): self.funList = open("scripts/funlist.txt", "r").read().split("\n") if self.funList[-1] == '': self.funList = self.funList[:-1] self.setWindowTitle("Robots' Search") self.setGeometry(500, 500, 500, 500) self.setWindowIcon(QIcon('robot_reader/utils/robot.png')) self.infoLabel = QLabel('here we provide some tips like flag usage ') self.searchButton = QPushButton('search') self.searchButton.setToolTip('click to run your search') self.searchButton.clicked.connect(self.search) # self.sgdclfiButton = QRadioButton("Klasyfikator SGD") # self.sgdclfiButton.setChecked(True) # self.sgdclfiButton.setToolTip("kosinus kąta pomiędzy dwoma wektorami reprezentującymi dokumentów") # self.distcosButton = QRadioButton("Dystans Kosinusowy") # self.distcosButton.setChecked(True) # self.distcosButton.setToolTip("klasyfikator liniowy wykorzystujący Stochastic Gradient Descent") self.bow = QRadioButton("Bag of Words") self.bow.setChecked(True) self.bow.setToolTip("dokumenty reprezentowane jako 'bag of words'") self.queryTextEdit = QTextEdit() self.queryTextEdit.setToolTip('type in your query') self.queryTextEdit.setMaximumHeight(25) vbox2 = QVBoxLayout() vbox2.addWidget(self.queryTextEdit) vbox2.setStretch(1, 0) self.recordNumber = QSpinBox() self.recordNumber.setMinimum(10) self.recordNumber.setMaximum(90) vbox2.addWidget(self.recordNumber) vbox = QVBoxLayout() #vbox.addWidget(self.infoLabel, alignment=QtCore.Qt.AlignLeft) vbox.addLayout(vbox2) hbox2 = QHBoxLayout() # hbox2.addWidget(self.sgdclfiButton) # hbox2.addWidget(self.distcosButton) hbox2.addWidget(self.bow) hbox2.addWidget(self.searchButton) vbox.addLayout(hbox2) # self.loading = QLabel() # vbox.addWidget(self.loading, alignment=QtCore.Qt.AlignCenter) hbox = QHBoxLayout() self.resultList = QListWidget() self.resultList.currentItemChanged.connect(self.setFileContent) hbox.addWidget(self.resultList) self.fileContent = QLabel() self.fileContent.setTextFormat(Qt.RichText) self.fileContent.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.contentScroll = QScrollArea() self.contentScroll.setWidgetResizable(True) self.contentScroll.setWidget(self.fileContent) hbox.addWidget(self.contentScroll) vbox.addLayout(hbox) self.setLayout(vbox) self.show()
def __init__(self, parent=None): super(Window, self).__init__(parent) self._plot_ref = None self.closed_loop_ref = None self.bode_plot_ref = None self.state_plot_refs = [] self.pz_plot_refs = [] self.file_name = None self.is_system_identified = False self.axis = 0 self.dt = 0.005 self.rise_time = 0.13 self.damping_index = 0.0 self.detune_coeff = 0.5 self.kc = 0.0 self.ki = 0.0 self.kd = 0.0 self.figure = plt.figure(1) self.figure.subplots_adjust(hspace=0.5, wspace=1.0) self.num = [] self.den = [] self.sys_id_delays = 1 self.sys_id_n_zeros = 2 self.sys_id_n_poles = 2 # this is the Canvas Widget that displays the `figure` # it takes the `figure` instance as a parameter to __init__ self.canvas = FigureCanvas(self.figure) # this is the Navigation widget # it takes the Canvas widget and a parent self.toolbar = NavigationToolbar(self.canvas, self) self.btn_open_log = QPushButton("Open log") self.btn_open_log.clicked.connect(self.loadLog) # set the layout layout_v = QVBoxLayout() layout_h = QHBoxLayout() left_menu = QVBoxLayout() left_menu.addWidget(self.btn_open_log) xyz_group = QHBoxLayout() r_x = QRadioButton("x") r_x.setChecked(True) r_y = QRadioButton("y") r_z = QRadioButton("z") xyz_group.addWidget(QLabel("Axis")) xyz_group.addWidget(r_x) xyz_group.addWidget(r_y) xyz_group.addWidget(r_z) r_x.clicked.connect(self.loadXData) r_y.clicked.connect(self.loadYData) r_z.clicked.connect(self.loadZData) left_menu.addLayout(xyz_group) pz_group = QFormLayout() self.line_edit_zeros = QSpinBox() self.line_edit_zeros.setValue(self.sys_id_n_zeros) self.line_edit_zeros.setRange(0, 6) self.line_edit_zeros.valueChanged.connect(self.onZerosChanged) pz_group.addRow(QLabel("Zeros"), self.line_edit_zeros) self.line_edit_poles = QSpinBox() self.line_edit_poles.setValue(self.sys_id_n_poles) self.line_edit_poles.setRange(0, 6) self.line_edit_poles.valueChanged.connect(self.onPolesChanged) pz_group.addRow(QLabel("Poles"), self.line_edit_poles) self.line_edit_delays = QSpinBox() self.line_edit_delays.setValue(self.sys_id_delays) self.line_edit_delays.setRange(1, 1000) self.line_edit_delays.valueChanged.connect(self.onDelaysChanged) pz_group.addRow(QLabel("Delays"), self.line_edit_delays) self.btn_run_sys_id = QPushButton("Run identification") self.btn_run_sys_id.clicked.connect(self.onSysIdClicked) self.btn_run_sys_id.setEnabled(False) pz_group.addRow(self.btn_run_sys_id) left_menu.addLayout(pz_group) layout_tf = self.createTfLayout() left_menu.addLayout(layout_tf) offset_group = QFormLayout() self.line_edit_offset = QDoubleSpinBox() self.line_edit_offset.setValue(0.0) self.line_edit_offset.setRange(-10.0, 10.0) self.line_edit_offset.textChanged.connect(self.onOffsetChanged) offset_group.addRow(QLabel("Offset"), self.line_edit_offset) left_menu.addLayout(offset_group) left_menu.addStretch(1) layout_gmvc = self.createGmvcLayout() layout_pid = self.createPidLayout() layout_controller = QHBoxLayout() layout_controller.addLayout(layout_gmvc) layout_controller.addLayout(layout_pid) layout_plot = QVBoxLayout() layout_h.addLayout(left_menu) layout_h.addLayout(layout_plot) layout_h.setStretch(1, 1) layout_plot.addWidget(self.toolbar) layout_plot.addWidget(self.canvas) layout_v.addLayout(layout_h) layout_v.setStretch(0, 1) layout_v.addLayout(layout_controller) self.setLayout(layout_v)
class ImportWidget(QWidget): def __init__(self): super().__init__() self.init_gui() def read_sheet(self, file_data, sheet_name): self.model.clear() for row in file_data[sheet_name]: items = [QStandardItem(str(field)) for field in row] self.model.appendRow(items) def open_filename(self): filename = QFileDialog.getOpenFileName( self, self.tr("Abrir archivo"), "/home/luciano", self.tr("Hojas de Cálculo (*.ods)")) if filename[0] != "": self._enable_widgets(True) self.file_data = get_data(filename[0]) for key in self.file_data.keys(): self.cmb_ods_sheets.addItem(key) self.read_sheet(self.file_data, list(self.file_data.keys())[0]) def import_expenses(self): try: row = int(self.le_initial_row.text()) - 1 description_col = int(self.le_description_col.text()) - 1 date_col = int(self.le_date_col.text()) - 1 default_date = self.default_date.date() date_format = self.le_date_format.text() percent = 1.0 / len(list(self.current_group.getMembers())) while self.model.item(row) is not None: print("Row ", row) expense = Expense() expense.setDescription( self.model.item(row, description_col).text()) print("Expense: ", expense.getDescription()) date = QDate.fromString( self.model.item(row, date_col).text(), date_format) if not date.isValid(): date = default_date expense.setDate(date.toString(Qt.ISODate)) print("Date: ", expense.getDate()) cost = 0 users = [] for member in self.current_group.getMembers(): print("Processing member ", member.getFirstName()) member_column = int( self.member_widget_map[member.getId()].text()) - 1 paid = 0 try: paid = float( self.model.item(row, member_column).text()) print("Expense: ", self.model.item(row, member_column).text()) except: pass cost = cost + paid expense_user = ExpenseUser() expense_user.setId(member.getId()) expense_user.setPaidShare(str(paid)) users.append(expense_user) for expense_user in users: expense_user.setOwedShare(str(cost * percent)) if cost == 0: raise Exception( self.tr('No se ha introducido monto para el gasto')) expense.setCost(str(cost)) expense.setUsers(users) expense.setGroupId(self.current_group.id) self.sObj.createExpense(expense) row = row + 1 self.le_initial_row.setText(str(row + 1)) except Exception as inst: QMessageBox.critical( self, self.tr("Error"), self.tr("Se ha producido un error en la fila") + str(row + 1) + "\n" + str(inst)) traceback.print_exc() def _enable_widgets(self, state): self.le_initial_row.setEnabled(state) self.cmb_group.setEnabled(state) self.cmb_ods_sheets.setEnabled(state) self.le_date_col.setEnabled(state) self.default_date.setEnabled(state) self.le_description_col.setEnabled(state) self.btn_import.setEnabled(state) self.le_date_format.setEnabled(state) def sheet_changed(self, sheet_name): self.read_sheet(self.file_data, sheet_name) def current_group_changed(self, idx): item = self.vlayout.takeAt(1) item.layout().deleteLater() item.invalidate() item = None self.vlayout.invalidate() self.group_members_layout = QFormLayout() self.current_group = self.cmb_group.itemData(idx) column_number = 1 self.member_widget_map = {} for member in self.current_group.getMembers(): self.member_widget_map[member.getId()] = QLineEdit( str(column_number)) self.group_members_layout.addRow( self.tr("Columna " + member.getFirstName()), self.member_widget_map[member.getId()]) column_number = column_number + 1 self.vlayout.insertLayout(1, self.group_members_layout) def init_gui(self): self.form_layout = QFormLayout() self.cmb_ods_sheets = QComboBox() self.le_initial_row = QLineEdit("1") self.le_initial_row.setValidator(QIntValidator(1, 99999)) self.cmb_group = QComboBox() self.le_date_col = QLineEdit("1") self.le_date_col.setValidator(QIntValidator(1, 999999)) self.default_date = QDateTimeEdit(QDate.currentDate()) self.default_date.setMinimumDate(QDate.currentDate().addDays(-365)) self.default_date.setMaximumDate(QDate.currentDate().addDays(365)) self.default_date.setDisplayFormat("dd.MM.yyyy") self.default_date.setCalendarPopup(True) self.le_date_format = QLineEdit("d/M/yyyy") self.le_description_col = QLineEdit("2") self.le_description_col.setValidator(QIntValidator(1, 9999)) self.sObj = get_splitwise() groups = self.sObj.getGroups() self.cmb_ods_sheets.currentTextChanged.connect(self.sheet_changed) for group in groups: self.cmb_group.addItem(group.getName(), group) self.cmb_group.currentIndexChanged.connect(self.current_group_changed) self.cmb_group.setCurrentIndex(0) btn_open_filename = QPushButton("Open") btn_open_filename.clicked.connect(self.open_filename) self.form_layout.addRow(self.tr("Archivo"), btn_open_filename) self.form_layout.addRow(self.tr("Hoja"), self.cmb_ods_sheets) self.form_layout.addRow(self.tr("Grupos"), self.cmb_group) self.form_layout.addRow(self.tr("Fila Inicial"), self.le_initial_row) self.form_layout.addRow(self.tr("Columna Fecha"), self.le_date_col) self.form_layout.addRow(self.tr("Formato de fecha"), self.le_date_format) self.form_layout.addRow(self.tr("Fecha por defecto"), self.default_date) self.form_layout.addRow(self.tr("Columna Concepto"), self.le_description_col) self.group_members_layout = QFormLayout() self.btn_import = QPushButton(self.tr("Importar")) self.btn_import.clicked.connect(self.import_expenses) self.model = QStandardItemModel(self) tableView = QTableView(self) tableView.setModel(self.model) self.vlayout = QVBoxLayout() self.vlayout.addLayout(self.form_layout) self.vlayout.addLayout(self.group_members_layout) self.vlayout.addWidget(self.btn_import) self.vlayout.setStretch(1, 1) hlayout = QHBoxLayout() hlayout.addWidget(tableView) hlayout.addLayout(self.vlayout) hlayout.setStretch(1, 0) hlayout.setStretch(0, 1) self.setLayout(hlayout) self._enable_widgets(False) self.show()
class MeasurementWidget(QWidget): """description of class""" def __init__(self, **kargs): super(MeasurementWidget, self).init__() self.layout = QGridLayout() self.expand = [] self.labels = [] self.datatables = [] self.initUI() def initUI(self): self.scroll = QScrollArea() #self.scroll.setMaximumHeight(550) #self.scroll.setMaximumWidth(750) self.a = QWidget() self.aLayout = self.grid = QGridLayout() self.a.setLayout(self.aLayout) self.a.setMinimumHeight(1100) #labels lbl1 = QLabel('<b style="font-size: 12pt">Measurement Details</b>') lbl1.move(0, 0) lbl1.resize(250, 30) self.layout.addWidget(lbl1, 0, 0, 1, 1) #self.aLayout.addWidget(lbl1) #--------------------------------------------------------------------------------------------------------- h_headers = [ 'Parameters', 'Measurement', '000_14-04-14', '000_14-04-14', '002_14-04-14', '003_14-04-14' ] v_headers = ['', '', '', '', '', '', ''] self.chbx1, self.chbx2, self.chbx3, self.chbx4 = QCheckBox( ), QCheckBox(), QCheckBox(), QCheckBox() data = [['Use', '', self.chbx1, self.chbx2, self.chbx3, self.chbx4], [ QLabel('<b>Total Q (m3/s)</b>'), QLabel('<b>2</b>'), QLabel('<b>3</b>'), QLabel('<b>9</b>'), QLabel('<b>9</b>'), QLabel('<b>9</b>') ], ['Top Q (m3/s)', '5', '6', '4', '5', '66'], ['Middle Q (m3/s)', '2', '3', '3', '5', '6'], ['Bottom Q (m3/s)', '4', '4', '3', '2', '1'], ['Left Q (m3/s)', '2', '3', '44', '2', '22'], ['Right Q (m3/s)', '2', '3', '3', '333', '222']] self.datatables.append( self.create_table(310, data, h_headers, v_headers)) func = partial(self.table_toggle, table_idx=0) label, collapse_widget = self.createTableCollapse("Discharge", func) self.labels.append(label) self.expand.append(True) self.aLayout.addWidget(collapse_widget) self.aLayout.addWidget(self.datatables[0]) #--------------------------------------------------------------------------------------------------------- self.chbx1, self.chbx2, self.chbx3, self.chbx4 = QCheckBox( ), QCheckBox(), QCheckBox(), QCheckBox() data = [['Use', '', self.chbx1, self.chbx2, self.chbx3, self.chbx4], [ QLabel('<b>Total Q (m3/s)</b>'), QLabel('<b>2</b>'), QLabel('<b>3</b>'), QLabel('<b>9</b>'), QLabel('<b>9</b>'), QLabel('<b>9</b>') ], ['Top Q (m3/s)', '5', '6', '4', '5', '66'], ['Middle Q (m3/s)', '2', '3', '3', '5', '6'], ['Bottom Q (m3/s)', '4', '4', '3', '2', '1'], ['Left Q (m3/s)', '2', '3', '44', '2', '22'], ['Right Q (m3/s)', '2', '3', '3', '333', '222']] self.datatables.append( self.create_table(310, data, h_headers, v_headers)) func = partial(self.table_toggle, table_idx=1) label, collapse_widget = self.createTableCollapse("The Sequel", func) self.labels.append(label) self.expand.append(True) self.aLayout.addWidget(collapse_widget) self.aLayout.addWidget(self.datatables[1]) #--------------------------------------------------------------------------------------------------------- self.chbx1, self.chbx2, self.chbx3, self.chbx4 = QCheckBox( ), QCheckBox(), QCheckBox(), QCheckBox() data = [['Use', '', self.chbx1, self.chbx2, self.chbx3, self.chbx4], [ QLabel('<b>Total Q (m3/s)</b>'), QLabel('<b>2</b>'), QLabel('<b>3</b>'), QLabel('<b>9</b>'), QLabel('<b>9</b>'), QLabel('<b>9</b>') ], ['Top Q (m3/s)', '5', '6', '4', '5', '66'], ['Middle Q (m3/s)', '2', '3', '3', '5', '6'], ['Bottom Q (m3/s)', '4', '4', '3', '2', '1'], ['Left Q (m3/s)', '2', '3', '44', '2', '22'], ['Right Q (m3/s)', '2', '3', '3', '333', '222']] self.datatables.append( self.create_table(310, data, h_headers, v_headers)) func = partial(self.table_toggle, table_idx=2) label, collapse_widget = self.createTableCollapse("The Triquel", func) self.labels.append(label) self.expand.append(True) self.aLayout.addWidget(collapse_widget) self.aLayout.addWidget(self.datatables[2]) self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) #self.layout.addWidget(self.scroll) #layout = new QVBoxLayout(central); #q = QSize() #q.setHeight(1000) #q.setWidth(700) #a.setMaximumSize(q) self.scroll.setWidget(self.a) self.scroll.setWidgetResizable(True) self.layout.addWidget(self.scroll, 1, 0, 1, 1) self.scroll2 = QScrollArea() self.scroll2.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.scroll2.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.chbx1, self.chbx2, self.chbx3, self.chbx4 = QCheckBox( ), QCheckBox(), QCheckBox(), QCheckBox() data = [['Use', '', self.chbx1, self.chbx2, self.chbx3, self.chbx4], [ QLabel('<b>Total Q (m3/s)</b>'), QLabel('<b>2</b>'), QLabel('<b>3</b>'), QLabel('<b>9</b>'), QLabel('<b>9</b>'), QLabel('<b>9</b>') ], ['Top Q (m3/s)', '5', '6', '4', '5', '66'], ['Middle Q (m3/s)', '2', '3', '3', '5', '6'], ['Bottom Q (m3/s)', '4', '4', '3', '2', '1'], ['Left Q (m3/s)', '2', '3', '44', '2', '22'], ['Right Q (m3/s)', '2', '3', '3', '333', '222']] self.scroll2.setWidgetResizable(True) #labels lbl2 = QLabel('<b style="font-size: 12pt">Messages</b>') lbl2.resize(250, 30) self.layout.addWidget(lbl2, 2, 0, 1, 1) #self.aLayout.addWidget(lbl1) self.b = QWidget() self.bLayout = QVBoxLayout() self.b.setLayout(self.bLayout) self.bLayout.addWidget( self.create_table(200, data, h_headers, v_headers)) self.scroll2.setWidget(self.b) self.layout.addWidget(self.scroll2, 3, 0, 1, 1) self.rightPane = QWidget() self.rightLayout = QVBoxLayout() self.rightPane.setLayout(self.rightLayout) #labels lbl3 = QLabel( '<b style="font-size: 12pt">Measurement Quality Assessment</b>') lbl3.resize(250, 30) self.rightLayout.addWidget(lbl3) h_headers = ['', 'COV %', '', '% Q'] v_headers = ['', '', ''] data = [['Q:', '11.92', 'Left/Right Edge:', '21.81 / 4.03'], ['Width:', '8.73', 'Invalid Cells:', '0.64'], [ 'Area:', '11.32', 'Invalid Ens:', '0.08', ]] self.datatables.append( self.create_table(110, data, h_headers, v_headers)) self.datatables[3].setColumnWidth(0, 50) self.datatables[3].setColumnWidth(1, 60) self.datatables[3].setColumnWidth(2, 100) for x in range(len(data)): self.datatables[3].setRowHeight(x, 25) self.rightLayout.addWidget(self.datatables[3]) h_headers = ['Parameter', 'Automatic', 'User'] v_headers = ['', '', '', '', '', '', ''] data = [['Random 95% Uncertainty', '19.0', ''], ['Invalid Data 95% Uncertainty', '0.1', ''], ['Edge Q 95% Uncertainty', '7.8', ''], ['Extrapolation 95% Uncertainty', '0.6', ''], ['Moving-Bed 95% Uncertainty', '1.5', ''], ['Systematic 68% Uncertainty', '1.5', ''], ['Estimated 95% Uncertainty', '20.8', '20.8']] self.datatables.append( self.create_table(210, data, h_headers, v_headers)) for x in range(len(data)): self.datatables[4].setRowHeight(x, 25) self.rightLayout.addWidget(self.datatables[4]) lbl4 = QLabel('<b style="font-size: 12pt">User Rating</b>') lbl4.resize(250, 30) self.rightLayout.addWidget(lbl4) self.combo = QComboBox() self.combo.addItem('Not Rated') self.combo.addItem('Excellent (<2%)') self.combo.addItem('Good (2-5%)') self.combo.addItem('Fair (5-8%)') self.combo.addItem('Poor (>8%)') self.rightLayout.addWidget(self.combo) lbl5 = QLabel('<b style="font-size: 12pt">Profile Extrapolation</b>') lbl5.resize(250, 30) self.rightLayout.addWidget(lbl5) x = [0, 10, 100] y = [3, 4, 5] self.mplwidget = MatplotlibWidget() self.mplwidget.setObjectName("mplwidget") self.mplwidget.plotDataPoints(x, y) self.rightLayout.addWidget(self.mplwidget) self.rightLayout.setStretch(0, 1) self.rightLayout.setStretch(1, 3) self.rightLayout.setStretch(2, 5) self.rightLayout.setStretch(3, 1) self.rightLayout.setStretch(4, 1) self.rightLayout.setStretch(5, 1) self.rightLayout.setStretch(6, 8) self.layout.addWidget(self.rightPane, 0, 1, 4, 1) #q = QSize() #q.setHeight(1000) #q.setWidth(700) #a.setMaximumSize(q) #self.scroll.setLayout(self.layout) self.layout.setRowStretch(0, 1) self.layout.setRowStretch(1, 10) self.layout.setRowStretch(2, 1) self.layout.setColumnStretch(0, 2) self.layout.setColumnStretch(1, 1) self.setLayout(self.layout) def createTableCollapse(self, text, func): collapseWidget = QWidget() hlayout = QHBoxLayout() collapseWidget.setLayout(hlayout) button = QPushButton('-') hlayout.setSpacing(10) button.clicked.connect(func) button.setFixedWidth(40) label = QLabel('<b style="font-size: 10pt">%s</b>' % text) hlayout.addWidget(button, 1) hlayout.addWidget(label, 20) return (button, collapseWidget) def create_table(self, height, data, h_headers, v_headers=None): datatable = QTableWidget() datatable.setMaximumHeight(height) datatable.setRowCount(len(data)) datatable.setColumnCount(len(data[0])) for x in range(len(data)): for y in range(len(data[x])): if type(data[x][y]) is str: datatable.setItem(x, y, QTableWidgetItem(data[x][y])) else: datatable.setCellWidget(x, y, data[x][y]) datatable.setHorizontalHeaderLabels(h_headers) if v_headers is not None: datatable.setVerticalHeaderLabels(v_headers) datatable.setAlternatingRowColors(True) datatable.setSortingEnabled(False) datatable.setEditTriggers(QAbstractItemView.NoEditTriggers) datatable.setStyleSheet( "QHeaderView::section { background-color: #e5e5e5; font-size: 8pt; font-weight: bold} " "QTableWidget { font-size: 8pt; } QHeaderView::section:horizontal { height: 30px}" ) datatable.horizontalHeader().setStretchLastSection(True) return datatable def table_toggle(self, table_idx): dt = self.datatables[table_idx] def resize_layout(): dt.setMaximumHeight(0) if self.expand[table_idx] == True: animation = QPropertyAnimation(self) animation.setPropertyName(QByteArray().append('size')) animation.setTargetObject(dt) animation.setDuration(250) ogWidth = dt.width() animation.setStartValue(QSize(ogWidth, 310)) animation.setEndValue(QSize(ogWidth, 0)) animation.finished.connect(resize_layout) animation.start() self.labels[table_idx].setText('+') self.a.updateGeometry() self.a.setMinimumHeight(self.a.minimumHeight() - 320) else: animation = QPropertyAnimation(self) animation.setPropertyName(QByteArray().append('size')) animation.setTargetObject(dt) animation.setDuration(250) dt.setMaximumHeight(310) ogWidth = dt.width() animation.setStartValue(QSize(ogWidth, 0)) animation.setEndValue(QSize(ogWidth, 310)) animation.start() self.labels[table_idx].setText('-') self.a.updateGeometry() self.a.setMinimumHeight(self.a.minimumHeight() + 320) self.expand[table_idx] = not self.expand[table_idx]
def create_left_column(self): # Create a vertical layout for the left column leftColumnLayout = QVBoxLayout() # Valve override group vorGroup = QGroupBox("Valve override") vorLayout = QHBoxLayout() self.vorNormalButton = QPushButton("Normal") self.vorNormalButton.setMinimumWidth(50) self.vorNormalButton.setFixedHeight(75) self.vorNormalButton.setCheckable(True) self.vorNormalButton.clicked.connect(self.update_vor_normal) self.vorClosedButton = QPushButton("Closed") self.vorClosedButton.setMinimumWidth(50) self.vorClosedButton.setFixedHeight(75) self.vorClosedButton.setCheckable(True) self.vorClosedButton.clicked.connect(self.update_vor_closed) self.vorOpenButton = QPushButton("Open") self.vorOpenButton.setMinimumWidth(50) self.vorOpenButton.setFixedHeight(75) self.vorOpenButton.setCheckable(True) self.vorOpenButton.clicked.connect(self.update_vor_open) vorState = self.controller.get_valve_override() if vorState == "Normal": self.vorNormalButton.setChecked(True) self.vorClosedButton.setChecked(False) self.vorOpenButton.setChecked(False) elif vorState == "Closed": self.vorNormalButton.setChecked(False) self.vorClosedButton.setChecked(True) self.vorOpenButton.setChecked(False) elif vorState == "Open": self.vorNormalButton.setChecked(False) self.vorClosedButton.setChecked(False) self.vorOpenButton.setChecked(True) else: raise ValueError(f"Unexpected vor state: {vorState}") vorLayout.addWidget(self.vorNormalButton) vorLayout.addWidget(self.vorClosedButton) vorLayout.addWidget(self.vorOpenButton) vorGroup.setLayout(vorLayout) vorGroup.setMaximumWidth(ControllerGUITab.LEFT_COLUMN_MAX_WIDTH) leftColumnLayout.addWidget(vorGroup, alignment=Qt.AlignTop) # Process configuration group processGroup = QGroupBox("Process configuration") processLayout = QFormLayout() self.gasFactorEdit = QLineEdit() self.gasFactorEdit.setValidator( QRegExpValidator(QRegExp("[0-9]{1,3}(|\\.[0-9]{1,3})"))) self.gasFactorEdit.editingFinished.connect(self.update_gas_factor) self.gasFactorEdit.setText("{:.5f}".format(self.controller.get_gas())) self.pvFullScaleEdit = QLineEdit() self.pvFullScaleEdit.setValidator( QRegExpValidator(QRegExp("(-|)[0-9]{1,3}(|\\.[0-9]{1,3})"))) self.pvFullScaleEdit.editingFinished.connect(self.update_pv_full_scale) self.pvFullScaleEdit.setText(str(self.controller.get_pv_full_scale())) self.pvSigtypeDropdown = QComboBox() self.pvSigtypeDropdown.addItems(Controller.INPUT_PORT_TYPES.keys()) self.pvSigtypeDropdown.currentTextChanged.connect( self.update_pv_signal_type) self.pvSigtypeDropdown.setCurrentText( str(self.controller.get_pv_signal_type())) self.spFullScaleEdit = QLineEdit() self.spFullScaleEdit.setValidator( QRegExpValidator(QRegExp("(-|)[0-9]{1,3}(|\\.[0-9]{1,3})"))) self.spFullScaleEdit.editingFinished.connect(self.update_sp_full_scale) self.spFullScaleEdit.setText(str(self.controller.get_sp_full_scale())) self.spSigtypeDropdown = QComboBox() self.spSigtypeDropdown.addItems(Controller.OUTPUT_PORT_TYPES.keys()) self.spSigtypeDropdown.currentTextChanged.connect( self.update_sp_signal_type) self.spSigtypeDropdown.setCurrentText( str(self.controller.get_sp_signal_type())) self.spSourceDropdown = QComboBox() self.spSourceDropdown.addItems(Controller.SP_SOURCES.keys()) self.spSourceDropdown.currentTextChanged.connect(self.update_source) self.spSourceDropdown.setCurrentText(str(self.controller.get_source())) self.decimalDropdown = QComboBox() self.decimalDropdown.addItems(Controller.DECIMAL_POINTS.keys()) self.decimalDropdown.currentTextChanged.connect( self.update_decimal_point) self.decimalDropdown.setCurrentText( str(self.controller.get_decimal_point())) self.measureUnitsDropdown = QComboBox() self.measureUnitsDropdown.addItems(Controller.MEASUREMENT_UNITS.keys()) self.measureUnitsDropdown.currentTextChanged.connect( self.update_measure_units) self.measureUnitsDropdown.setCurrentText( str(self.controller.get_measurement_units())) self.timebaseDropdown = QComboBox() self.timebaseDropdown.addItems(Controller.RATE_TIME_BASE.keys()) self.timebaseDropdown.currentTextChanged.connect(self.update_time_base) self.timebaseDropdown.setCurrentText( str(self.controller.get_time_base())) processLayout.addRow(QLabel("Gas factor"), self.gasFactorEdit) processLayout.addRow(QLabel("PV Full Scale"), self.pvFullScaleEdit) processLayout.addRow(QLabel("PV Signal Type"), self.pvSigtypeDropdown) processLayout.addRow(QLabel("SP Full Scale"), self.spFullScaleEdit) processLayout.addRow(QLabel("SP Signal Type"), self.spSigtypeDropdown) processLayout.addRow(QLabel("Setpoint source"), self.spSourceDropdown) processLayout.addRow(QLabel("Decimal point"), self.decimalDropdown) processLayout.addRow(QLabel("Measurement units"), self.measureUnitsDropdown) processLayout.addRow(QLabel("Time base"), self.timebaseDropdown) processGroup.setLayout(processLayout) processGroup.setMaximumWidth(ControllerGUITab.LEFT_COLUMN_MAX_WIDTH) leftColumnLayout.addWidget(processGroup, alignment=Qt.AlignTop) leftColumnLayout.setStretch(1, 100) runtimeGroup = QGroupBox("Runtime options") runtimeLayout = QVBoxLayout() layout = QHBoxLayout() self.bufferSizeEdit = QLineEdit() self.bufferSizeEdit.setText("64") self.bufferSizeEdit.setValidator(QIntValidator()) self.bufferSizeEdit.editingFinished.connect(self.update_buffer_size) layout.addWidget(QLabel("Sample buffer size")) layout.addWidget(self.bufferSizeEdit) layout.addWidget(QLabel("samples")) runtimeLayout.addLayout(layout) layout = QHBoxLayout() self.intervalEdit = QLineEdit() self.intervalEdit.setText("1") self.intervalEdit.setValidator( QRegExpValidator(QRegExp("[0-9]*(|\\.[0-9]*)"))) self.intervalEdit.editingFinished.connect(self.update_graph_timer) layout.addWidget(QLabel("Data update interval")) layout.addWidget(self.intervalEdit) layout.addWidget(QLabel("minutes")) runtimeLayout.addLayout(layout) layout = QHBoxLayout() self.setpointEdit = QLineEdit() self.setpointEdit.setValidator( QRegExpValidator(QRegExp("[0-9]*(|\\.[0-9]*)"))) self.setpointEdit.editingFinished.connect(self.update_setpoint) self.setpointEdit.setText(str(self.controller.get_setpoint())) self.setpointUnitsLabel = QLabel( f"{self.measureUnitsDropdown.currentText()}/{self.timebaseDropdown.currentText()}" ) layout.addWidget(QLabel("Setpoint")) layout.addWidget(self.setpointEdit) layout.addWidget(self.setpointUnitsLabel) runtimeLayout.addLayout(layout) layout = QHBoxLayout() manualMeasureButton = QPushButton("Get measurement") manualMeasureButton.clicked.connect(self.update_plot) self.saveCsvButton = QPushButton("Start saving to CSV") self.saveCsvButton.clicked.connect(self.save_to_csv_start) layout.addWidget(manualMeasureButton) layout.addWidget(self.saveCsvButton) runtimeLayout.addLayout(layout) runtimeGroup.setLayout(runtimeLayout) runtimeGroup.setMaximumWidth(ControllerGUITab.LEFT_COLUMN_MAX_WIDTH) runtimeGroup.setFixedHeight(150) leftColumnLayout.addWidget(runtimeGroup, alignment=Qt.AlignBottom) return leftColumnLayout
class RecommendMusicDetailBase(ScrollArea): def __init__(self, parent=None): """推荐歌单tabbase""" super().__init__() self.parent = parent self.setObjectName("RecommendMusicDetail") self.musicList = [] self.frame.setContentsMargins(0, 0, 0, 0) # 主布局。 self.mainLayout = QVBoxLayout(self.frame) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.topLayout = QHBoxLayout() self.topLayout.setContentsMargins(0, 0, 0, 0) self.picLabel = PicLabel(width=180, height=180) self.topLayout.addWidget(self.picLabel) self.topRightLayout = QVBoxLayout() self.topRightLayout.setContentsMargins(0, 0, 0, 0) self.topRightLayout.setSpacing(0) self.topLayout.addLayout(self.topRightLayout) self.topRightLayoutTitle = QHBoxLayout() self.topRightLayoutTitle.setContentsMargins(0, 0, 0, 0) self.topRightLayoutTitle.setSpacing(0) self.gedanButton = QPushButton("歌单") self.gedanButton.setMaximumSize(36, 20) self.titleLabel = QLabel() self.titleLabel.setWordWrap(True) self.titleLabel.setMaximumHeight(40) self.topRightLayoutTitle.addWidget(self.gedanButton) self.topRightLayoutTitle.addWidget(self.titleLabel) self.topRightLayout.addLayout(self.topRightLayoutTitle) self.authorLabel = QLabel() self.authorLabel.setMaximumHeight(28) self.topRightLayout.addWidget(self.authorLabel) self.playAllButton = QPushButton("全部播放") self.playAllButton.setIcon(QIcon('icons/playAll.png')) self.playAllButton.setObjectName('playAllButton') self.playAllButton.setMaximumSize(90, 24) self.topRightLayout.addWidget(self.playAllButton) self.topRightLayoutDesc = QHBoxLayout() self.topRightLayoutDesc.setContentsMargins(0, 0, 0, 0) self.topRightLayoutDesc.setSpacing(0) self.descLabel = QLabel("简介:") self.descriptionText = QTextEdit() self.descriptionText.setReadOnly(True) self.descriptionText.setMinimumWidth(450) self.descriptionText.setMinimumHeight(100) self.descriptionText.setMaximumHeight(100) self.topRightLayoutDesc.addWidget(self.descLabel) self.topRightLayoutDesc.addWidget(self.descriptionText) self.topRightLayout.addLayout(self.topRightLayoutDesc) self.topLayout.addLayout(self.topRightLayout) self.mainLayout.addLayout(self.topLayout) self.contentsTab = QTabWidget() self.singsTable = QTableWidget() self.singsTable.verticalHeader().setVisible(False) self.singsTable.setAlternatingRowColors(True) #self.singsTable.horizontalHeader().setStretchLastSection(True) self.singsTable.setColumnCount(4) #注意必须在初始化行列之后进行,否则,没有效果 self.singsTable.setHorizontalHeaderLabels(['序号', '音乐标题', '歌手', '时长']) self.singsTable.horizontalHeader().setSectionResizeMode( QHeaderView.Stretch) self.singsTable.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Interactive) self.singsTable.horizontalHeader().setSectionResizeMode( 3, QHeaderView.Interactive) self.singsTable.setColumnWidth(0, 40) self.singsTable.setColumnWidth(3, 100) self.singsTable.setObjectName('singsTable') """ self.singsTable.setMinimumWidth(self.width()) self.singsTable.setColumnWidths({i: j for i, j in zip(range(3), [self.width() / 3 * 1.25, self.width() / 3 * 1.25, self.width() / 3 * 0.5])}) """ self.contentsTab.addTab(self.singsTable, "歌曲列表") self.mainLayout.addWidget(self.contentsTab) self.mainLayout.setStretch(0, 3) self.mainLayout.setStretch(1, 7) self.singsTable.setEditTriggers(QAbstractItemView.NoEditTriggers) self.singsTable.setSelectionBehavior(QAbstractItemView.SelectRows) self.singsTable.horizontalHeader().setStyleSheet( "QHeaderView::section{background:#1C394D;}") self.singsTable.itemDoubleClicked.connect(self.musicItemDoubleClick) self.singsTable.setContextMenuPolicy(Qt.CustomContextMenu) self.singsTable.customContextMenuRequested.connect( self.singsTableContextMenu) def musicItemDoubleClick(self, item): #print(item) currentRow = self.singsTable.currentRow() """ player = self.parent.player import os import random names = [name for name in os.listdir(r"F:\musicdowmload") if ".MP3" in name] url = r"F:\musicdowmload\{}".format(random.choice(names)) player.playMusic(QUrl.fromLocalFile(url)) """ self.palyMusic(self.musicList[currentRow]) def singsTableContextMenu(self, pos): currentRow = self.singsTable.currentRow() pmenu = QMenu(self) downloadAct = QAction("下载", pmenu) pmenu.addAction(downloadAct) downloadAct.triggered.connect(lambda: self.downloadMusic(currentRow)) #pmenu.popup(self.singsTable.mapToGlobal(pos)) pmenu.popup(QCursor.pos()) async def downloadMusic(self, currentRow): pass async def palyMusic(self, data): pass
class ProjectDockWidget(DockWidget): FOLDER = "folder" MAKE_FILE = "mark_file" MAKE_ITEM = "mark_item" OriginImage = "image" current_item_changed_signal = pyqtSignal(QtTreePropertyBrowser) delete_mark_item_signal = pyqtSignal(Project, MarkItem) double_click_mark_item = pyqtSignal(Project, MarkItem) def __init__(self, parent=None): super(ProjectDockWidget, self).__init__("标注项目", parent) self.setObjectName("projectTreeDockWidget") self._item_to_project = {} self._project_to_root_index = {} self.project_tree = QTreeWidget(self) self.project_tree.setColumnCount(1) self.project_tree.setHeaderHidden(True) self.project_tree.setEditTriggers(QAbstractItemView.DoubleClicked) print(type(QAbstractItemView.DoubleClicked)) print(QAbstractItemView.DoubleClicked) self.project_tree.setObjectName("projectTree") self.project_tree.setContextMenuPolicy(Qt.CustomContextMenu) self.project_tree.customContextMenuRequested.connect( self.project_tree_item_context_menu) self.project_tree_mark_item_context_menu = self._create_mark_item_child_context_menu( ) self.project_tree.currentItemChanged.connect(self.current_item_changed) self.project_tree.doubleClicked.connect(self.mouse_double_clicked) self._widget = QWidget(self) self._layout = QVBoxLayout(self._widget) self._layout.setStretch(0, 0) self._layout.setContentsMargins(0, 6, 6, 6) self._layout.addWidget(self.project_tree) self.setWidget(self._widget) def _create_mark_item_child_context_menu(self): menu = QMenu(self.project_tree) remove_self_action = menu.addAction( "删除") # create_action(menu, "删除", slot=self.delete_self) remove_self_action.triggered.connect(self.delete_self) rename_action = create_action(menu, "重命名...", slot=self.rename) add_actions(menu, (remove_self_action, None, rename_action)) return menu def create_project(self, project): if project in self._project_to_root_index: return root = TopLevelTreeItem(project, self.project_tree) root.setSelected(True) # 原始图片 original_img_child = QTreeWidgetItem() original_img_child.setText(0, os.path.basename(project.image_path)) original_img_child.setToolTip(0, project.image_path) original_img_child.setIcon(0, QIcon(":/img_icon.png")) original_img_child.setWhatsThis(0, self.OriginImage) root.addChild(original_img_child) self._project_to_root_index[ project] = self.project_tree.indexOfTopLevelItem(root) def add_mark_item(self, project, mark_item: MarkItem): if project not in self._project_to_root_index: return mark_item_child = MarkTreeItem(mark_item) mark_item_child.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled) self._item_to_project[mark_item] = project self.project_tree.topLevelItem( self._project_to_root_index[project]).addChild(mark_item_child) def project_tree_item_context_menu(self, point): point = self.project_tree.mapToGlobal(point) current_item = self.project_tree.currentItem() if current_item: if not current_item.parent(): """TODO""" else: what_file = current_item.whatsThis(0) if what_file == self.MAKE_ITEM: self.project_tree_mark_item_context_menu.exec_(point) def rename(self): current_item = self.project_tree.currentItem() new_name, ok = QInputDialog.getText(self, "重命名", "请输入新的名字:", text=current_item.text(0)) if ok and current_item.text(0) != new_name: if isinstance(current_item, MarkTreeItem): current_item.get_mark_item().item_name = new_name def mouse_double_clicked(self) -> None: """""" current_item = self.project_tree.currentItem() if isinstance(current_item, MarkTreeItem): item = current_item.get_mark_item() self.double_click_mark_item.emit(self._item_to_project[item], item) elif isinstance(current_item, TopLevelTreeItem): project = current_item.get_project() self.double_click_mark_item.emit(project, None) def current_item_changed(self, current_item, p): if isinstance(current_item, AbstractProjectTreeItem): self.current_item_changed_signal.emit( current_item.get_item_browser()) def delete_all_file(self): """""" def delete_all_mark_file(self): """""" def delete_all_mark_item(self): """""" def selected_mark_changed(self, selected_item: MarkItem): """""" # self.project_tree. if selected_item in self._item_to_project: project = self._item_to_project[selected_item] top_level_index = self._project_to_root_index[project] top_level_item = self.project_tree.topLevelItem(top_level_index) for index in range(top_level_item.childCount()): item = top_level_item.child(index) if isinstance(item, MarkTreeItem): if item.get_mark_item() == selected_item: self.project_tree.setCurrentItem(item) return def close_project(self, project): if project not in self._project_to_root_index: return self.project_tree.takeTopLevelItem( self._project_to_root_index[project]) def delete_self(self): current_item = self.project_tree.currentItem() if isinstance(current_item, MarkTreeItem): project = self._item_to_project[current_item.get_mark_item()] self.delete_mark_item_signal.emit(project, current_item.get_mark_item()) parent = current_item.parent() parent.removeChild(current_item) if current_item.get_mark_item() in self._item_to_project: del self._item_to_project[current_item.get_mark_item()] del current_item def setting_selection(self): """""" def outline_detect(self): """""" # 标注项目属性的设置 def property_setting(self): pass
def initUi(self): self.statusBar().showMessage('加载中...') self.setGeometry(100, 60, 600, 400) self.setWindowTitle('王梅的股票查询分析系统') self.setWindowIcon(QIcon('logo.jpg')) self.themeSetAct = QAction('更换图表主题(&T)', self) self.themeSetAct.setShortcut('Ctrl+T') # 默认浅色主题 self.themeIndex = 0 self.themeSetAct.setStatusTip(Visualization.themesTip[self.themeIndex]) #self.themeSetAct.triggered.connect(self.changeTheme) menubar = self.menuBar() setMenu = menubar.addMenu('设置(&S)') setMenu.addAction(self.themeSetAct) self.widget = QWidget() self.setCentralWidget(self.widget) # 添加web view self.leftTopView = QWebEngineView() self.leftTopView.setContextMenuPolicy(Qt.NoContextMenu) self.BottomView = QWebEngineView() self.BottomView.setContextMenuPolicy(Qt.NoContextMenu) self.StockLineEdit = QLineEdit(" ") search_Btn = QPushButton('搜索') search_Btn.clicked.connect(self.searchStock) # 搜索布局 h0box = QHBoxLayout() h0box.addWidget(self.StockLineEdit) h0box.addWidget(search_Btn) h0box.setStretch(0, 4) h0box.setStretch(1, 1) # 左上布局 lefttopbox = QVBoxLayout() lefttopbox.addLayout(h0box) lefttopbox.addWidget(self.leftTopView) lefttopbox.setStretch(0, 1) lefttopbox.setStretch(1, 1) # 右上布局 h1box = QHBoxLayout() h1box.addLayout(lefttopbox) h1box.addWidget(RightTableView()) #h1box.addWidget(self.leftTopView) h1box.setStretch(0, 1) h1box.setStretch(1, 1) # 底部布局 h2box = QHBoxLayout() h2box.addWidget(self.BottomView) # 整个界面布局 vbox = QVBoxLayout() vbox.addLayout(h1box) vbox.addLayout(h2box) vbox.setStretch(0, 1) vbox.setStretch(1, 1) self.widget.setLayout(vbox)
class Appearance(SettingsSection): Name = 'Appearance' DEFAULT_STYLE = 'background: rgb(70, 70, 70);' + \ 'border: 1 solid rgb(0, 0, 0);' + \ 'border-radius: 6;' def __init__(self, size, parent=None): super().__init__(size, parent) self.verticalLayout = QVBoxLayout(self) self.textEditGroup = QGroupBox(self) self.horizontalLayout = QHBoxLayout(self.textEditGroup) self.textEdit = QTextEdit(self.textEditGroup) self.horizontalLayout.addWidget(self.textEdit) self.verticalLayout.addWidget(self.textEditGroup) self.fontSizeGroup = QGroupBox(self) self.horizontalLayout_1 = QHBoxLayout(self.fontSizeGroup) self.fontSizeSpin = QSpinBox(self.fontSizeGroup) self.horizontalLayout_1.addWidget(self.fontSizeSpin) self.verticalLayout.addWidget(self.fontSizeGroup) self.colorGroup = QGroupBox(self) self.horizontalLayout_2 = QHBoxLayout(self.colorGroup) self.colorBButton = QPushButton(self.colorGroup) self.horizontalLayout_2.addWidget(self.colorBButton) self.colorFButton = QPushButton(self.colorGroup) self.horizontalLayout_2.addWidget(self.colorFButton) self.verticalLayout.addWidget(self.colorGroup) self.previewGroup = QGroupBox(self) self.horizontalLayout_3 = QHBoxLayout(self.previewGroup) self.beforeLabel = QLabel(self.previewGroup) self.beforeLabel.setStyleSheet(self.DEFAULT_STYLE) self.beforeLabel.setAlignment(QtCore.Qt.AlignCenter) self.horizontalLayout_3.addWidget(self.beforeLabel) self.nowLabel = QLabel(self.previewGroup) self.nowLabel.setStyleSheet(self.DEFAULT_STYLE) self.nowLabel.setAlignment(QtCore.Qt.AlignCenter) self.horizontalLayout_3.addWidget(self.nowLabel) self.verticalLayout.addWidget(self.previewGroup) self.textEdit.textChanged.connect(self.changeText) self.fontSizeSpin.valueChanged.connect(self.updatePreview) self.colorBButton.clicked.connect(self.changeBColor) self.colorFButton.clicked.connect(self.changeFColor) self.warning = QLabel(self) self.warning.setText("The real appearance depends on the layout") self.warning.setAlignment(QtCore.Qt.AlignCenter) self.warning.setStyleSheet("color: red; font-weight: bold") self.verticalLayout.addWidget(self.warning) self.verticalLayout.setStretch(0, 3) self.verticalLayout.setStretch(1, 1) self.verticalLayout.setStretch(2, 1) self.verticalLayout.setStretch(3, 2) self.verticalLayout.setStretch(4, 1) self.retranslateUi() self.bColor = 'rgb(0,0,0)' self.fColor = 'rgb(177,177,177)' self.fontSizeSpin.setValue(11) def retranslateUi(self): self.textEditGroup.setTitle("Shown Text") self.textEdit.setText("Empty") self.fontSizeGroup.setTitle("Set Font Size") self.colorGroup.setTitle("Color") self.colorBButton.setText("Select background color") self.colorFButton.setText("Select font color") self.previewGroup.setTitle("Preview") self.beforeLabel.setText("Before") self.nowLabel.setText("After") def enable_check(self, enable): self.textEditGroup.setCheckable(enable) self.textEditGroup.setChecked(False) self.fontSizeGroup.setCheckable(enable) self.fontSizeGroup.setChecked(False) self.colorGroup.setCheckable(enable) self.colorGroup.setChecked(False) def get_configuration(self): conf = {} checked = self.textEditGroup.isCheckable() if(not (checked and not self.textEditGroup.isChecked())): conf['name'] = self.textEdit.toPlainText() if(not (checked and not self.colorGroup.isChecked())): conf['background'] = self.bColor conf['color'] = self.fColor if(not (checked and not self.fontSizeGroup.isChecked())): conf['font-size'] = self.fontSizeSpin.value() return conf def set_configuration(self, conf): if(conf is not None): if('name' in conf): self.textEdit.setText(conf['name']) self.nowLabel.setText(conf['name']) if('background' in conf): self.bColor = conf['background'] if('color' in conf): self.fColor = conf['color'] if('font-size' in conf): self.fontSizeSpin.setValue(conf['font-size']) self.updatePreview() self.beforeLabel.setStyleSheet(self.nowLabel.styleSheet()) def updatePreview(self): self.nowLabel.setStyleSheet('background: ' + self.bColor + ';\ border: 1 solid rgb(0,0,0);\ border-radius: 6;\ color: ' + self.fColor + ';\ font-size: ' + str(self.fontSizeSpin.value()) + 'pt;') def changeBColor(self): initial = QColor(*map(int, re.findall('\d{1,3}', self.bColor))) color = QColorDialog.getColor(initial, parent=self) if(color.isValid()): self.bColor = 'rgb' + str(color.getRgb()) self.updatePreview() def changeFColor(self): initial = QColor(*map(int, re.findall('\d{1,3}', self.fColor))) color = QColorDialog.getColor(initial, parent=self) if(color.isValid()): self.fColor = 'rgb' + str(color.getRgb()) self.updatePreview() def changeText(self): self.nowLabel.setText(self.textEdit.toPlainText())
def initWindow(self): QToolTip.setFont(QFont('SansSerif', 10)) # main layout frameWidget = QWidget() mainWidget = QSplitter(Qt.Horizontal) frameLayout = QVBoxLayout() self.settingWidget = QWidget() self.settingWidget.setProperty("class","settingWidget") self.receiveSendWidget = QSplitter(Qt.Vertical) self.functionalWiget = QWidget() settingLayout = QVBoxLayout() sendReceiveLayout = QVBoxLayout() sendFunctionalLayout = QVBoxLayout() mainLayout = QHBoxLayout() self.settingWidget.setLayout(settingLayout) self.receiveSendWidget.setLayout(sendReceiveLayout) self.functionalWiget.setLayout(sendFunctionalLayout) mainLayout.addWidget(self.settingWidget) mainLayout.addWidget(self.receiveSendWidget) mainLayout.addWidget(self.functionalWiget) mainLayout.setStretch(0,2) mainLayout.setStretch(1, 6) mainLayout.setStretch(2, 2) menuLayout = QHBoxLayout() mainWidget.setLayout(mainLayout) frameLayout.addLayout(menuLayout) frameLayout.addWidget(mainWidget) frameWidget.setLayout(frameLayout) self.setCentralWidget(frameWidget) # option layout self.settingsButton = QPushButton() self.skinButton = QPushButton("") self.waveButton = QPushButton("") self.aboutButton = QPushButton() self.functionalButton = QPushButton() self.encodingCombobox = ComboBox() self.encodingCombobox.addItem("ASCII") self.encodingCombobox.addItem("UTF-8") self.encodingCombobox.addItem("UTF-16") self.encodingCombobox.addItem("GBK") self.encodingCombobox.addItem("GB2312") self.encodingCombobox.addItem("GB18030") self.settingsButton.setProperty("class", "menuItem1") self.skinButton.setProperty("class", "menuItem2") self.aboutButton.setProperty("class", "menuItem3") self.functionalButton.setProperty("class", "menuItem4") self.waveButton.setProperty("class", "menuItem5") self.settingsButton.setObjectName("menuItem") self.skinButton.setObjectName("menuItem") self.aboutButton.setObjectName("menuItem") self.functionalButton.setObjectName("menuItem") self.waveButton.setObjectName("menuItem") menuLayout.addWidget(self.settingsButton) menuLayout.addWidget(self.skinButton) menuLayout.addWidget(self.waveButton) menuLayout.addWidget(self.aboutButton) menuLayout.addStretch(0) menuLayout.addWidget(self.encodingCombobox) menuLayout.addWidget(self.functionalButton) # widgets receive and send area self.receiveArea = QTextEdit() self.sendArea = QTextEdit() self.clearReceiveButtion = QPushButton(parameters.strClearReceive) self.sendButtion = QPushButton(parameters.strSend) self.sendHistory = ComboBox() sendWidget = QWidget() sendAreaWidgetsLayout = QHBoxLayout() sendWidget.setLayout(sendAreaWidgetsLayout) buttonLayout = QVBoxLayout() buttonLayout.addWidget(self.clearReceiveButtion) buttonLayout.addStretch(1) buttonLayout.addWidget(self.sendButtion) sendAreaWidgetsLayout.addWidget(self.sendArea) sendAreaWidgetsLayout.addLayout(buttonLayout) sendReceiveLayout.addWidget(self.receiveArea) sendReceiveLayout.addWidget(sendWidget) sendReceiveLayout.addWidget(self.sendHistory) sendReceiveLayout.setStretch(0, 7) sendReceiveLayout.setStretch(1, 2) sendReceiveLayout.setStretch(2, 1) # widgets serial settings serialSettingsGroupBox = QGroupBox(parameters.strSerialSettings) serialSettingsLayout = QGridLayout() serialReceiveSettingsLayout = QGridLayout() serialSendSettingsLayout = QGridLayout() serialPortLabek = QLabel(parameters.strSerialPort) serailBaudrateLabel = QLabel(parameters.strSerialBaudrate) serailBytesLabel = QLabel(parameters.strSerialBytes) serailParityLabel = QLabel(parameters.strSerialParity) serailStopbitsLabel = QLabel(parameters.strSerialStopbits) self.serialPortCombobox = ComboBox() self.serailBaudrateCombobox = ComboBox() self.serailBaudrateCombobox.addItem("9600") self.serailBaudrateCombobox.addItem("19200") self.serailBaudrateCombobox.addItem("38400") self.serailBaudrateCombobox.addItem("57600") self.serailBaudrateCombobox.addItem("115200") self.serailBaudrateCombobox.setCurrentIndex(4) self.serailBaudrateCombobox.setEditable(True) self.serailBytesCombobox = ComboBox() self.serailBytesCombobox.addItem("5") self.serailBytesCombobox.addItem("6") self.serailBytesCombobox.addItem("7") self.serailBytesCombobox.addItem("8") self.serailBytesCombobox.setCurrentIndex(3) self.serailParityCombobox = ComboBox() self.serailParityCombobox.addItem("None") self.serailParityCombobox.addItem("Odd") self.serailParityCombobox.addItem("Even") self.serailParityCombobox.addItem("Mark") self.serailParityCombobox.addItem("Space") self.serailParityCombobox.setCurrentIndex(0) self.serailStopbitsCombobox = ComboBox() self.serailStopbitsCombobox.addItem("1") self.serailStopbitsCombobox.addItem("1.5") self.serailStopbitsCombobox.addItem("2") self.serailStopbitsCombobox.setCurrentIndex(0) self.checkBoxRts = QCheckBox("rts") self.checkBoxDtr = QCheckBox("dtr") self.serialOpenCloseButton = QPushButton(parameters.strOpen) serialSettingsLayout.addWidget(serialPortLabek,0,0) serialSettingsLayout.addWidget(serailBaudrateLabel, 1, 0) serialSettingsLayout.addWidget(serailBytesLabel, 2, 0) serialSettingsLayout.addWidget(serailParityLabel, 3, 0) serialSettingsLayout.addWidget(serailStopbitsLabel, 4, 0) serialSettingsLayout.addWidget(self.serialPortCombobox, 0, 1) serialSettingsLayout.addWidget(self.serailBaudrateCombobox, 1, 1) serialSettingsLayout.addWidget(self.serailBytesCombobox, 2, 1) serialSettingsLayout.addWidget(self.serailParityCombobox, 3, 1) serialSettingsLayout.addWidget(self.serailStopbitsCombobox, 4, 1) serialSettingsLayout.addWidget(self.checkBoxRts, 5, 0,1,1) serialSettingsLayout.addWidget(self.checkBoxDtr, 5, 1,1,1) serialSettingsLayout.addWidget(self.serialOpenCloseButton, 6, 0,1,2) serialSettingsGroupBox.setLayout(serialSettingsLayout) settingLayout.addWidget(serialSettingsGroupBox) # serial receive settings serialReceiveSettingsGroupBox = QGroupBox(parameters.strSerialReceiveSettings) self.receiveSettingsAscii = QRadioButton(parameters.strAscii) self.receiveSettingsHex = QRadioButton(parameters.strHex) self.receiveSettingsAscii.setChecked(True) self.receiveSettingsAutoLinefeed = QCheckBox(parameters.strAutoLinefeed) self.receiveSettingsAutoLinefeedTime = QLineEdit(parameters.strAutoLinefeedTime) self.receiveSettingsAutoLinefeed.setMaximumWidth(75) self.receiveSettingsAutoLinefeedTime.setMaximumWidth(75) serialReceiveSettingsLayout.addWidget(self.receiveSettingsAscii,1,0,1,1) serialReceiveSettingsLayout.addWidget(self.receiveSettingsHex,1,1,1,1) serialReceiveSettingsLayout.addWidget(self.receiveSettingsAutoLinefeed, 2, 0, 1, 1) serialReceiveSettingsLayout.addWidget(self.receiveSettingsAutoLinefeedTime, 2, 1, 1, 1) serialReceiveSettingsGroupBox.setLayout(serialReceiveSettingsLayout) settingLayout.addWidget(serialReceiveSettingsGroupBox) # serial send settings serialSendSettingsGroupBox = QGroupBox(parameters.strSerialSendSettings) self.sendSettingsAscii = QRadioButton(parameters.strAscii) self.sendSettingsHex = QRadioButton(parameters.strHex) self.sendSettingsAscii.setChecked(True) self.sendSettingsScheduledCheckBox = QCheckBox(parameters.strScheduled) self.sendSettingsScheduled = QLineEdit(parameters.strScheduledTime) self.sendSettingsScheduledCheckBox.setMaximumWidth(75) self.sendSettingsScheduled.setMaximumWidth(75) self.sendSettingsCFLF = QCheckBox(parameters.strCRLF) self.sendSettingsCFLF.setChecked(False) serialSendSettingsLayout.addWidget(self.sendSettingsAscii,1,0,1,1) serialSendSettingsLayout.addWidget(self.sendSettingsHex,1,1,1,1) serialSendSettingsLayout.addWidget(self.sendSettingsScheduledCheckBox, 2, 0, 1, 1) serialSendSettingsLayout.addWidget(self.sendSettingsScheduled, 2, 1, 1, 1) serialSendSettingsLayout.addWidget(self.sendSettingsCFLF, 3, 0, 1, 2) serialSendSettingsGroupBox.setLayout(serialSendSettingsLayout) settingLayout.addWidget(serialSendSettingsGroupBox) settingLayout.setStretch(0, 5) settingLayout.setStretch(1, 2.5) settingLayout.setStretch(2, 2.5) # right functional layout self.addButton = QPushButton(parameters.strAdd) functionalGroupBox = QGroupBox(parameters.strFunctionalSend) functionalGridLayout = QGridLayout() functionalGridLayout.addWidget(self.addButton,0,1) functionalGroupBox.setLayout(functionalGridLayout) sendFunctionalLayout.addWidget(functionalGroupBox) self.isHideFunctinal = True self.hideFunctional() # main window self.statusBarStauts = QLabel() self.statusBarStauts.setMinimumWidth(80) self.statusBarStauts.setText("<font color=%s>%s</font>" %("#008200", parameters.strReady)) self.statusBarSendCount = QLabel(parameters.strSend+"(bytes): "+"0") self.statusBarReceiveCount = QLabel(parameters.strReceive+"(bytes): "+"0") self.statusBar().addWidget(self.statusBarStauts) self.statusBar().addWidget(self.statusBarSendCount,2) self.statusBar().addWidget(self.statusBarReceiveCount,3) # self.statusBar() self.resize(800, 500) self.MoveToCenter() self.setWindowTitle(parameters.appName+" V"+str(helpAbout.versionMajor)+"."+str(helpAbout.versionMinor)) icon = QIcon() print("icon path:"+self.DataPath+"/"+parameters.appIcon) icon.addPixmap(QPixmap(self.DataPath+"/"+parameters.appIcon), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) if sys.platform == "win32": ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("comtool") self.show() return
class App(QWidget): def __init__(self): super().__init__() self.title = 'CSA Program Chapter Tracker' self.left = 50 self.top = 75 self.width = 1350 self.height = 700 self.init_UI() def init_UI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.create_student_table() self.create_record_table() self.recordTableWidget.setEditTriggers( QAbstractItemView.NoEditTriggers) self.create_calendar() # l is label self.lname = QLabel("Name", self) self.lnumber = QLabel("Student ID", self) self.lgrade = QLabel("Grade", self) self.lhours = QLabel("Hours", self) self.lcsa = QLabel("CSA", self) self.lstart = QLabel(self.my_calendar.selectedDate().toString(), self) self.lend = QLabel(self.my_calendar.selectedDate().toString(), self) self.lname.move(102.5, 540) self.lnumber.move(252.5, 540) self.lgrade.move(425, 540) self.lhours.move(562.5, 540) self.lcsa.move(710, 540) self.lstart.move(1025, 350) self.lend.move(1180, 350) self.lstart.setFrameStyle(QFrame.Panel | QFrame.Raised) self.lend.setFrameStyle(QFrame.Panel | QFrame.Raised) self.lstart.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.lstart.setAlignment(Qt.AlignCenter) self.lend.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.lend.setAlignment(Qt.AlignCenter) self.lstart.resize(self.lstart.sizeHint().width() + 6, self.lstart.sizeHint().height() + 3) self.lend.resize(self.lend.sizeHint().width() + 6, self.lend.sizeHint().height() + 3) # tb is textbox self.tbname = QLineEdit(self) self.tbnumber = QLineEdit(self) self.tbhours = QLineEdit(self) # b is combobox self.bgrade = QComboBox(self) self.bcsa = QComboBox(self) self.btimespan = QComboBox(self) self.bgrade.addItem("9th") self.bgrade.addItem("10th") self.bgrade.addItem("11th") self.bgrade.addItem("12th") self.bcsa.addItem("N/A") self.bcsa.addItem("CSA Community") self.bcsa.addItem("CSA Service") self.bcsa.addItem("CSA Achievement") self.btimespan.addItem("Weeks") self.btimespan.addItem("Months") self.btimespan.addItem("Custom") self.bgrade.move(368, 570) self.bcsa.move(652.5, 570) self.btimespan.move(815, 105) self.tbname.move(50, 570) self.tbnumber.move(200, 570) self.tbhours.move(510, 570) self.tbname.resize(140, 25) self.tbnumber.resize(165, 25) self.tbhours.resize(140, 25) self.bgrade.resize(140, 25) self.bcsa.resize(155, 25) self.bgrade.currentText() self.add_button = QPushButton('Add', self) self.add_button.setToolTip('Add student to database with given data') self.add_button.move(810, 567.5) self.add_button.clicked.connect(self.add_student) self.delete_button = QPushButton('Delete', self) self.delete_button.setToolTip('Delete selected rows from database') self.delete_button.move(810, 245) self.delete_button.clicked.connect(self.remove_students) self.print_button = QPushButton('Compile Data', self) self.print_button.setToolTip( 'Compile the current student data as a pdf') self.print_button.move(810, 65) self.print_button.resize(self.print_button.sizeHint()) self.print_button.clicked.connect(self.compile_pdf) self.generate_button = QPushButton('Generate Student', self) self.generate_button.setToolTip('Generate a random student') self.generate_button.move(810, 605) self.generate_button.resize(self.generate_button.sizeHint()) self.generate_button.clicked.connect(self.generate_students) self.start_date_button = QPushButton('Set Start', self) self.start_date_button.setToolTip( 'Set the start date for the data to compile at') self.start_date_button.move(1030, 315) self.start_date_button.resize(self.start_date_button.sizeHint()) self.start_date_button.clicked.connect(self.set_start_date) self.end_date_button = QPushButton('Set End', self) self.end_date_button.setToolTip( 'Set the end date for the data to compile to') self.end_date_button.move(1185, 315) self.end_date_button.resize(self.end_date_button.sizeHint()) self.end_date_button.clicked.connect(self.set_end_date) self.btimespan.resize(self.print_button.sizeHint()) self.layout = QVBoxLayout() self.layout.setContentsMargins(50, 70, 550, 200) self.layout.addWidget(self.recordTableWidget) self.layout.addWidget(self.studentTableWidget) self.layout.setSpacing(29) self.layout.setStretch(0, 3) self.layout.setStretch(1, 5) self.setLayout(self.layout) self.edit = True self.show() def create_student_table(self): self.studentTableWidget = QTableWidget() row_count = c.execute("SELECT COUNT(*) FROM studentdata").fetchone()[0] self.studentTableWidget.setRowCount(row_count) self.studentTableWidget.setColumnCount(5) self.studentTableWidget.setShowGrid(True) self.studentTableWidget.move(0, 0) self.studentTableWidget.setHorizontalHeaderLabels( ['Name', 'Student ID', 'Grade Level', 'Hours', 'CSA']) self.header = self.studentTableWidget.horizontalHeader() self.header.setSectionResizeMode(0, QHeaderView.Stretch) self.header.setSectionResizeMode(1, QHeaderView.ResizeToContents) self.header.setSectionResizeMode(2, QHeaderView.ResizeToContents) self.header.setSectionResizeMode(3, QHeaderView.ResizeToContents) self.header.setSectionResizeMode(4, QHeaderView.ResizeToContents) self.populate_student_data() self.studentTableWidget.itemChanged.connect(self.log_change) def create_record_table(self): self.recordTableWidget = QTableWidget() row_count = c.execute("SELECT COUNT(*) FROM recorddata").fetchone()[0] self.recordTableWidget.setRowCount(row_count) self.recordTableWidget.setColumnCount(4) self.recordTableWidget.setShowGrid(True) self.recordTableWidget.setHorizontalHeaderLabels( ['Date', 'Name', 'Student ID', 'Hours Added']) self.header = self.recordTableWidget.horizontalHeader() self.header.setSectionResizeMode(0, QHeaderView.Stretch) self.header.setSectionResizeMode(1, QHeaderView.ResizeToContents) self.header.setSectionResizeMode(3, QHeaderView.ResizeToContents) self.header.setSectionResizeMode(2, QHeaderView.ResizeToContents) self.populate_record_data() def create_calendar(self): self.my_calendar = QCalendarWidget(self) self.my_calendar.move(1000, 70) self.my_calendar.resize(300, 200) self.ldate = QLabel(self) self.ldate.move(1100, 280) self.ldate.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.ldate.setLineWidth(2) self.my_calendar.clicked[QDate].connect(self.on_date_selection) self.ldate.setText(self.my_calendar.selectedDate().toString()) self.ldate.resize(self.ldate.sizeHint()) def on_date_selection(self, date): self.ldate.setText(date.toString()) self.ldate.resize(self.ldate.sizeHint()) def populate_student_data(self): c.execute("SELECT * FROM studentdata") student_data = c.fetchall() self.edit = False self.studentTableWidget.setRowCount(0) self.studentTableWidget.setRowCount(len(student_data)) for i in range(len(student_data)): self.studentTableWidget.setItem( i, 0, QTableWidgetItem(str(student_data[i][0]))) self.studentTableWidget.setItem( i, 1, QTableWidgetItem(str(student_data[i][1]))) self.studentTableWidget.setItem( i, 2, QTableWidgetItem(str(student_data[i][2]))) self.studentTableWidget.setItem( i, 3, QTableWidgetItem(str(student_data[i][3]))) self.studentTableWidget.setItem( i, 4, QTableWidgetItem(str(student_data[i][4]))) self.edit = True def populate_record_data(self): c.execute("SELECT * FROM recorddata") record_data = c.fetchall()[::-1] self.recordTableWidget.setRowCount(0) self.recordTableWidget.setRowCount(len(record_data)) for i in range(len(record_data)): self.recordTableWidget.setItem( i, 0, QTableWidgetItem(str(record_data[i][0]))) self.recordTableWidget.setItem( i, 1, QTableWidgetItem(str(record_data[i][1]))) self.recordTableWidget.setItem( i, 2, QTableWidgetItem(str(record_data[i][2]))) self.recordTableWidget.setItem( i, 3, QTableWidgetItem(str(record_data[i][3]))) def log_change(self, item): if self.edit: cols = {0: "name", 1: "number", 2: "grade", 3: "hours", 4: "csa"} c.execute("SELECT * FROM studentdata") student_data = c.fetchall() student_number = student_data[item.row()][1] student_name = student_data[item.row()][0] old_hours = student_data[item.row()][3] if item.column() == 3: hours = item.text() if hours.isdigit() == False: try: hours = eval(hours) c.execute( "UPDATE studentdata SET hours = ? WHERE number = ?", ( hours, student_number, )) self.update_csa(float(hours), student_number, item) c.execute("INSERT INTO recorddata VALUES (?, ?, ?, ?)", (datetime.now().strftime("%B %d, %Y %I:%M %p"), \ student_name, student_number, str('%.3f' % (float(hours)-old_hours)).rstrip('0').rstrip('.'),)) self.populate_record_data() except Exception as e: value_error = QMessageBox() value_error.setIcon(QMessageBox.Critical) value_error.setInformativeText( 'Please enter a valid expression or number') value_error.setWindowTitle("Error: Value") value_error.exec_() else: c.execute( "UPDATE studentdata SET hours = ? WHERE number = ?", ( hours, student_number, )) self.update_csa(float(hours), student_number, item) c.execute("INSERT INTO recorddata VALUES (?, ?, ?, ?)", (datetime.now().strftime("%B %d, %Y %I:%M %p"), \ student_name, student_number, str('%.3f' % (float(hours)-old_hours)).rstrip('0').rstrip('.'),)) self.populate_record_data() else: try: c.execute( "UPDATE studentdata SET {} = ? WHERE number = ?". format(cols[item.column()]), ( item.text(), student_number, )) if item.column() == 0 or item.column() == 1: c.execute( "UPDATE recorddata SET {} = ? WHERE number = ?". format(cols[item.column()]), ( item.text(), student_number, )) self.populate_record_data() except Exception as e: insert_error = QMessageBox() insert_error.setIcon(QMessageBox.Critical) insert_error.setInformativeText( 'Please check your Student ID is unique') insert_error.setWindowTitle("Error: Values") insert_error.exec_() replace_list = [ '/' * (i + 1) for i in range(len(student_data)) ] replace_existing = [ i[1] for i in student_data if i[1] in replace_list ] replace_new = [ i for i in replace_list if i not in replace_existing ] replace_new.sort(key=len) c.execute( "UPDATE studentdata SET number = ? WHERE number = ?", ( replace_new[0], student_number, )) c.execute( "UPDATE recorddata SET number = ? WHERE number = ?", ( replace_new[0], student_number, )) self.studentTableWidget.setItem( item.row(), item.column(), QTableWidgetItem(replace_new[0])) conn.commit() def update_csa(self, hours, student_number, item): csa_switcher = { 50: "CSA Community", 200: "CSA Service", 500: "CSA Achievement" } adjusted_hours = 500 if hours >= 500 else 200 if hours >= 200 else 50 if hours >= 50 else 0 csa_award = csa_switcher.get(adjusted_hours, "N/A") c.execute("UPDATE studentdata SET csa = ? WHERE number = ?", (csa_award, student_number)) conn.commit() try: self.studentTableWidget.blockSignals(True) self.studentTableWidget.setItem(item.row(), 4, QTableWidgetItem(str(csa_award))) self.studentTableWidget.setItem( item.row(), 3, QTableWidgetItem(str('%.3f' % hours).rstrip('0').rstrip('.'))) self.studentTableWidget.blockSignals(False) except Exception as e: print(e) c.execute("SELECT * FROM studentdata") @pyqtSlot() def add_student(self): # i is input iname = self.tbname.text() inumber = self.tbnumber.text() igrade = str(self.bgrade.currentText()) ihours = self.tbhours.text() icsa = str(self.bcsa.currentText()) try: for i in range(5): if [iname, inumber, igrade, ihours, icsa][i] == '': raise Exception int(ihours) c.execute('''INSERT INTO studentdata VALUES (?, ?, ?, ?, ?)''', ( iname, inumber, igrade, ihours, icsa, )) c.execute('''INSERT INTO recorddata VALUES (?, ?, ?, ?)''', ( datetime.now().strftime("%B %d, %Y %I:%M %p"), iname, inumber, ihours, )) conn.commit() self.populate_student_data() self.populate_record_data() except Exception as e: insert_error = QMessageBox() insert_error.setIcon(QMessageBox.Critical) insert_error.setInformativeText( 'Please check your Student ID is unique, all inputs are filled out, and hours is a number' ) insert_error.setWindowTitle("Error: Values") insert_error.exec_() @pyqtSlot() def remove_students(self): selected = self.studentTableWidget.selectedItems() selected_dict = {} for item in selected: if item.row() in selected_dict: selected_dict[item.row()] += 1 else: selected_dict[item.row()] = 1 c.execute('''SELECT * FROM studentdata''') student_data = c.fetchall() numbers = () for key in reversed(list(selected_dict.keys())): if selected_dict[key] == 5: self.studentTableWidget.removeRow(key) numbers += (student_data[key][1], ) c.execute( "DELETE FROM studentdata WHERE number IN ({})".format(", ".join( "?" * len(numbers))), numbers) c.execute( "DELETE FROM recorddata WHERE number IN ({})".format(", ".join( "?" * len(numbers))), numbers) self.populate_record_data() conn.commit() @pyqtSlot() def compile_pdf(self): pdf = FPDF() pdf.add_page() pdf.set_font("courier", size=12) if self.btimespan.currentText() == "Weeks": start_range = (datetime.now() - timedelta(7)) end_range = datetime.now() txt = "Last Week Report" elif self.btimespan.currentText() == "Months": start_range = (datetime.now() - timedelta(30)) end_range = datetime.now() txt = "Last Week Report" else: start_range = datetime.strptime(self.lstart.text(), "%a %b %d %Y") end_range = datetime.strptime(self.lend.text(), "%a %b %d %Y") txt = "Custom Report: %s - %s" % (start_range.strftime( "%B %d, %Y"), end_range.strftime("%B %d, %Y")) pdf.cell(200, 10, txt=txt, ln=1, align="C") c.execute('''SELECT * FROM recorddata''') datafetch = c.fetchall() record_data = [record for record in datafetch if datetime.strptime(record[0], ("%B %d, %Y %I:%M %p")) >= start_range and\ datetime.strptime(record[0], ("%B %d, %Y %I:%M %p")) <= end_range][::-1] if record_data == []: insert_error = QMessageBox() insert_error.setIcon(QMessageBox.Critical) insert_error.setInformativeText('No data to Compile') insert_error.setWindowTitle("Error: Data") insert_error.exec_() else: field1_max = len( max([str(record[0]) for record in record_data], key=len)) field2_max = len( max([str(record[1]) for record in record_data], key=len)) field3_max = len( max([str(record[2]) for record in record_data], key=len)) field4_max = len( max([str(record[3]) for record in record_data], key=len)) field_maxes = [field1_max, field2_max, field3_max, field4_max] xpos = 200 ypos = 15 yline = 35 iconst = 2.725 sconst = 2.4 spacer = 0 if sum(field_maxes) > 75 else int( (75 - sum(field_maxes)) / 3) line_count = 0 page_lines = 17 if spacer == 0: pdf.set_font("courier", size=9) spacer = 0 if sum(field_maxes) > 100 else int( (100 - sum(field_maxes)) / 3) iconst *= 0.75 sconst *= 0.75 for record in record_data: txt = '' for i in range(len(list(record))): txt += str( record[i]) + ' ' * int(field_maxes[i] - len(str(record[i])) + spacer) pdf.cell(xpos, ypos, txt=txt, ln=1, align="L") pdf.line(0, yline, 400, yline) yline += 15 line_count += 1 newx = 0 if line_count % page_lines == 0: yline = 10 title_space = 25 if line_count == page_lines else 10 for i in field_maxes[0:3]: newx += (i) * iconst + (spacer) * sconst pdf.line(newx, title_space, newx, 20 + 15 * page_lines) elif line_count == len(record_data): title_space = 25 if line_count < page_lines else 10 footer_space = 20 if line_count < page_lines else 10 for i in field_maxes[0:3]: newx += (i) * iconst + (spacer) * sconst pdf.line(newx, title_space, newx, footer_space + 15 * (line_count % page_lines)) if len(record_data) > page_lines: pdf.line(0, yline, 400, yline) c.execute('''SELECT name, number FROM studentdata''') student_data = c.fetchall() for student in student_data: if student[1] in [record[2] for record in record_data]: total_user_hours = str( round( sum([ record[3] for record in record_data if record[2] == student[1] ]), 3)) txt = ' ' * int( sum(field_maxes) + spacer * 3 - len(total_user_hours) - len(student[0]) - 2) + student[0] + ': ' + total_user_hours pdf.cell(xpos, ypos, txt=txt, ln=1, align="L") total_hours = str( round(sum([record[3] for record in record_data]), 3)) txt = ' ' * int( sum(field_maxes) + spacer * 3 - len(total_hours) - 13) + "Total Hours: " + total_hours pdf.cell(xpos, ypos, txt=txt, ln=1, align="L") pdf.output("community_service_program.pdf") #generate random student with hours added on a random date @pyqtSlot() def generate_students(self): start_dt = date.today().replace(day=1, month=1).toordinal() end_dt = date.today().toordinal() random_day = date.fromordinal(random.randint( start_dt, end_dt)).strftime("%B %d, %Y %I:%M %p") random_name = fake.name() random_id = fake.ssn() random_grade = random.choice(['9th', '10th', '11th', '12th']) random_hours = random.randint(1, 500) csa_award = 'CSA Community' if random_hours >= 500 else ( 'CSA Service' if random_hours >= 200 else ('CSA Achievement' if random_hours >= 50 else 'N/A')) c.execute('''INSERT INTO studentdata VALUES (?, ?, ?, ?, ?)''', ( random_name, str(random_id), random_grade, random_hours, csa_award, )) c.execute('''INSERT INTO recorddata VALUES (?, ?, ?, ?)''', ( str(random_day), random_name, str(random_id), random_hours, )) conn.commit() self.populate_record_data() self.populate_student_data() @pyqtSlot() def set_start_date(self): if datetime.strptime( self.lend.text(), "%a %b %d %Y") < datetime.strptime( self.my_calendar.selectedDate().toString(), "%a %b %d %Y"): self.lend.setText(self.my_calendar.selectedDate().toString()) self.lend.resize(self.lend.sizeHint()) self.lstart.setText(self.my_calendar.selectedDate().toString()) self.lstart.resize(self.lstart.sizeHint().width() + 6, self.lstart.sizeHint().height() + 3) @pyqtSlot() def set_end_date(self): if datetime.strptime(self.my_calendar.selectedDate().toString(), "%a %b %d %Y") < datetime.strptime( self.lstart.text(), "%a %b %d %Y"): date_error = QMessageBox() date_error.setIcon(QMessageBox.Critical) date_error.setInformativeText( 'End date cannot be before start date') date_error.setWindowTitle("Error: Date") date_error.exec_() else: self.lend.setText(self.my_calendar.selectedDate().toString()) self.lend.resize(self.lend.sizeHint().width() + 6, self.lend.sizeHint().height() + 3)
class MainWindow(QMainWindow): errorSignal = pyqtSignal(str, str) hintSignal = pyqtSignal(str, str) updateProgressSignal = pyqtSignal(str, int, int, str) updateProgressPrintSignal = pyqtSignal(str) showSerialComboboxSignal = pyqtSignal() downloadResultSignal = pyqtSignal(bool, str) DataPath = "./" app = None def __init__(self,app): super().__init__() self.app = app self.programStartGetSavedParameters() self.initVar() self.initWindow() self.initEvent() self.updateFrameParams() def __del__(self): pass def initVar(self): self.burning = False self.isDetectSerialPort = False self.DataPath = parameters.dataPath self.kflash = KFlash(print_callback=self.kflash_py_printCallback) self.saveKfpkDir = "" def setWindowSize(self, w=520, h=550): self.resize(w, h) def initWindow(self): QToolTip.setFont(QFont('SansSerif', 10)) # main layout self.frameWidget = QWidget() mainWidget = QSplitter(Qt.Horizontal) self.frameLayout = QVBoxLayout() self.settingWidget = QWidget() settingLayout = QVBoxLayout() self.settingWidget.setProperty("class","settingWidget") mainLayout = QVBoxLayout() self.settingWidget.setLayout(settingLayout) mainLayout.addWidget(self.settingWidget) mainLayout.setStretch(0,2) menuLayout = QHBoxLayout() self.progressHint = QLabel() self.progressHint.hide() self.progressbarRootWidget = QWidget() progressbarLayout = QVBoxLayout() self.progressbarRootWidget.setProperty("class","progressbarWidget") self.progressbarRootWidget.setLayout(progressbarLayout) self.downloadWidget = QWidget() downloadLayout = QVBoxLayout() self.downloadWidget.setProperty("class","downloadWidget") self.downloadWidget.setLayout(downloadLayout) mainWidget.setLayout(mainLayout) # menu # ----- # settings and others # ----- # progress bar # ----- # download button # ----- # status bar self.frameLayout.addLayout(menuLayout) self.frameLayout.addWidget(mainWidget) self.frameLayout.addWidget(self.progressHint) self.frameLayout.addWidget(self.progressbarRootWidget) self.frameLayout.addWidget(self.downloadWidget) self.frameWidget.setLayout(self.frameLayout) self.setCentralWidget(self.frameWidget) self.setFrameStrentch(1) # option layout self.langButton = QPushButton() self.skinButton = QPushButton() self.aboutButton = QPushButton() self.langButton.setProperty("class", "menuItemLang") self.skinButton.setProperty("class", "menuItem2") self.aboutButton.setProperty("class", "menuItem3") self.langButton.setObjectName("menuItem") self.skinButton.setObjectName("menuItem") self.aboutButton.setObjectName("menuItem") menuLayout.addWidget(self.langButton) menuLayout.addWidget(self.skinButton) menuLayout.addWidget(self.aboutButton) menuLayout.addStretch(0) # widgets file select self.fileSelectGroupBox = QGroupBox(tr("SelectFile")) settingLayout.addWidget(self.fileSelectGroupBox) self.fileSelectLayout = QVBoxLayout() self.fileSelectGroupBox.setLayout(self.fileSelectLayout) oneFilePathWidget = QWidget() oneFilePathWidgetLayout = QHBoxLayout() oneFilePathWidget.setLayout(oneFilePathWidgetLayout) filePathWidget = QLineEdit() openFileButton = QPushButton(tr("OpenFile")) oneFilePathWidgetLayout.addWidget(filePathWidget) oneFilePathWidgetLayout.addWidget(openFileButton) oneFilePathWidgetLayout.setStretch(0, 3) oneFilePathWidgetLayout.setStretch(1, 1) self.fileSelectLayout.addWidget(oneFilePathWidget) self.fileSelectWidgets = [["kfpkg", oneFilePathWidget, oneFilePathWidgetLayout, filePathWidget, None, openFileButton]] # for "button": ["button", addoneWidget, addoneWidgetLayout, addFileButton, packFileButton] # for "bin": ["bin", oneFilePathWidget, oneFilePathWidgetLayout, filePathWidget, fileBurnAddrWidget, openFileButton, fileBurnEncCheckbox] # widgets board select boardSettingsGroupBox = QGroupBox(tr("BoardSettings")) settingLayout.addWidget(boardSettingsGroupBox) boardSettingsLayout = QGridLayout() boardSettingsGroupBox.setLayout(boardSettingsLayout) self.boardLabel = QLabel(tr("Board")) self.boardCombobox = ComboBox() self.boardCombobox.addItem(parameters.SipeedMaixDock) self.boardCombobox.addItem(parameters.SipeedMaixBit) self.boardCombobox.addItem(parameters.SipeedMaixBitMic) self.boardCombobox.addItem(parameters.SipeedMaixduino) self.boardCombobox.addItem(parameters.SipeedMaixGo) self.boardCombobox.addItem(parameters.SipeedMaixGoD) self.boardCombobox.addItem(parameters.KendryteKd233) self.boardCombobox.addItem(parameters.kendryteTrainer) self.boardCombobox.addItem(parameters.Auto) self.burnPositionLabel = QLabel(tr("BurnTo")) self.burnPositionCombobox = ComboBox() self.burnPositionCombobox.addItem(tr("Flash")) self.burnPositionCombobox.addItem(tr("SRAM")) boardSettingsLayout.addWidget(self.boardLabel, 0, 0) boardSettingsLayout.addWidget(self.boardCombobox, 0, 1) boardSettingsLayout.addWidget(self.burnPositionLabel, 1, 0) boardSettingsLayout.addWidget(self.burnPositionCombobox, 1, 1) # widgets serial settings serialSettingsGroupBox = QGroupBox(tr("SerialSettings")) serialSettingsLayout = QGridLayout() serialPortLabek = QLabel(tr("SerialPort")) serailBaudrateLabel = QLabel(tr("SerialBaudrate")) slowModeLabel = QLabel(tr("Speed mode")) self.serialPortCombobox = ComboBox() self.serailBaudrateCombobox = ComboBox() self.serailBaudrateCombobox.addItem("115200") self.serailBaudrateCombobox.addItem("921600") self.serailBaudrateCombobox.addItem("1500000") self.serailBaudrateCombobox.addItem("2000000") self.serailBaudrateCombobox.addItem("3500000") self.serailBaudrateCombobox.addItem("4000000") self.serailBaudrateCombobox.addItem("4500000") self.serailBaudrateCombobox.setCurrentIndex(1) self.serailBaudrateCombobox.setEditable(True) self.slowModeCombobox = ComboBox() self.slowModeCombobox.addItem(tr("Slow mode")) self.slowModeCombobox.addItem(tr("Fast mode")) serialSettingsLayout.addWidget(serialPortLabek,0,0) serialSettingsLayout.addWidget(serailBaudrateLabel, 1, 0) serialSettingsLayout.addWidget(slowModeLabel, 2, 0) serialSettingsLayout.addWidget(self.serialPortCombobox, 0, 1) serialSettingsLayout.addWidget(self.serailBaudrateCombobox, 1, 1) serialSettingsLayout.addWidget(self.slowModeCombobox, 2, 1) serialSettingsGroupBox.setLayout(serialSettingsLayout) settingLayout.addWidget(serialSettingsGroupBox) # set stretch settingLayout.setStretch(0,1) settingLayout.setStretch(1,1) settingLayout.setStretch(2,2) # widgets progress bar self.progressbar = QProgressBar(self.progressbarRootWidget) self.progressbar.setValue(0) self.progressbarRootWidget.hide() # widgets download area self.downloadButton = QPushButton(tr("Download")) downloadLayout.addWidget(self.downloadButton) # main window self.statusBarStauts = QLabel() self.statusBarStauts.setMinimumWidth(80) self.statusBarStauts.setText("<font color=%s>%s</font>" %("#1aac2d", tr("DownloadHint"))) self.statusBar().addWidget(self.statusBarStauts) self.setWindowSize() self.MoveToCenter() self.setWindowTitle(parameters.appName+" V"+str(helpAbout.versionMajor)+"."+str(helpAbout.versionMinor)) icon = QIcon() print("icon path:"+self.DataPath+"/"+parameters.appIcon) icon.addPixmap(QPixmap(self.DataPath+"/"+parameters.appIcon), QIcon.Normal, QIcon.Off) self.setWindowIcon(icon) if sys.platform == "win32": ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(parameters.appName) self.show() self.progressbar.setGeometry(10, 0, self.downloadWidget.width()-25, 40) print("config file path:", parameters.configFilePath) def initEvent(self): self.serialPortCombobox.clicked.connect(self.portComboboxClicked) self.errorSignal.connect(self.errorHint) self.hintSignal.connect(self.hint) self.downloadResultSignal.connect(self.downloadResult) self.showSerialComboboxSignal.connect(self.showCombobox) self.updateProgressSignal.connect(self.updateProgress) self.updateProgressPrintSignal.connect(self.updateProgressPrint) self.langButton.clicked.connect(self.langChange) self.skinButton.clicked.connect(self.skinChange) self.aboutButton.clicked.connect(self.showAbout) self.downloadButton.clicked.connect(self.download) self.fileSelectWidget_Button(0).clicked.connect(lambda:self.selectFile(self.fileSelectWidget_Path(0))) self.myObject=MyClass(self) slotLambda = lambda: self.indexChanged_lambda(self.myObject) self.serialPortCombobox.currentIndexChanged.connect(slotLambda) def setFrameStrentch(self, mode): if mode == 0: self.frameLayout.setStretch(0,1) self.frameLayout.setStretch(1,3) self.frameLayout.setStretch(2,3) self.frameLayout.setStretch(3,1) self.frameLayout.setStretch(4,1) self.frameLayout.setStretch(5,1) else: self.frameLayout.setStretch(0,0) self.frameLayout.setStretch(1,0) self.frameLayout.setStretch(2,1) self.frameLayout.setStretch(3,1) self.frameLayout.setStretch(4,1) self.frameLayout.setStretch(5,1) def fileSelectWidget_Type(self, index): return self.fileSelectWidgets[index][0] def fileSelectWidget_Widget(self, index): return self.fileSelectWidgets[index][1] def fileSelectWidget_Layout(self, index): return self.fileSelectWidgets[index][2] def fileSelectWidget_Path(self, index): return self.fileSelectWidgets[index][3] def fileSelectWidget_Addr(self, index): return self.fileSelectWidgets[index][4] def fileSelectWidget_Button(self, index): return self.fileSelectWidgets[index][5] def fileSelectWidget_Prefix(self, index): return self.fileSelectWidgets[index][6] def fileSelectWidget_Close(self, index): return self.fileSelectWidgets[index][7] # @QtCore.pyqtSlot(str) def indexChanged_lambda(self, obj): mainObj = obj.arg self.serialPortCombobox.setToolTip(mainObj.serialPortCombobox.currentText()) def portComboboxClicked(self): self.detectSerialPort() def MoveToCenter(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def removeFileSelection(self, button): index = -1 for i in range(len(self.fileSelectWidgets)): if len(self.fileSelectWidgets[i]) >= 8: if self.fileSelectWidget_Close(i) == button: index = i print(index) if index == -1: return if len(self.fileSelectWidgets) > 2: self.fileSelectWidget_Button(index).clicked.disconnect() self.fileSelectWidget_Close(index).clicked.disconnect() self.fileSelectWidget_Widget(index).setParent(None) self.fileSelectWidgets.remove(self.fileSelectWidgets[index]) if len(self.fileSelectWidgets) == 2: self.fileSelectWidget_Close(0).clicked.disconnect() self.fileSelectWidget_Close(0).setParent(None) self.fileSelectWidgets[0].remove(self.fileSelectWidget_Close(0)) self.downloadWidget.resize(self.downloadWidget.width(), 58) self.setWindowSize(self.width()) def addAddFileWidget(self): if len(self.fileSelectWidgets) == 2: removeButton0 = QPushButton() removeButton0.setProperty("class", "remove_file_selection") self.fileSelectWidgets[0][2].addWidget(removeButton0) self.fileSelectWidgets[0].append(removeButton0) removeButton0.clicked.connect(lambda:self.removeFileSelection(removeButton0)) oneFilePathWidget = QWidget() oneFilePathWidgetLayout = QHBoxLayout() oneFilePathWidget.setLayout(oneFilePathWidgetLayout) filePathWidget = QLineEdit() fileBurnAddrWidget = QLineEdit("0x00000") fileBurnEncCheckbox = QCheckBox(tr("Prefix")) openFileButton = QPushButton(tr("OpenFile")) removeButton = QPushButton() removeButton.setProperty("class", "remove_file_selection") oneFilePathWidgetLayout.addWidget(filePathWidget) oneFilePathWidgetLayout.addWidget(fileBurnAddrWidget) oneFilePathWidgetLayout.addWidget(fileBurnEncCheckbox) oneFilePathWidgetLayout.addWidget(openFileButton) oneFilePathWidgetLayout.addWidget(removeButton) oneFilePathWidgetLayout.setStretch(0, 4) oneFilePathWidgetLayout.setStretch(1, 2) oneFilePathWidgetLayout.setStretch(2, 1) oneFilePathWidgetLayout.setStretch(3, 2) # oneFilePathWidgetLayout.setStretch(4, 1) index = len(self.fileSelectWidgets)-1 self.fileSelectWidgets.insert(index, ["bin", oneFilePathWidget, oneFilePathWidgetLayout, filePathWidget, fileBurnAddrWidget, openFileButton, fileBurnEncCheckbox, removeButton]) self.fileSelectLayout.insertWidget(index, oneFilePathWidget) openFileButton.clicked.connect(lambda:self.selectFile(filePathWidget)) removeButton.clicked.connect(lambda:self.removeFileSelection(removeButton)) def fileSelectShowKfpkg(self, index, name): if index==0 and self.fileSelectWidget_Type(0) == "kfpkg": #only one kgpkg before self.fileSelectWidget_Path(index).setText(name) else:# have bin file before, remove all and add one for kfpkg for i in range(len(self.fileSelectWidgets)): if self.fileSelectWidget_Type(i)=="button": self.fileSelectWidgets[i][3].clicked.disconnect() self.fileSelectWidgets[i][4].clicked.disconnect() else: self.fileSelectWidget_Button(i).clicked.disconnect() # self.fileSelectLayout.removeWidget(self.fileSelectWidget_Widget(i)) self.fileSelectWidget_Widget(i).setParent(None) self.fileSelectWidgets.clear() oneFilePathWidget = QWidget() oneFilePathWidgetLayout = QHBoxLayout() oneFilePathWidget.setLayout(oneFilePathWidgetLayout) filePathWidget = QLineEdit() openFileButton = QPushButton(tr("OpenFile")) oneFilePathWidgetLayout.addWidget(filePathWidget) oneFilePathWidgetLayout.addWidget(openFileButton) oneFilePathWidgetLayout.setStretch(0, 3) oneFilePathWidgetLayout.setStretch(1, 1) self.fileSelectLayout.addWidget(oneFilePathWidget) self.fileSelectWidgets.append(["kfpkg", oneFilePathWidget, oneFilePathWidgetLayout, filePathWidget, None, openFileButton]) openFileButton.clicked.connect(lambda:self.selectFile(filePathWidget)) filePathWidget.setText(name) # TODO: resize window def fileSelectShowBin(self, index, name, addr=None, prefix=None, prefixAuto=False, closeButton=False ): if index==0 and self.fileSelectWidget_Type(0) == "kfpkg": #only one kgpkg before self.fileSelectWidget_Button(index).clicked.disconnect() # self.fileSelectLayout.removeWidget(self.fileSelectWidget_Widget(index)) self.fileSelectWidget_Widget(index).setParent(None) self.fileSelectWidgets.clear() oneFilePathWidget = QWidget() oneFilePathWidgetLayout = QHBoxLayout() oneFilePathWidget.setLayout(oneFilePathWidgetLayout) filePathWidget = QLineEdit() fileBurnAddrWidget = QLineEdit("0x00000") fileBurnEncCheckbox = QCheckBox(tr("Prefix")) openFileButton = QPushButton(tr("OpenFile")) if closeButton: removeButton = QPushButton() removeButton.setProperty("class", "remove_file_selection") oneFilePathWidgetLayout.addWidget(filePathWidget) oneFilePathWidgetLayout.addWidget(fileBurnAddrWidget) oneFilePathWidgetLayout.addWidget(fileBurnEncCheckbox) oneFilePathWidgetLayout.addWidget(openFileButton) if closeButton: oneFilePathWidgetLayout.addWidget(removeButton) oneFilePathWidgetLayout.setStretch(0, 4) oneFilePathWidgetLayout.setStretch(1, 2) oneFilePathWidgetLayout.setStretch(2, 1) oneFilePathWidgetLayout.setStretch(3, 2) # oneFilePathWidgetLayout.setStretch(4, 1) self.fileSelectLayout.addWidget(oneFilePathWidget) openFileButton.clicked.connect(lambda:self.selectFile(filePathWidget)) if closeButton: self.fileSelectWidgets.append(["bin", oneFilePathWidget, oneFilePathWidgetLayout, filePathWidget, fileBurnAddrWidget, openFileButton, fileBurnEncCheckbox, removeButton]) removeButton.clicked.connect(lambda:self.removeFileSelection(removeButton)) print(removeButton) else: self.fileSelectWidgets.append(["bin", oneFilePathWidget, oneFilePathWidgetLayout, filePathWidget, fileBurnAddrWidget, openFileButton, fileBurnEncCheckbox]) # add ADD button addoneWidget = QWidget() addoneWidgetLayout = QHBoxLayout() addoneWidget.setLayout(addoneWidgetLayout) addFileButton = QPushButton(tr("Add File")) packFileButton = QPushButton(tr("Pack to kfpkg")) addoneWidgetLayout.addWidget(addFileButton) addoneWidgetLayout.addWidget(packFileButton) self.fileSelectLayout.addWidget(addoneWidget) self.fileSelectWidgets.append(["button", addoneWidget, addoneWidgetLayout, addFileButton, packFileButton]) addFileButton.clicked.connect(self.addAddFileWidget) packFileButton.clicked.connect(self.packFile) self.fileSelectWidget_Path(index).setText(name) if prefixAuto: if name.endswith(".bin"): self.fileSelectWidget_Prefix(index).setChecked(True) else: self.fileSelectWidget_Prefix(index).setChecked(False) elif prefix: self.fileSelectWidget_Prefix(index).setChecked(True) if addr: self.fileSelectWidget_Addr(index).setText("0x%06x" %(addr)) # return: ("kfpkg", [(file path, burn addr, add prefix),...]) # or ("bin", file path) # or (None, None) def getBurnFilesInfo(self): files = [] if self.fileSelectWidgets[0][0] == "kfpkg": path = self.fileSelectWidget_Path(0).text().strip() if path=="" or not os.path.exists(path): self.errorSignal.emit(tr("Error"), tr("Line {}: ").format(i+1)+tr("File path error")+":"+path) return (None, None) return ("kfpkg", path) for i in range(len(self.fileSelectWidgets)): if self.fileSelectWidgets[i][0] == "bin": path = self.fileSelectWidget_Path(i).text().strip() if path=="": continue if not os.path.exists(path): self.errorSignal.emit(tr("Error"), tr("Line {}: ").format(i+1)+tr("File path error")+":"+path) return (None, None) try: addr = int(self.fileSelectWidgets[i][4].text(), 16) except Exception: self.errorSignal.emit(tr("Error"), tr("Line {}: ").format(i+1)+tr("Address error")+self.fileSelectWidgets[i][4].text()) return (None, None) files.append( (path, addr, self.fileSelectWidgets[i][6].isChecked()) ) return ("bin", files) class KFPKG(): def __init__(self): self.fileInfo = {"version": "0.1.0", "files": []} self.filePath = {} self.burnAddr = [] def addFile(self, addr, path, prefix=False): if not os.path.exists(path): raise ValueError(tr("FilePathError")) if addr in self.burnAddr: raise ValueError(tr("Burn dddr duplicate")+":0x%06x" %(addr)) f = {} f_name = os.path.split(path)[1] f["address"] = addr f["bin"] = f_name f["sha256Prefix"] = prefix self.fileInfo["files"].append(f) self.filePath[f_name] = path self.burnAddr.append(addr) def listDumps(self): kfpkg_json = json.dumps(self.fileInfo, indent=4) return kfpkg_json def listDump(self, path): with open(path, "w") as f: f.write(json.dumps(self.fileInfo, indent=4)) def listLoads(self, kfpkgJson): self.fileInfo = json.loads(kfpkgJson) def listLload(self, path): with open(path) as f: self.fileInfo = json.load(f) def save(self, path): listName = os.path.join(tempfile.gettempdir(), "kflash_gui_tmp_list.json") self.listDump(listName) try: with zipfile.ZipFile(path, "w") as zip: for name,path in self.filePath.items(): zip.write(path, arcname=name, compress_type=zipfile.ZIP_LZMA) zip.write(listName, arcname="flash-list.json", compress_type=zipfile.ZIP_LZMA) zip.close() except Exception as e: os.remove(listName) raise e os.remove(listName) def packFile(self): # generate flash-list.json fileType, files = self.getBurnFilesInfo() if not fileType or not files or fileType=="kfpkg": self.errorSignal.emit(tr("Error"), tr("File path error")) return kfpkg = self.KFPKG() try: for path, addr, prefix in files: kfpkg.addFile(addr, path, prefix) except Exception as e: self.errorSignal.emit(tr("Error"), tr("Pack kfpkg fail")+":"+str(e)) return # select saving path if not os.path.exists(self.saveKfpkDir): self.saveKfpkDir = os.getcwd() fileName_choose, filetype = QFileDialog.getSaveFileName(self, tr("Save File"), self.saveKfpkDir, "k210 packages (*.kfpkg)") if fileName_choose == "": self.errorSignal.emit(tr("Error"), tr("File path error")) return if not fileName_choose.endswith(".kfpkg"): fileName_choose += ".kfpkg" self.saveKfpkDir = os.path.split(fileName_choose)[0] # print("save to ", fileName_choose) # write kfpkg file try: kfpkg.save(fileName_choose) except Exception as e: self.errorSignal.emit(tr("Error"), tr("Pack kfpkg fail")+":"+str(e)) return self.hintSignal.emit(tr("Success"), tr("Save kfpkg success")) def selectFile(self, pathobj): index = -1 for i in range(len(self.fileSelectWidgets)): if len(self.fileSelectWidgets[i]) >= 4: if pathobj == self.fileSelectWidget_Path(i): index = i if index == -1: return tmp = index while tmp>=0: oldPath = self.fileSelectWidget_Path(tmp).text() if oldPath != "": break tmp -= 1 if oldPath=="": oldPath = os.getcwd() fileName_choose, filetype = QFileDialog.getOpenFileName(self, tr("SelectFile"), oldPath, "All Files (*);;bin Files (*.bin);;k210 packages (*.kfpkg);;kmodel (*.kmodel);;encrypted kmodle(*.smodel)") # 设置文件扩展名过滤,用双分号间隔 if fileName_choose == "": return if not self.isFileValid(fileName_choose): self.errorSignal.emit(tr("Error"), tr("File path error")) return if self.isKfpkg(fileName_choose): self.fileSelectShowKfpkg(index, fileName_choose) else: self.fileSelectShowBin(index, fileName_choose, prefixAuto=True, closeButton=False) def errorHint(self, title, str): QMessageBox.critical(self, title, str) def hint(self, title, str): QMessageBox.information(self, title, str) def findSerialPort(self): self.port_list = list(serial.tools.list_ports.comports()) return self.port_list def portChanged(self): self.serialPortCombobox.setCurrentIndex(0) self.serialPortCombobox.setToolTip(str(self.portList[0])) def detectSerialPort(self): if not self.isDetectSerialPort: self.isDetectSerialPort = True t = threading.Thread(target=self.detectSerialPortProcess) t.setDaemon(True) t.start() def showCombobox(self): self.serialPortCombobox.showPopup() def isKfpkg(self, name): if name.endswith(".kfpkg"): return True return False def isFileValid(self, name): if not os.path.exists(name): return False return True def detectSerialPortProcess(self): while(1): portList = self.findSerialPort() if len(portList)>0: currText = self.serialPortCombobox.currentText() self.serialPortCombobox.clear() for i in portList: showStr = str(i[0])+" ("+str(i[1])+")" self.serialPortCombobox.addItem(showStr) index = self.serialPortCombobox.findText(currText) if index>=0: self.serialPortCombobox.setCurrentIndex(index) else: self.serialPortCombobox.setCurrentIndex(0) break time.sleep(1) self.showSerialComboboxSignal.emit() self.isDetectSerialPort = False def programExitSaveParameters(self): paramObj = paremeters_save.ParametersToSave() paramObj.board = self.boardCombobox.currentText() paramObj.burnPosition = self.burnPositionCombobox.currentText() paramObj.baudRate = self.serailBaudrateCombobox.currentIndex() paramObj.skin = self.param.skin paramObj.language = translation.current_lang path = self.fileSelectWidget_Path(0).text() if path.endswith(".kfpkg"): paramObj.files.append(path) else: for i in range(len(self.fileSelectWidgets)): try: addr = int(self.fileSelectWidget_Addr(i).text(),16) except Exception: continue paramObj.files.append( (self.fileSelectWidget_Path(i).text(), addr, self.fileSelectWidget_Prefix(i).isChecked()) ) if self.slowModeCombobox.currentIndex()==0: paramObj.slowMode = True else: paramObj.slowMode = False paramObj.save(parameters.configFilePath) def programStartGetSavedParameters(self): paramObj = paremeters_save.ParametersToSave() paramObj.load(parameters.configFilePath) translation.setLanguage(paramObj.language) self.param = paramObj def updateFrameParams(self): pathLen = len(self.param.files) if pathLen == 1 and type(self.param.files[0])==str and self.param.files[0].endswith(".kfpkg"): self.fileSelectWidget_Path(0).setText(self.param.files[0]) elif pathLen != 0: index = 0 for path, addr, prefix in self.param.files: prefix = None if (not prefix) else True if index!=0: self.addAddFileWidget() if pathLen > 1 and index != 0: closeButton = True else: closeButton = False self.fileSelectShowBin(index, path, addr, prefix, closeButton=closeButton) index += 1 self.boardCombobox.setCurrentText(self.param.board) self.burnPositionCombobox.setCurrentText(self.param.burnPosition) self.serailBaudrateCombobox.setCurrentIndex(self.param.baudRate) if self.param.slowMode: self.slowModeCombobox.setCurrentIndex(0) else: self.slowModeCombobox.setCurrentIndex(1) def closeEvent(self, event): try: self.programExitSaveParameters() finally: event.accept() def langChange(self): if self.param.language == translation.language_en: translation.setLanguage(translation.language_zh) lang = tr("Chinese language") else: translation.setLanguage(translation.language_en) lang = tr("English language") self.hint(tr("Hint"), tr("Language Changed to ") + lang + "\n"+ tr("Reboot to take effect")) self.frameWidget.style().unpolish(self.downloadButton) self.frameWidget.style().polish(self.downloadButton) self.frameWidget.update() def skinChange(self): if self.param.skin == 1: # light file = open(self.DataPath + '/assets/qss/style-dark.qss', "r") self.param.skin = 2 else: # elif self.param.skin == 2: # dark file = open(self.DataPath + '/assets/qss/style.qss', "r") self.param.skin = 1 self.app.setStyleSheet(file.read().replace("$DataPath", self.DataPath)) def showAbout(self): QMessageBox.information(self, tr("About"),"<h1 style='color:#f75a5a';margin=10px;>"+parameters.appName+ '</h1><br><b style="color:#08c7a1;margin = 5px;">V'+str(helpAbout.versionMajor)+"."+ str(helpAbout.versionMinor)+"."+str(helpAbout.versionDev)+ "</b><br><br>"+helpAbout.date+"<br><br>"+helpAbout.strAbout()) def autoUpdateDetect(self): auto = autoUpdate.AutoUpdate() if auto.detectNewVersion(): auto.OpenBrowser() def openDevManagement(self): os.system('start devmgmt.msc') def updateProgress(self, fileTypeStr, current, total, speedStr): currBurnPos = self.burnPositionCombobox.currentText() if currBurnPos == tr("SRAM") or currBurnPos == tr_en("SRAM"): fileTypeStr = tr("ToSRAM") percent = current/float(total)*100 hint = "<font color=%s>%s %s:</font> <font color=%s> %.2f%%</font> <font color=%s> %s</font>" %("#ff7575", tr("Downloading"), fileTypeStr, "#2985ff", percent, "#1aac2d", speedStr) self.progressHint.setText(hint) self.progressbar.setValue(percent) def updateProgressPrint(self, str): self.statusBarStauts.setText(str) def kflash_py_printCallback(self, *args, end = "\n"): msg = "" for i in args: msg += str(i) msg.replace("\n", " ") self.updateProgressPrintSignal.emit(msg) def progress(self, fileTypeStr, current, total, speedStr): self.updateProgressSignal.emit(fileTypeStr, current, total, speedStr) def download(self): if self.burning: self.terminateBurn() return tmpFile = "" fileType, filesInfo = self.getBurnFilesInfo() if not fileType or not filesInfo: self.errorSignal.emit(tr("Error"), tr("File path error")) return if fileType == "kfpkg": filename = filesInfo else:#generate kfpkg tmpFile = os.path.join(tempfile.gettempdir(), "kflash_gui_tmp.kfpkg") kfpkg = self.KFPKG() try: for path, addr, prefix in filesInfo: kfpkg.addFile(addr, path, prefix) kfpkg.save(tmpFile) except Exception as e: os.remove(tmpFile) self.errorSignal.emit(tr("Error"), tr("Pack kfpkg fail")+":"+str(e)) return filename = os.path.abspath(tmpFile) self.burning = True # if not self.checkFileName(filename): # self.errorSignal.emit(tr("Error"), tr("FilePathError")) # self.burning = False # return color = False board = "dan" boardText = self.boardCombobox.currentText() if boardText == parameters.SipeedMaixGo: board = "goE" elif boardText == parameters.SipeedMaixGoD: board = "goD" elif boardText == parameters.SipeedMaixduino: board = "maixduino" elif boardText == parameters.SipeedMaixBit: board = "bit" elif boardText == parameters.SipeedMaixBitMic: board = "bit_mic" elif boardText == parameters.KendryteKd233: board = "kd233" elif boardText == parameters.kendryteTrainer: board = "trainer" elif boardText == parameters.Auto: board = None sram = False if self.burnPositionCombobox.currentText()==tr("SRAM") or \ self.burnPositionCombobox.currentText()==tr_en("SRAM"): sram = True try: baud = int(self.serailBaudrateCombobox.currentText()) except Exception: self.errorSignal.emit(tr("Error"), tr("BaudrateError")) self.burning = False return dev = "" try: dev = self.serialPortCombobox.currentText().split()[0] except Exception: pass if dev=="": self.errorSignal.emit(tr("Error"), tr("PleaseSelectSerialPort")) self.burning = False return slow = self.slowModeCombobox.currentIndex()==0 # hide setting widgets self.setFrameStrentch(1) self.settingWidget.hide() self.progressbar.setValue(0) self.progressbar.setGeometry(10, 0, self.downloadWidget.width()-25, 40) self.progressbarRootWidget.show() self.progressHint.show() self.downloadButton.setText(tr("Cancel")) self.downloadButton.setProperty("class", "redbutton") self.downloadButton.style().unpolish(self.downloadButton) self.downloadButton.style().polish(self.downloadButton) self.downloadButton.update() self.statusBarStauts.setText("<font color=%s>%s ...</font>" %("#1aac2d", tr("Downloading"))) hint = "<font color=%s>%s</font>" %("#ff0d0d", tr("DownloadStart")) self.progressHint.setText(hint) # download self.burnThread = threading.Thread(target=self.flashBurnProcess, args=(dev, baud, board, sram, filename, self.progress, tmpFile!="", color, slow)) self.burnThread.setDaemon(True) self.burnThread.start() def flashBurnProcess(self, dev, baud, board, sram, filename, callback, cleanFile, color, slow): success = True errMsg = "" try: if board: self.kflash.process(terminal=False, dev=dev, baudrate=baud, board=board, sram = sram, file=filename, callback=callback, noansi=not color, slow_mode=slow) else: self.kflash.process(terminal=False, dev=dev, baudrate=baud, sram = sram, file=filename, callback=callback, noansi=not color, slow_mode=slow) except Exception as e: errMsg = str(e) if str(e) != "Burn SRAM OK": success = False if cleanFile: os.remove(filename) if success: self.downloadResultSignal.emit(True, errMsg) else: self.downloadResultSignal.emit(False, errMsg) def downloadResult(self, success, msg): if success: self.hintSignal.emit(tr("Success"), tr("DownloadSuccess")) self.statusBarStauts.setText("<font color=%s>%s</font>" %("#1aac2d", tr("DownloadSuccess"))) else: if msg == "Cancel": self.statusBarStauts.setText("<font color=%s>%s</font>" %("#ff1d1d", tr("DownloadCanceled"))) else: msg = tr("ErrorSettingHint") + "\n\n"+msg self.errorSignal.emit(tr("Error"), msg) self.statusBarStauts.setText("<font color=%s>%s</font>" %("#ff1d1d", tr("DownloadFail"))) self.progressHint.setText("") self.downloadButton.setText(tr("Download")) self.downloadButton.setProperty("class", "normalbutton") self.downloadButton.style().unpolish(self.downloadButton) self.downloadButton.style().polish(self.downloadButton) self.downloadButton.update() self.setFrameStrentch(0) self.progressbarRootWidget.hide() self.progressHint.hide() self.settingWidget.show() self.burning = False def terminateBurn(self): hint = "<font color=%s>%s</font>" %("#ff0d0d", tr("DownloadCanceling")) self.progressHint.setText(hint) self.kflash.kill()