def _on_command_run(self, command_input: QLineEdit): """Handles running commands.""" if command_input.text().strip() == "": return self._model.add_command(self._current_bot.uid, Command(CommandType.SHELL, command_input.text().encode())) command_input.clear() self.display_info("Command added to the queue of:\n {}@{}".format( self._current_bot.username, self._current_bot.hostname ))
class AddBookUI(QMainWindow): def __init__(self): super().__init__() self.width = 640 self.height = 400 self.top = 500 self.left = 400 self.initUI() def initUI(self): self.labelBookName = QLabel(self) self.labelBookName.setText("Book Name") self.labelAuthor = QLabel(self) self.labelAuthor.setText("Author") self.labelBookName.move(250, 100) self.labelAuthor.move(250, 130) self.bookname = QLineEdit(self) self.bookname.move(300, 100) self.author = QLineEdit(self) self.author.move(300, 130) button = QPushButton("Add Book", self) button.move(300, 190) button.clicked.connect(self.add_book) self.setWindowTitle("Add Books") self.setGeometry(self.left, self.top, self.width, self.height) def add_book(self): book = self.bookname.text(); author = self.author.text(); print(book) print(author) book = Book(book, author) session.add(book) session.commit() self.statusBar().showMessage("Book Saved Successfully") self.bookname.clear() self.author.clear()
class GameListWidget(QWidget): def __init__(self, main): super(GameListWidget, self).__init__() self.main_win = main self.keystore_exchanged = False self.setObjectName("GameListWidget") v_layout = QVBoxLayout() h_layout1 = QHBoxLayout() self.game_list_view = QListView() self.game_list_view.setViewMode(QListView.ListMode) self.game_list_view.setEditTriggers(QAbstractItemView.NoEditTriggers) self.game_list_model = GameListModel(self.main_win.games) self.game_list_view.setModel(self.game_list_model) self.game_list_view.clicked.connect(self.list_item_onclick) h_layout1.addWidget(self.game_list_view, 1) self.game_list_view.setCurrentIndex( self.game_list_model.index(self.main_win.game_index)) self.game = self.main_win.games[self.main_win.game_index] form_layout = QFormLayout() form_layout.setContentsMargins(20, 50, 20, 50) self.game_name_value = QLineEdit() form_layout.addRow("游戏名称:", self.game_name_value) self.game_desc_value = QTextEdit() form_layout.addRow("游戏简介:", self.game_desc_value) self.game_appid_value = QLabel() self.game_appid_value.setTextInteractionFlags(Qt.TextSelectableByMouse) form_layout.addRow("游戏ID:", self.game_appid_value) self.game_appkey_value = QLabel() self.game_appkey_value.setTextInteractionFlags( Qt.TextSelectableByMouse) form_layout.addRow("客户端Key:", self.game_appkey_value) h_layout = QHBoxLayout() self.keystore_path = QLineEdit() select_key_btn = QPushButton("浏览") select_key_btn.setStyleSheet('QPushButton{border-radius: 0px;}') select_key_btn.clicked.connect(self.select_ketstore) h_layout.addWidget(self.keystore_path) h_layout.addWidget(select_key_btn) form_layout.addRow("KeyStore:", h_layout) self.keystore_pwd_value = QLineEdit() form_layout.addRow("KeyPass:"******"Alias:", self.keystore_alias_value) self.keystore_aliaspwd_value = QLineEdit() form_layout.addRow("AliasPass:"******"更换Icon") icon_exchange_btn.setFixedWidth(100) icon_exchange_btn.clicked.connect(self.exchange_icon) v_layout1.addWidget(icon_exchange_btn, alignment=Qt.AlignHCenter) v_layout1.addStretch(2) h_layout1.addLayout(v_layout1, 1) v_layout.addLayout(h_layout1) h_layout2 = QHBoxLayout() create_game_btn = QPushButton("返 回") create_game_btn.setFixedWidth(100) create_game_btn.clicked.connect(self.back) h_layout2.addWidget(create_game_btn, alignment=Qt.AlignLeft | Qt.AlignBottom) back_btn = QPushButton("创建游戏") back_btn.setFixedWidth(100) back_btn.clicked.connect(self.add_game) h_layout2.addWidget(back_btn, alignment=Qt.AlignHCenter) next_btn = QPushButton("下一步") next_btn.setFixedWidth(100) next_btn.clicked.connect(self.next) h_layout2.addWidget(next_btn, alignment=Qt.AlignRight | Qt.AlignBottom) v_layout.addLayout(h_layout2) self.setLayout(v_layout) self.set_game_info() def set_game_info(self): self.game_name_value.setText(self.game['name']) self.game_desc_value.setText(self.game['desc']) self.game_appid_value.setText(self.game['id']) self.game_appkey_value.setText(self.game['key']) self.keystore_path.setText(self.game['keystore']) self.keystore_pwd_value.setText(self.game['keypwd']) self.keystore_alias_value.setText(self.game['alias']) self.keystore_aliaspwd_value.setText(self.game['aliaspwd']) icon = Utils.get_full_path('games/' + self.game['id'] + '/icon/icon.png') if not os.path.exists(icon): icon = 'icon.png' self.icon_img.setPixmap(QPixmap(icon)) def list_item_onclick(self): self.main_win.game_index = self.game_list_view.currentIndex().row() self.game = self.main_win.games[self.main_win.game_index] self.set_game_info() def back(self): self.main_win.set_main_widget() def add_game(self): if not self.save_data(): return self.main_win.set_create_game_widget(self.main_win.games) def select_ketstore(self): fname = QFileDialog.getOpenFileName( self, '选择签名文件', Utils.get_full_path('games/' + self.game['id'] + '/keystore/')) if fname[0]: if os.path.samefile( fname[0], Utils.get_full_path('games/' + self.game['id'] + '/keystore/' + self.game['keystore'])): self.keystore_path.setText(self.game['keystore']) self.keystore_pwd_value.setText(self.game['keypwd']) self.keystore_alias_value.setText(self.game['alias']) self.keystore_aliaspwd_value.setText(self.game['aliaspwd']) self.keystore_exchanged = False else: self.keystore_path.setText(fname[0]) self.keystore_pwd_value.clear() self.keystore_alias_value.clear() self.keystore_aliaspwd_value.clear() self.keystore_exchanged = True def exchange_icon(self): fname = QFileDialog.getOpenFileName( self, '选择icon', Utils.get_full_path('games/' + self.game['id'] + '/icon/'), ("Images (*.png)")) if fname[0]: pix = QPixmap(fname[0]) if pix.width() != 512 or pix.height() != 512: QMessageBox.warning(self, "警告", "必须上传512*512.png图片") return self.icon_img.setPixmap(pix) current_icon = Utils.get_full_path('games/' + self.game['id'] + '/icon/icon.png') if os.path.exists(current_icon): if os.path.samefile(os.path.dirname(fname[0]), os.path.dirname(current_icon)): if not os.path.samefile( fname[0], current_icon ): # 如果选中的,在game的icon目录下,但不是当前icon,则进行重命名 count = 0 temp = 'icon0.png' while os.path.exists( Utils.get_full_path('games/' + self.game['id'] + '/icon/' + temp)): count += 1 temp = 'icon' + str(count) + '.png' os.renames( current_icon, Utils.get_full_path('games/' + self.game['id'] + '/icon/' + temp)) os.renames(fname[0], current_icon) else: # 如果所选的是当前icon,不做处理 return else: # 如果选中的不在game的icon目录下,则重命名当前icon,并将选中的icon复制到目录下作为当前icon count = 0 temp = 'icon0.png' while os.path.exists( Utils.get_full_path('games/' + self.game['id'] + '/icon/' + temp)): count += 1 temp = 'icon' + str(count) + '.png' os.renames( current_icon, Utils.get_full_path('games/' + self.game['id'] + '/icon/' + temp)) Utils.copy_file(fname[0], current_icon) else: Utils.copy_file(fname[0], current_icon) def save_data(self): if self.game_name_value.text().strip() == "": QMessageBox.warning(self, "警告", "游戏名称不能为空!") return False if self.keystore_path.text().strip() == "": QMessageBox.warning(self, "警告", "必须上传keystore签名文件!") return False if self.keystore_pwd_value.text().strip() == "": QMessageBox.warning(self, "警告", "keystore密码不能为空!") return False if self.keystore_alias_value.text().strip() == "": QMessageBox.warning(self, "警告", "alias不能为空!") return False if self.keystore_aliaspwd_value.text().strip() == "": QMessageBox.warning(self, "警告", "alias密码不能为空!") return False self.game['name'] = self.game_name_value.text().strip() self.game['desc'] = self.game_desc_value.toPlainText().strip() if self.keystore_exchanged: keystore = os.path.basename(self.keystore_path.text().strip()) self.game['keystore'] = keystore self.game['keypwd'] = self.keystore_pwd_value.text().strip() self.game['alias'] = self.keystore_alias_value.text().strip() self.game['aliaspwd'] = self.keystore_aliaspwd_value.text().strip() keystore_path = Utils.get_full_path('games/' + self.game['id'] + '/keystore/' + keystore) if not os.path.exists(keystore_path): Utils.copy_file(self.keystore_path.text().strip(), keystore_path) self.main_win.games[self.main_win.game_index] = self.game self.game_list_model.update_item(self.main_win.game_index, self.game) return Utils.update_games(Utils.get_full_path('games/games.xml'), self.game, self.main_win.game_index) def next(self): if not self.save_data(): return channels = Utils.get_channels( Utils.get_full_path('games/' + self.game['id'] + '/config.xml')) if channels is None: if not os.path.exists(Utils.get_full_path('channelsdk')): QMessageBox.warning( self, "警告", os.path.dirname(os.getcwd()) + " 没有channelsdk文件夹") return elif len(os.listdir(Utils.get_full_path('channelsdk'))) <= 0: QMessageBox.warning( self, "警告", "本地没有渠道sdk,请手动添加sdk文件夹到" + Utils.get_full_path('channelsdk')) return channels = [] self.main_win.set_add_channel_widget(channels) else: self.main_win.set_channel_list_widget(channels)
class RemoveDialog(Dialog): def __init__(self, parent): from calibre_plugins.diaps_toolbag.span_div_config import plugin_prefs as prefs self.criteria = None self.prefs = prefs self.parent = parent self.help_file_name = '{0}_span_div_help.html'.format(PLUGIN_SAFE_NAME) self.taglist = TAGLIST Dialog.__init__(self, _('Edit Spans & Divs'), 'toolbag_spans_divs_dialog', parent) def setup_ui(self): DELETE_STR = _('Delete') MODIFY_STR = _('Modify') NO_ATTRIB_STR = _('No attributes ("naked" tag)') self.NO_CHANGE_STR = _('No change') layout = QVBoxLayout(self) self.setLayout(layout) help_layout = QHBoxLayout() layout.addLayout(help_layout) # Add hyperlink to a help file at the right. We will replace the correct name when it is clicked. help_label = QLabel('<a href="http://www.foo.com/">Plugin Help</a>', self) help_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard) help_label.setAlignment(Qt.AlignRight) help_label.linkActivated.connect(self.help_link_activated) help_layout.addWidget(help_label) action_layout = QHBoxLayout() layout.addLayout(action_layout) label = QLabel(_('Action type:'), self) action_layout.addWidget(label) self.action_combo = QComboBox() action_layout.addWidget(self.action_combo) self.action_combo.addItems([DELETE_STR, MODIFY_STR]) self.action_combo.currentIndexChanged.connect(self.update_gui) tag_layout = QHBoxLayout() layout.addLayout(tag_layout) label = QLabel(_('Tag name:'), self) tag_layout.addWidget(label) self.tag_combo = QComboBox() tag_layout.addWidget(self.tag_combo) self.tag_combo.addItems(self.taglist) self.tag_combo.currentIndexChanged.connect(self.update_gui) attr_layout = QHBoxLayout() layout.addLayout(attr_layout) label = QLabel(_('Having the attribute:'), self) attr_layout.addWidget(label) self.attr_combo = QComboBox() attr_layout.addWidget(self.attr_combo) self.attr_combo.addItems(self.prefs['attrs']) self.attr_combo.addItem(NO_ATTRIB_STR) self.attr_combo.currentIndexChanged.connect(self.update_gui) srch_layout = QHBoxLayout() layout.addLayout(srch_layout) label = QLabel(_("Whose value is (no quotes):"), self) srch_layout.addWidget(label) self.srch_txt = QLineEdit('', self) srch_layout.addWidget(self.srch_txt) self.srch_method = QCheckBox(_('Regex'), self) srch_layout.addWidget(self.srch_method) newtag_layout = QHBoxLayout() layout.addLayout(newtag_layout) label = QLabel(_('Change tag to:'), self) newtag_layout.addWidget(label) self.newtag_combo = QComboBox() newtag_layout.addWidget(self.newtag_combo) self.newtag_combo.addItem(self.NO_CHANGE_STR) self.newtag_combo.addItems(self.prefs['{}_changes'.format(unicode(self.tag_combo.currentText()))]) if self.action_combo.currentIndex() == 0: self.newtag_combo.setDisabled(True) newattr_layout = QVBoxLayout() layout.addLayout(newattr_layout) label = QLabel(_('New attribute string to insert (entire):'), self) newattr_layout.addWidget(label) self.newattr_txt = QLineEdit('', self) newattr_layout.addWidget(self.newattr_txt) self.copy_attr = QCheckBox(_('Copy existing attribute string'), self) self.copy_attr.stateChanged.connect(self.update_txt_box) newattr_layout.addWidget(self.copy_attr) if self.action_combo.currentIndex() == 0: self.copy_attr.setDisabled(True) self.newattr_txt.setDisabled(True) layout.addSpacing(10) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._ok_clicked) button_box.rejected.connect(self.reject) layout.addWidget(button_box) def update_gui(self): if self.attr_combo.currentIndex() == self.attr_combo.count()-1: self.srch_txt.clear() self.srch_txt.setDisabled(True) self.srch_method.setChecked(False) self.srch_method.setDisabled(True) else: self.srch_txt.setDisabled(False) self.srch_method.setDisabled(False) self.newtag_combo.clear() self.newtag_combo.addItem(self.NO_CHANGE_STR) self.newtag_combo.addItems(self.prefs['{}_changes'.format(unicode(self.tag_combo.currentText()))]) if self.action_combo.currentIndex() == 0: self.newtag_combo.setCurrentIndex(0) self.newtag_combo.setDisabled(True) self.newattr_txt.clear() self.newattr_txt.setDisabled(True) self.copy_attr.setChecked(False) self.copy_attr.setDisabled(True) else: self.newtag_combo.setDisabled(False) self.newattr_txt.setDisabled(False) self.copy_attr.setDisabled(False) def update_txt_box(self): if self.copy_attr.isChecked(): self.newattr_txt.clear() self.newattr_txt.setDisabled(True) else: self.newattr_txt.setDisabled(False) def _ok_clicked(self): if self.action_combo.currentIndex() == 0: action = 'delete' else: action = 'modify' if self.attr_combo.currentIndex() == self.attr_combo.count()-1: attribute = None else: attribute = unicode(self.attr_combo.currentText()) srch_str = unicode(self.srch_txt.displayText()) if not len(srch_str): srch_str = None if srch_str is None and attribute is not None: return error_dialog(self.parent, _('Error'), '<p>{0}'.format( _('Must enter a value for the attribute selected')), det_msg='', show=True) srch_method = 'normal' if self.srch_method.isChecked(): srch_method = 'regex' if self.newtag_combo.currentIndex() == 0: newtag = None else: newtag = unicode(self.newtag_combo.currentText()) if action == 'modify' and newtag is None and self.copy_attr.isChecked(): return error_dialog(self.parent, _('Error'), '<p>{0}'.format( _('What--exactly--would that achieve?')), det_msg='', show=True) new_str = unicode(self.newattr_txt.displayText()) copy_attr = False if self.copy_attr.isChecked(): copy_attr = True if not len(new_str): new_str = '' self.criteria = (srch_str, srch_method, unicode(self.tag_combo.currentText()), attribute, action, newtag, new_str, copy_attr) self.accept() def getCriteria(self): return self.criteria def help_link_activated(self, url): def get_help_file_resource(): # Copy the HTML helpfile to the plugin directory each time the # link is clicked in case the helpfile is updated in newer plugins. file_path = os.path.join(config_dir, 'plugins', self.help_file_name) with open(file_path,'w') as f: f.write(load_resource('resources/{}'.format(self.help_file_name))) return file_path url = 'file:///' + get_help_file_resource() open_url(QUrl(url))
class PunctDialog(Dialog): def __init__(self, parent): self.prefs = self.prefsPrep() self.criteria = None self.parent = parent self.help_file_name = '{0}_smarten_help.html'.format(PLUGIN_SAFE_NAME) Dialog.__init__(self, _('Smarten Punctuation (the sequel)'), 'toolbag_smarter_dialog', parent) def setup_ui(self,): layout = QVBoxLayout(self) self.setLayout(layout) help_layout = QHBoxLayout() layout.addLayout(help_layout) # Add hyperlink to a help file at the right. We will replace the correct name when it is clicked. help_label = QLabel('<a href="http://www.foo.com/">Plugin Help</a>', self) help_label.setTextInteractionFlags(Qt.LinksAccessibleByMouse | Qt.LinksAccessibleByKeyboard) help_label.setAlignment(Qt.AlignRight) help_label.linkActivated.connect(self.help_link_activated) help_layout.addWidget(help_label) self.edu_quotes = QCheckBox(_('Smarten Quotation marks'), self) layout.addWidget(self.edu_quotes) self.edu_quotes.setChecked(self.prefs['edu_quotes']) self.edu_quotes.stateChanged.connect(self.quotes_gui_changes) exceptions_group_box = QGroupBox('', self) layout.addWidget(exceptions_group_box) exceptions_group_box_layout = QVBoxLayout() exceptions_group_box.setLayout(exceptions_group_box_layout) self.use_file = QCheckBox(_('Use custom apostrophe exceptions file'), self) exceptions_group_box_layout.addWidget(self.use_file) if not self.edu_quotes.isChecked(): self.use_file.setDisabled(True) else: self.use_file.setChecked(self.prefs['use_file']) self.use_file.stateChanged.connect(self.use_file_gui_changes) path_layout = QHBoxLayout() exceptions_group_box_layout.addLayout(path_layout) self.file_path = QLineEdit('', self) if not self.edu_quotes.isChecked() and not self.use_file.isChecked(): self.file_path.setReadOnly(True) else: self.file_path.setText(self.prefs['file_path']) self.file_path.setReadOnly(True) path_layout.addWidget(self.file_path) self.file_button = QPushButton('...', self) self.file_button.clicked.connect(self.getFile) path_layout.addWidget(self.file_button) if not self.edu_quotes.isChecked() and not self.use_file.isChecked(): self.file_button.setDisabled(True) combo_layout = QVBoxLayout() layout.addLayout(combo_layout) label = QLabel(_('(em|en)-dash settings'), self) combo_layout.addWidget(label) self.dashes_combo = QComboBox() combo_layout.addWidget(self.dashes_combo) values = [_('Do not educate dashes'), _('-- = emdash (no endash support)'), _('-- = emdash | --- = endash'), _('--- = emdash | -- = endash')] self.dashes_combo.addItems(values) self.dashes_combo.setCurrentIndex(self.prefs['dashes']) # self.dashes_combo.currentIndexChanged.connect(self.update_gui) self.ellipses = QCheckBox(_('Smarten ellipses'), self) layout.addWidget(self.ellipses) self.ellipses.setChecked(self.prefs['ellipses']) self.unicode = QCheckBox(_('Educate with unicode characters (instead of entities)'), self) layout.addWidget(self.unicode) self.unicode.setChecked(self.prefs['unicode']) layout.addSpacing(10) button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) button_box.accepted.connect(self._ok_clicked) button_box.rejected.connect(self.reject) layout.addWidget(button_box) def getFile(self): unique_dlg_name = '{0}plugin:smarter_choose_dialog'.format(PLUGIN_SAFE_NAME) caption = _('Select custom apostrophe exceptions file') filters = [('Text files', ['txt'])] c = choose_files(self, unique_dlg_name, caption, filters, all_files=True) if c: self.file_path.setReadOnly(False) self.file_path.setText(c[0]) self.file_path.setReadOnly(True) def _ok_clicked(self): quotes_setting = 'q' if self.edu_quotes.isChecked() else '' if self.dashes_combo.currentIndex() == 0: dash_setting = '' elif self.dashes_combo.currentIndex() == 1: dash_setting = 'd' elif self.dashes_combo.currentIndex() == 2: dash_setting = 'i' elif self.dashes_combo.currentIndex() == 3: dash_setting = 'D' else: dash_setting = '' ellipses_setting = 'e' if self.ellipses.isChecked() else '' smarty_attr = quotes_setting + dash_setting + ellipses_setting if smarty_attr == '': smarty_attr = '0' self.file_path.setReadOnly(False) if self.use_file.isChecked() and not len(self.file_path.displayText()): self.file_path.setReadOnly(True) return error_dialog(self.parent, _('Error'), '<p>' + _('Must select a custom exception file'), det_msg='', show=True) if self.use_file.isChecked(): apos_exception_file = unicode(self.file_path.displayText()) if not os.path.exists(apos_exception_file): apos_exception_file = None else: apos_exception_file = None self.file_path.setReadOnly(True) apos_words_list = [] if apos_exception_file is not None: apos_words_list = self.parseExceptionsFile(os.path.normpath(apos_exception_file)) self.criteria = (smarty_attr, self.unicode.isChecked(), apos_words_list) self.savePrefs() self.accept() def getCriteria(self): return self.criteria def quotes_gui_changes(self): if self.edu_quotes.isChecked(): self.use_file.setDisabled(False) if self.use_file.isChecked(): self.file_button.setDisabled(False) else: self.use_file.setChecked(False) self.file_path.setReadOnly(False) self.file_path.clear() self.file_path.setReadOnly(True) self.use_file.setDisabled(True) self.file_button.setDisabled(True) def use_file_gui_changes(self): if self.use_file.isChecked(): self.file_button.setDisabled(False) else: self.file_path.setReadOnly(False) self.file_path.clear() self.file_path.setReadOnly(True) self.file_button.setDisabled(True) def prefsPrep(self): from calibre.utils.config import JSONConfig plugin_prefs = JSONConfig('plugins/{0}_SmarterPunct_settings'.format(PLUGIN_SAFE_NAME)) plugin_prefs.defaults['edu_quotes'] = True plugin_prefs.defaults['use_file'] = False plugin_prefs.defaults['file_path'] = '' plugin_prefs.defaults['dashes'] = 1 plugin_prefs.defaults['ellipses'] = True plugin_prefs.defaults['unicode'] = True return plugin_prefs def savePrefs(self): self.prefs['edu_quotes'] = self.edu_quotes.isChecked() self.prefs['use_file'] = self.use_file.isChecked() self.prefs['file_path'] = unicode(self.file_path.displayText()) if len(self.file_path.displayText()) else '' self.prefs['dashes'] = self.dashes_combo.currentIndex() self.prefs['ellipses'] = self.ellipses.isChecked() self.prefs['unicode'] = self.unicode.isChecked() def help_link_activated(self, url): def get_help_file_resource(): # Copy the HTML helpfile to the plugin directory each time the # link is clicked in case the helpfile is updated in newer plugins. file_path = os.path.join(config_dir, 'plugins', self.help_file_name) with open(file_path,'w') as f: f.write(load_resource('resources/{}'.format(self.help_file_name))) return file_path url = 'file:///' + get_help_file_resource() open_url(QUrl(url)) def parseExceptionsFile(self, filename): import os, codecs, chardet words_list = [] bytes = min(32, os.path.getsize(filename)) raw = open(filename, 'rb').read(bytes) if raw.startswith(codecs.BOM_UTF8): enc = 'utf-8-sig' else: result = chardet.detect(raw) enc = result['encoding'] try: with codecs.open(filename, encoding=enc, mode='r') as fd: words_list = [line.rstrip() for line in fd] words_list = filter(None, words_list) print('Exceptions list:', words_list) except: pass return words_list
class LLT_AddWord(QMainWindow): def __init__(self): super(LLT_AddWord, self).__init__() self.w = QWidget() self.setCentralWidget(self.w) self.verbDic = [] self.nounDic = [] self.adjDic = [] self.phraseDic = [] self.wordList = [] self.w.setWindowTitle("Add Word") self.w.setGeometry(0, 0, 500, 500) self.vRad = QRadioButton("Verb") self.vRad.setChecked(True) self.nRad = QRadioButton("Noun") self.aRad = QRadioButton("Adjective") self.pRad = QRadioButton("Phrase") self.okBut = QPushButton("OK") self.okBut.clicked.connect(self.OK) self.entryLab = QLabel("Word: ") self.wordEntry = QLineEdit() self.wordEntry.setEnabled(False) self.tranLab = QLabel("Translation: ") self.tranEntry = QLineEdit() self.tranEntry.setEnabled(False) self.checkBut = QPushButton("Check") self.checkBut.clicked.connect(self.check) self.saveBut = QPushButton("Save") self.saveBut.clicked.connect(self.save) self.clearBut = QPushButton("Clear") self.clearBut.clicked.connect(self.clear) self.newBut = QPushButton("New word") self.newBut.clicked.connect(self.new) self.exitBut = QPushButton("Exit") self.exitBut.clicked.connect(self.exit) grid = QGridLayout() grid.addWidget(self.vRad, 0, 0) grid.addWidget(self.nRad, 0, 1) grid.addWidget(self.aRad, 0, 2) grid.addWidget(self.pRad, 0, 3) grid.addWidget(self.okBut, 0, 4) grid.addWidget(self.entryLab, 1, 0) grid.addWidget(self.wordEntry, 1, 1, 1, 3) grid.addWidget(self.tranLab, 2, 0) grid.addWidget(self.tranEntry, 2, 1, 1, 3) grid.addWidget(self.checkBut, 3, 0) grid.addWidget(self.saveBut, 3, 1) grid.addWidget(self.clearBut, 3, 2) grid.addWidget(self.newBut, 3, 3) grid.addWidget(self.exitBut, 3, 4) self.getDics() self.setLists() self.w.setLayout(grid) self.w.show() def OK(self): self.vRad.setEnabled(False) self.nRad.setEnabled(False) self.aRad.setEnabled(False) self.pRad.setEnabled(False) self.okBut.setEnabled(False) self.wordEntry.setEnabled(True) self.tranEntry.setEnabled(True) def check(self): word = self.wordEntry.text().upper() if word in self.wordList: msgBox = QMessageBox() msgBox.setText(word + ' already in dictionary') msgBox.exec_() else: msgBox = QMessageBox() msgBox.setText(word + ' not in dictionary yet') msgBox.exec_() def save(self): spanWord = self.wordEntry.text().upper() tranWord = self.tranEntry.text().upper() if spanWord in self.wordList: msgBox = QMessageBox() msgBox.setText(spanWord + ' already in dictionary') msgBox.exec_() else: self.wordList.append(spanWord) newWord = [spanWord, tranWord] self.wordEntry.setEnabled(False) self.tranEntry.setEnabled(False) if self.vRad.isChecked(): self.verbDic.append(newWord) v = open('verb.txt', 'w') json.dump(self.verbDic, v) v.close() elif self.nRad.isChecked(): self.nounDic.append(newWord) n = open('noun.txt', 'w') json.dump(self.nounDic, n) n.close() elif self.aRad.isChecked(): self.adjDic.append(newWord) a = open('adj.txt', 'w') json.dump(self.adjDic, a) a.close() elif self.pRad.isChecked(): self.phraseDic.append(newWord) p = open('phrase.txt', 'w') json.dump(self.phraseDic, p) p.close() else: msgBox = QMessageBox() msgBox.setText( "You must select a dictionary before saving word.") msgBox.exec_() def clear(self): self.vRad.setEnabled(True) self.nRad.setEnabled(True) self.aRad.setEnabled(True) self.pRad.setEnabled(True) self.okBut.setEnabled(True) self.wordEntry.setEnabled(False) self.tranEntry.setEnabled(False) self.wordEntry.clear() self.tranEntry.clear() def new(self): self.vRad.setEnabled(True) self.nRad.setEnabled(True) self.aRad.setEnabled(True) self.pRad.setEnabled(True) self.okBut.setEnabled(True) self.wordEntry.setEnabled(False) self.tranEntry.setEnabled(False) self.wordEntry.clear() self.tranEntry.clear() def exit(self): confirm = QMessageBox.question(self.w, 'Quit', 'Are you sure you want to exit?', QMessageBox.Yes | QMessageBox.No) if confirm == QMessageBox.Yes: self.close() else: pass def getDics(self): try: v = open('verb.txt', 'r') self.verbDic = json.load(v) v.close() except: self.verbDic = [] try: n = open('noun.txt', 'r') self.nounDic = json.load(n) n.close() except: self.nounDic = [] try: p = open('phrase.txt', 'r') self.phraseDic = json.load(p) p.close() except: self.phraseDic = [] try: a = open('adj.txt', 'r') self.adjDic = json.load(a) a.close() except: self.phraseDic = [] def setLists(self): for item in self.verbDic: self.wordList.append(item[0]) for item in self.nounDic: self.wordList.append(item[0]) for item in self.phraseDic: self.wordList.append(item[0]) for item in self.adjDic: self.wordList.append(item[0])
class Index(QWidget): show_mainindex_sg = pyqtSignal(int, str) show_register_sg = pyqtSignal() def __init__(self, parent=None): super(Index, self).__init__(parent) self.desktop = QApplication.desktop() self.screenRect = self.desktop.screenGeometry() self.h = self.screenRect.height() self.w = self.screenRect.width() self.xr = self.w / 930 self.yr = self.h / 640 self.zr = min(self.xr, self.yr) self.top_wi = QWidget(self) self.logo_la = QLabel(self.top_wi) self.ind_wi = QWidget(self) self.login_but = QPushButton(self.ind_wi) self.joke_but = QPushButton(self.ind_wi) self.register_but = QPushButton(self.ind_wi) self.imp_la = QLabel(self.ind_wi) self.account_le = QLineEdit(self.ind_wi) self.psw_le = QLineEdit(self.ind_wi) self.loading = QLabel(self) self.gif = QMovie('./resource/image/load.gif') self.set_ui() with open('index.qss', 'r') as f: self.setStyleSheet(f.read()) def set_ui(self): self.setWindowTitle('Login') self.setObjectName('index') self.resize(self.w, self.h) self.top_wi.setObjectName('top') self.top_wi.resize(930 * self.xr, 95 * self.yr) self.logo_la.setObjectName('logo') self.logo_la.resize(65 * self.xr, 65 * self.zr) self.logo_la.move(29 * self.xr, 16 * self.yr) effect = QGraphicsDropShadowEffect() effect.setOffset(10, 10) effect.setColor(QColor(0, 0, 0, 80)) effect.setBlurRadius(20) self.ind_wi.setObjectName('login') self.ind_wi.resize(327 * self.xr, 388 * self.yr) self.ind_wi.move(300 * self.xr, 150 * self.yr) self.ind_wi.setGraphicsEffect(effect) self.joke_but.setObjectName('joke') self.joke_but.resize(130 * self.xr, 30 * self.yr) self.joke_but.move(76 * self.xr, 234 * self.yr) self.joke_but.setFlat(True) self.joke_but.setText('忘记密码?我也没办法') self.login_but.setObjectName('button') self.login_but.move(64 * self.xr, 260 * self.yr) self.login_but.resize(202 * self.xr, 45 * self.yr) self.login_but.setText('登陆') self.login_but.clicked.connect(self.login) self.register_but.setObjectName('button') self.register_but.move(64 * self.xr, 315 * self.yr) self.register_but.resize(202 * self.xr, 45 * self.yr) self.register_but.setText('注册') self.register_but.clicked.connect(self.show_register) self.imp_la.setObjectName('imp_label') self.imp_la.resize(100 * self.zr, 100 * self.zr) self.imp_la.move(115 * self.xr + 100 * (self.xr - self.zr) / 2, 15 * self.yr) self.imp_la.setStyleSheet('border-radius:{}px;'.format(self.zr * 49)) self.account_le.setObjectName('input') self.account_le.setTextMargins(20, 0, 0, 0) self.account_le.resize(213 * self.xr, 45 * self.yr) self.account_le.move(59 * self.xr, 126 * self.yr) self.account_le.setPlaceholderText('账号') self.psw_le.setObjectName('input') self.psw_le.setTextMargins(20, 0, 0, 0) self.psw_le.resize(213 * self.xr, 45 * self.yr) self.psw_le.move(59 * self.xr, 181 * self.yr) self.psw_le.setPlaceholderText('密码') self.psw_le.setEchoMode(QLineEdit.Password) self.loading.setObjectName('load') self.loading.resize(self.xr * 150, self.yr * 150) self.loading.move(self.xr * 760, self.yr * 500) self.loading.setScaledContents(True) self.loading.setMovie(self.gif) self.gif.start() self.ind_wi.setStyleSheet('#input{border-radius:' + str(self.zr * 20) + 'px;}' + '#button{border-radius:' + str( self.zr * 20) + 'px;' + 'font-size:' + str(int(self.zr * 18)) + 'px;}') def login(self): account_p = self.account_le.text() psw_p = self.psw_le.text() dic = login(account_p, psw_p) if dic['status'] == 0: self.show_mainindex_sg.emit(dic['data']['user_id'], dic['data']['token']) elif dic['status'] == 1: self.account_le.clear() self.psw_le.clear() self.account_le.setStyleSheet('border:4px solid;border-color:red;') self.account_le.setPlaceholderText('网络超时') else: self.account_le.clear() self.psw_le.clear() self.account_le.setStyleSheet('border:4px solid;border-color:red;') self.account_le.setPlaceholderText('账号不存在或密码错误') def show_register(self): self.show_register_sg.emit()
class Search(QWidget): search_sg = pyqtSignal(dict) back_sg = pyqtSignal() def __init__(self, parent=None): super(Search, self).__init__(parent) self.desktop = QApplication.desktop() self.screenRect = self.desktop.screenGeometry() self.h = self.screenRect.height() self.w = self.screenRect.width() self.xr = self.w / 930 self.yr = self.h / 640 self.zr = min(self.xr, self.yr) self.token = '' self.head = QLabel(self) self.search = QLineEdit(self) self.butt = QPushButton(self) self.but = QPushButton(self) self.set_ui() def set_ui(self): self.search.setObjectName('search') self.search.resize(self.xr * 520, self.yr * 40) self.search.move(self.xr * 205, self.yr * 300) self.search.setPlaceholderText('请输入战局ID') self.search.setTextMargins(20, 0, 0, 0) self.search.setStyleSheet('font-size:{}px;border-radius:{}px;'.format(int(self.zr * 16), self.zr * 15)) self.head.setObjectName('head') self.head.resize(self.xr * 200, self.yr * 50) self.head.move(self.xr * 360, self.yr * 240) self.head.setText('搜索战局') self.head.setAlignment(Qt.AlignCenter) self.head.setStyleSheet('font-size:{}px;'.format(int(self.zr * 25))) self.but.setObjectName('button') self.but.resize(self.xr * 130, self.yr * 40) self.but.move(self.xr * 480, self.yr * 380) self.but.setText('返回') self.but.clicked.connect(self.back_for) self.butt.setObjectName('button') self.butt.resize(self.xr * 130, self.yr * 40) self.butt.move(self.xr * 320, self.yr * 380) self.butt.setText('搜索') self.butt.clicked.connect(self.search_for) self.setStyleSheet('#button{font-size:' + str(int(self.zr * 18)) + 'px;border-radius:' + str( self.zr * 15) + 'px;background-color:#333643;color:#ffffff;}#button:hover{background-color:#575B6E;}#button:pressed{background-color:#202129;}') def search_for(self): id_p = self.search.text() self.search.clear() dic = find_info(id_p, self.token) # print(dic) if dic['status'] == 0: self.search_sg.emit(dic) else: self.search.setStyleSheet( 'font-size:{}px;border-radius:{}px;border:4px solid;border-color:red'.format(int(self.zr * 16), self.zr * 15)) self.search.clear() self.search.setPlaceholderText('ID不存在') def back_for(self): self.back_sg.emit() def get_token(self, t): self.token = t
class Register(QWidget): register_ok_sg = pyqtSignal() def __init__(self, parent=None): super(Register, self).__init__(parent) self.desktop = QApplication.desktop() self.screenRect = self.desktop.screenGeometry() self.h = self.screenRect.height() self.w = self.screenRect.width() self.xr = self.w / 930 self.yr = self.h / 640 self.zr = min(self.xr, self.yr) self.top_wi = QWidget(self) self.logo_la = QLabel(self.top_wi) self.ind_wi = QWidget(self) self.register_but = QPushButton(self.ind_wi) self.imp_la = QLabel(self.ind_wi) self.account_le = QLineEdit(self.ind_wi) self.psw_le = QLineEdit(self.ind_wi) self.name_le = QLineEdit(self.ind_wi) self.set_ui() with open('index.qss', 'r') as f: self.setStyleSheet(f.read()) def set_ui(self): self.setWindowTitle('Register') self.setObjectName('register') self.resize(self.w, self.h) self.top_wi.setObjectName('top') self.top_wi.resize(930 * self.xr, 95 * self.yr) self.logo_la.setObjectName('logo') self.logo_la.resize(65 * self.xr, 65 * self.zr) self.logo_la.move(29 * self.xr, 16 * self.yr) effect = QGraphicsDropShadowEffect() effect.setOffset(10, 10) effect.setColor(QColor(0, 0, 0, 80)) effect.setBlurRadius(20) self.ind_wi.setObjectName('login') self.ind_wi.resize(327 * self.xr, 388 * self.yr) self.ind_wi.move(300 * self.xr, 150 * self.yr) self.ind_wi.setGraphicsEffect(effect) self.register_but.setObjectName('button') self.register_but.move(64 * self.xr, 315 * self.yr) self.register_but.resize(202 * self.xr, 45 * self.yr) self.register_but.setText('注册新用户') self.register_but.clicked.connect(self.register) self.imp_la.setObjectName('imp_label') self.imp_la.resize(100 * self.zr, 100 * self.zr) self.imp_la.move(115 * self.xr + 100 * (self.xr - self.zr) / 2, 15 * self.yr) self.imp_la.setStyleSheet('border-radius:{}px;'.format(self.zr * 49)) self.account_le.setObjectName('input') self.account_le.setTextMargins(20, 0, 0, 0) self.account_le.resize(213 * self.xr, 45 * self.yr) self.account_le.move(59 * self.xr, 126 * self.yr) self.account_le.setPlaceholderText('账号') self.psw_le.setObjectName('input') self.psw_le.setTextMargins(20, 0, 0, 0) self.psw_le.resize(213 * self.xr, 45 * self.yr) self.psw_le.move(59 * self.xr, 181 * self.yr) self.psw_le.setPlaceholderText('密码') self.psw_le.setEchoMode(QLineEdit.Password) self.name_le.setObjectName('input') self.name_le.setTextMargins(20, 0, 0, 0) self.name_le.resize(213 * self.xr, 45 * self.yr) self.name_le.move(59 * self.xr, 236 * self.yr) self.name_le.setPlaceholderText('昵称') self.ind_wi.setStyleSheet('#input{border-radius:' + str(self.zr * 20) + 'px;}' + '#button{border-radius:' + str(self.zr * 20) + 'px;' + 'font-size:' + str(int(self.zr * 18)) + 'px;}') def register(self): account_p = self.account_le.text() psw_p = self.psw_le.text() # name_p = self.name_le.text() dic = register(account_p, psw_p) if dic['status'] == 1001: self.account_le.clear() self.psw_le.clear() self.account_le.setStyleSheet('border:4px solid;border-color:red;') self.account_le.setPlaceholderText('账号已存在') elif dic['status'] == 0: self.register_ok_sg.emit() else: self.account_le.clear() self.psw_le.clear() self.account_le.setStyleSheet('border:4px solid;border-color:red;') self.account_le.setPlaceholderText('未知错误')
class LLT_Lookup(QMainWindow): def __init__(self): super(LLT_Lookup, self).__init__() self.w = QWidget() self.setCentralWidget(self.w) self.verbDic = [] self.nounDic = [] self.adjDic = [] self.phraseDic = [] self.wordList = [] self.wordDic = [] self.index = int(0) self.w.setWindowTitle("Word Lookup") self.w.setGeometry(0,0,500, 500) self.lookLab = QLabel("Lookup: ") self.lookEntry = QLineEdit() self.lookBut = QPushButton("Search") self.lookBut.clicked.connect(self.search) self.wordLab = QLabel("Word: ") self.resultWord = QLabel() self.tranLab = QLabel("Translation: ") self.resultTran = QLabel() self.newBut = QPushButton("New Search") self.newBut.clicked.connect(self.new) self.exitBut = QPushButton("Exit") self.exitBut.clicked.connect(self.exit) grid = QGridLayout() grid.addWidget(self.lookLab, 0, 0) grid.addWidget(self.lookEntry, 0, 1, 1, 2) grid.addWidget(self.lookBut, 0, 3) grid.addWidget(self.wordLab, 1, 0) grid.addWidget(self.resultWord, 1, 1, 1, 3) grid.addWidget(self.tranLab, 2, 0) grid.addWidget(self.resultTran, 2, 1, 1, 3) grid.addWidget(self.newBut, 3, 0) grid.addWidget(self.exitBut, 3, 3) self.getDics() self.setLists() self.w.setLayout(grid) self.w.show() def search(self): searchWord = self.lookEntry.text().upper().strip() if searchWord in self.wordList: self.lookEntry.setEnabled(False) self.lookBut.setEnabled(False) self.index = self.wordList.index(searchWord) foundWord = self.wordDic[self.index] self.resultWord.setText(foundWord[0]) self.resultTran.setText(foundWord[1]) else: msgBox = QMessageBox() msgBox.setText("Word not currently saved in dictionary.") msgBox.exec_(); def new(self): self.lookEntry.setEnabled(True) self.lookBut.setEnabled(True) self.resultWord.setText('') self.resultTran.setText('') self.lookEntry.clear() def exit(self): confirm = QMessageBox.question(self.w, 'Quit', 'Are you sure you want to exit?', QMessageBox.Yes | QMessageBox.No) if confirm == QMessageBox.Yes: self.close() else: pass def getDics(self): try: v=open('verb.txt','r') self.verbDic=json.load(v) v.close() except: self.verbDic = [] try: n=open('noun.txt','r') self.nounDic=json.load(n) n.close() except: self.nounDic = [] try: p=open('phrase.txt','r') self.phraseDic=json.load(p) p.close() except: self.phraseDic = [] try: a=open('adj.txt','r') self.adjDic=json.load(a) a.close() except: self.phraseDic = [] def setLists(self): for item in self.verbDic: self.wordList.append(item[0]) self.wordDic.append(item) for item in self.nounDic: self.wordList.append(item[0]) self.wordDic.append(item) for item in self.adjDic: self.wordList.append(item[0]) self.wordDic.append(item) for item in self.phraseDic: self.wordList.append(item[0]) self.wordDic.append(item)
class MainWindow(QMainWindow): # 求解完成信号 done1Signal = pyqtSignal(str) done2Signal = pyqtSignal(str) def __init__(self): super().__init__() # 移动两根火柴和移动一根火柴的按钮 self.twobtn = QPushButton(self) self.onebtn = QPushButton(self) # 文本输入框以及提示字符,接受输入的等式 self.tip1 = QLabel(self) self.facin1 = QLineEdit(self) self.opin = QLineEdit(self) self.tipop = QLabel(self) self.facin2 = QLineEdit(self) self.tip2 = QLabel(self) self.ansin = QLineEdit(self) self.equaop = QLabel(self) self.tipans = QLabel(self) self.toolbar = QToolBar() # 数码管显示,由于算符无法使用故使用QLabel代替 self.lcd1 = QLCDNumber(self) self.lcd2 = QLCDNumber(self) self.lcd3 = QLCDNumber(self) self.lcd1.setDigitCount(2) self.lcd2.setDigitCount(2) self.lcd3.setDigitCount(2) self.lcd1.setMode(QLCDNumber.Dec) self.lcd2.setMode(QLCDNumber.Dec) self.lcd3.setMode(QLCDNumber.Dec) self.lcd1.setSegmentStyle(QLCDNumber.Flat) self.lcd1.setStyleSheet("border: 2px solid black; color: green; background: silver;") self.lcd2.setSegmentStyle(QLCDNumber.Flat) self.lcd2.setStyleSheet("border: 2px solid black; color: green; background: silver;") self.lcd3.setSegmentStyle(QLCDNumber.Flat) self.lcd3.setStyleSheet("border: 2px solid black; color: green; background: silver;") self.lcdop = QLabel(self) self.lcdeq = QLabel(self) # 上翻,下翻展示 self.last = QPushButton(self) self.next = QPushButton(self) # 提示信息,提示是否有解,有解还将显示难度系数 self.tips = QTextBrowser(self) # 程序名及版本号 self.version = 'SmartMatch_v1.1.18' # 帮助子窗口 self.help = HelpWindow() # 等式库子窗口 self.lib = LibraryWindow() # 移动一根所有变化的状态空间 self.closed1 = [] # 移动两根所有变化的状态空间 self.closed2 = [] # 等式列表 self.showlist = [] # 是否可保存 self.allowed = 0 # 等式列表中当前的等式序号 self.now = 0 # 输入为等式的标记 self.initeq = 0 # 状态栏 self.status = self.statusBar() self.init_ui() def init_ui(self): # 两个列表存放搜索结果 # 默认使用了我的桌面分辨率大小的标准尺寸 width = 1440 height = 900 x = width / 4 y = height / 4 w = width / 2 h = height / 2 # 创建全屏主窗口 self.setGeometry(x, y, w, h) self.setWindowTitle(self.version) self.setWindowIcon(QIcon("../images/icon.jpg")) #设置主窗口背景 palette = QPalette() palette.setBrush(self.backgroundRole(), QBrush(QPixmap('../images/background.png'))) self.setPalette(palette) # 进入后的提示信息 self.status.showMessage("欢迎") # 创建工具栏 self.addToolBar(self.toolbar) self.facin1.move(w / 6, h / 4) self.facin1.resize(w / 12, h / 12) self.facin1.setMaxLength(2) self.facin1.setFont(QFont('Roman times', 20, QFont.DemiBold)) self.facin1.setAlignment(Qt.AlignCenter) self.tip1.move(w / 6, h / 6) self.tip1.resize(w / 12, h / 12) self.tip1.setText('Number1:') self.tip1.setFont(QFont('Roman times', 12, QFont.DemiBold)) self.tip1.setAlignment(Qt.AlignCenter) self.opin.move(w/3, h / 4) self.opin.resize(w / 24, h / 12) self.opin.setMaxLength(1) self.opin.setFont(QFont('Roman times', 20, QFont.DemiBold)) self.opin.setAlignment(Qt.AlignCenter) self.tipop.move(5*w/16, h / 6) self.tipop.resize(w / 12, h / 12) self.tipop.setText('Operator:') self.tipop.setFont(QFont('Roman times', 12, QFont.DemiBold)) self.tipop.setAlignment(Qt.AlignCenter) self.facin2.move(11*w/24, h / 4) self.facin2.resize(w / 12, h / 12) self.facin2.setMaxLength(2) self.facin2.setFont(QFont('Roman times', 20, QFont.DemiBold)) self.facin2.setAlignment(Qt.AlignCenter) self.tip2.move(11*w/24, h / 6) self.tip2.resize(w / 12, h / 12) self.tip2.setText('Number2:') self.tip2.setFont(QFont('Roman times', 12, QFont.DemiBold)) self.tip2.setAlignment(Qt.AlignCenter) self.equaop.move(5*w/8, h / 4) self.equaop.resize(w / 24, h / 12) self.equaop.setText('=') self.equaop.setFont(QFont('Roman time2', 20, QFont.DemiBold)) self.equaop.setAlignment(Qt.AlignCenter) self.ansin.move(3*w/4, h / 4) self.ansin.resize(w / 12, h / 12) self.ansin.setMaxLength(2) self.ansin.setFont(QFont('Roman times', 20, QFont.DemiBold)) self.ansin.setAlignment(Qt.AlignCenter) self.tipans.move(3*w/4, h / 6) self.tipans.resize(w / 12, h / 12) self.tipans.setText('Answer:') self.tipans.setFont(QFont('Roman times', 12, QFont.DemiBold)) self.tipans.setAlignment(Qt.AlignCenter) # 移动一根火柴按钮 self.onebtn.move(w / 3, 3 * h / 8) self.onebtn.resize(w / 3, h / 16) self.onebtn.setText('搜索只移动一根火柴的结果') self.onebtn.setStatusTip('开始搜索只移动一根火柴的所有结果') self.onebtn.clicked.connect(lambda: self.startSearch(1)) # 移动两根火柴按钮 self.twobtn.move(w / 3, 7 * h / 16) self.twobtn.resize(w / 3, h / 16) self.twobtn.setText('搜索只移动两根火柴的结果') self.twobtn.setStatusTip('开始搜索只移动两根火柴的所有结果') self.twobtn.clicked.connect(lambda: self.startSearch(2)) # LCD显示摆放 self.lcd1.move(w/6, 7*h/12) self.lcd1.resize(w/12, h/8) self.lcd2.move(11*w/24, 7*h/12) self.lcd2.resize(w/12, h/8) self.lcd3.move(3*w/4, 7*h/12) self.lcd3.resize(w/12, h/8) self.lcdeq.move(5*w/8, 7*h/12) self.lcdeq.resize(w/24, h/8) self.lcdeq.setText('=') self.lcdeq.setStyleSheet("font:30pt;border-width: 2px;border-style: solid;border-color: rgb(0, 0, 0);" "background:silver;color: green;") self.lcdeq.setAlignment(Qt.AlignCenter) self.lcdop.move(w/3, 7*h/12) self.lcdop.resize(w/24, h/8) self.lcdop.setStyleSheet("font:30pt;border-width: 2px;border-style: solid;border-color: rgb(0, 0, 0);" "background:silver;color: green;") self.lcdop.setAlignment(Qt.AlignCenter) # 状态信息显示 self.tips.move(w/6, 3*h/4) self.tips.resize(2*w/3, h/10) self.tips.setStyleSheet("background:white;font:12pt") # 上翻下翻 self.last.move(w/4, 17*h/20) self.last.resize(w/8, h/18) self.last.setText('上一个') self.last.setStatusTip('查看上一个可行解') self.last.clicked.connect(lambda: self.changeShow(1)) self.next.move(5*w/8, 17*h/20) self.next.resize(w/8, h/18) self.next.setText('下一个') self.next.setStatusTip('查看下一个可行解') self.next.clicked.connect(lambda: self.changeShow(2)) # 退出动作 exitAct = QAction(QIcon('../images/exit.png'), '&Exit', self) # mac系统下的快捷键 exitAct.setShortcut('command+Q') exitAct.setStatusTip('退出') exitAct.setToolTip('快捷键:command+Q') exitAct.triggered.connect(lambda: self.sureClose()) # 移动一根火柴动作 start1Act = QAction(QIcon('../images/start1.png'), '&Start1', self) start1Act.setShortcut('command+W') start1Act.setToolTip('快捷键:command+W') start1Act.setStatusTip('开始搜索只移动一根火柴的所有结果') start1Act.triggered.connect(lambda: self.startSearch(1)) # 移动两根火柴动作 start2Act = QAction(QIcon('../images/start2.png'), '&Start2', self) start2Act.setShortcut('command+E') start2Act.setToolTip('快捷键:command+E') start2Act.setStatusTip('开始搜索只移动两根火柴的所有结果') start2Act.triggered.connect(lambda: self.startSearch(2)) # 从库中选择等式动作 openLib = QAction(QIcon('../images/lib.png'), '&Library', self) openLib.setShortcut('command+R') openLib.setToolTip('快捷键:command+R') openLib.setStatusTip('打开已有等式库') openLib.triggered.connect(lambda: self.openLibrary()) # 打开帮助和信息界面 openHelp = QAction(QIcon('../images/help.png'), '&Help', self) openHelp.setShortcut('command+A') openHelp.setToolTip('快捷键:command+A') openHelp.setStatusTip('打开帮助界面') openHelp.triggered.connect(lambda: self.openHelp()) # 保存可解等式动作 saveEquation = QAction(QIcon('../images/save.png'), '&Save', self) saveEquation.setShortcut('command+S') saveEquation.setToolTip('快捷键:command+S') saveEquation.setShortcut('保存可解的等式') saveEquation.setStatusTip('保存当前的可解等式') saveEquation.triggered.connect(lambda: self.saveEquation()) # 清除输入和工作区动作 clearAll = QAction(QIcon('../images/clear.png'), 'Clear', self) clearAll.setShortcut('command+C') clearAll.setToolTip('快捷键:command+C') clearAll.setShortcut('清除输入及变量') clearAll.setStatusTip('清除输入及变量') clearAll.triggered.connect(lambda: self.clearAction()) self.toolbar.addAction(start1Act) self.toolbar.addAction(start2Act) self.toolbar.addAction(clearAll) self.toolbar.addAction(openLib) self.toolbar.addAction(saveEquation) self.toolbar.addAction(openHelp) self.toolbar.addAction(exitAct) # 信号和槽连接 self.done1Signal.connect(self.getDone1) self.done2Signal.connect(self.getDone2) # 主功能函数,移动一根或两根全搜索 def startSearch(self, num): self.varClear() self.lcdClear() common = '请确保{}方格内输入{}。' if self.facin1.text() == '': warn = QMessageBox.about(self, '错误提示', common.format('Number1', '数字')) self.status.showMessage('空输入错误') elif self.facin2.text() == '': warn = QMessageBox.about(self, '错误提示', common.format('Number2', '数字')) self.status.showMessage('空输入错误') elif self.ansin.text() == '': warn = QMessageBox.about(self, '错误提示', common.format('Answer', '数字')) self.status.showMessage('空输入错误') elif self.opin.text() == '': warn = QMessageBox.about(self, '错误提示', common.format('Operator', '"+", "-"或"*"号')) self.status.showMessage('空输入错误') else: try: fac1 = str(self.facin1.text()) for x in range(0, len(fac1)): int(fac1[x]) fac2 = str(self.facin2.text()) for x in range(0, len(fac2)): int(fac2[x]) ans = str(self.ansin.text()) for x in range(0, len(ans)): int(ans[x]) except ValueError: warn = QMessageBox.about(self, '类型错误', common.format('Number1, Nubmber2和Answer', '仅为阿拉伯数字')) self.status.showMessage('输入类型错误') else: fac1 = str(self.facin1.text()) fac2 = str(self.facin2.text()) op = str(self.opin.text()) ans = str(self.ansin.text()) if not(op == '+' or op == '-' or op == '*'): warn = QMessageBox.about(self, '类型错误', common.format('Operator', '"+", "-"或"*"号')) self.status.showMessage('输入类型错误') else: base = MatchEquation(fac1, fac2, ans, op) if num == 1: self.closed1 = onePerop(base) self.done1Signal.emit('Done') elif num == 2: self.closed2 = twoPerop(base) self.done2Signal.emit('Done') self.status.showMessage('完成') # 打开等式库子窗口,接收选择等式 def openLibrary(self): self.lib.show() self.lib.equationSignal.connect(self.getLibequation) # 打开帮助界面子窗口 def openHelp(self): self.help.show() # 接收等式库子窗口的信号 def getLibequation(self, connect): temp = '' for x in range(0, len(connect)): if connect[x] == '+' or connect[x] == '-' or connect[x] == '*': self.opin.setText(connect[x]) self.facin1.setText(temp) temp = '' elif connect[x] == '=': self.facin2.setText(temp) temp = '' else: temp = temp + connect[x] self.ansin.setText(temp) # 接受对移动一根火柴问题求解完成的信号 def getDone1(self, connect): ansNum = 0 for equation in self.closed1: if equation.equal == True: ansNum = ansNum + 1 self.showlist.append(equation) if ansNum == 0 or (ansNum == 1 and self.closed1[0] == self.showlist[0]): self.tips.setText('很抱歉,该等式通过移动一根火柴无解。') elif ansNum > 1 and self.closed1[0] == self.showlist[0]: self.allowed = 1 self.initeq = 1 self.now = self.now + 1 info1 = '该问题是将等式变为新的等式问题, 有{}种新等式' info2 = '该问题的难度系数为{:.2f}' self.tips.setText(info1.format(ansNum - 1) + '<br>' + info2.format(len(self.closed1) / (ansNum - 1))) self.lcd1.display(self.showlist[self.now].factor1.tostr()) self.lcd2.display(self.showlist[self.now].factor2.tostr()) self.lcd3.display(self.showlist[self.now].answer.tostr()) self.lcdop.setText(self.showlist[self.now].operator.tostr()) else: self.allowed = 1 info1 = '通过移动一根火柴使等式成立,有{}种可行的解法' info2 = '该问题的难度系数为{:.2f}' self.tips.setText(info1.format(ansNum)+'<br>'+info2.format(len(self.closed1) / ansNum)) self.lcd1.display(self.showlist[self.now].factor1.tostr()) self.lcd2.display(self.showlist[self.now].factor2.tostr()) self.lcd3.display(self.showlist[self.now].answer.tostr()) self.lcdop.setText(self.showlist[self.now].operator.tostr()) # 接受对移动两根火柴问题求解完成的信号 def getDone2(self, connect): ansNum = 0 for equation in self.closed2: if equation.equal == True: ansNum = ansNum + 1 self.showlist.append(equation) if ansNum == 0 or (ansNum == 1 and self.closed2[0] == self.showlist[0]): self.tips.setText('很抱歉,该等式通过移动两根火柴无解。') elif ansNum > 1 and self.closed2[0] == self.showlist[0]: self.allowed = 2 self.initeq = 1 self.now = self.now + 1 info1 = '该问题是将等式变为新的等式问题, 有{}种新等式' info2 = '该问题的难度系数为{:.2f}' self.tips.setText(info1.format(ansNum - 1) + '<br>' + info2.format(len(self.closed2) / (ansNum - 1))) self.lcd1.display(self.showlist[self.now].factor1.tostr()) self.lcd2.display(self.showlist[self.now].factor2.tostr()) self.lcd3.display(self.showlist[self.now].answer.tostr()) self.lcdop.setText(self.showlist[self.now].operator.tostr()) else: self.allowed = 2 info1 = '通过移动两根火柴使等式成立,有{}种可行的解法' info2 = '该问题的难度系数为{:.2f}' self.tips.setText(info1.format(ansNum) + '<br>' + info2.format(len(self.closed2)/ansNum)) self.lcd1.display(self.showlist[self.now].factor1.tostr()) self.lcd2.display(self.showlist[self.now].factor2.tostr()) self.lcd3.display(self.showlist[self.now].answer.tostr()) self.lcdop.setText(self.showlist[self.now].operator.tostr()) # 接受上下翻信号 def changeShow(self, flag): if flag == 1: if self.now == 0 or (self.initeq == 1 and self.now == 1): self.status.showMessage('已经是第一个结果') else: self.now = self.now - 1 elif flag == 2: if self.now + 1 == len(self.showlist): self.status.showMessage('已经是最后一个结果') else: self.now = self.now + 1 if len(self.showlist) > 0: self.lcd1.display(self.showlist[self.now].factor1.tostr()) self.lcd2.display(self.showlist[self.now].factor2.tostr()) self.lcd3.display(self.showlist[self.now].answer.tostr()) self.lcdop.setText(self.showlist[self.now].operator.tostr()) else: self.status.showMessage('您还未输入并求解问题') # 保存可行等式 def saveEquation(self): if len(self.showlist) > 0: aim = '' eq = '' flag = 0 if self.allowed == 1: aim = (self.closed1[0].factor1.tostr() + ';' + self.closed1[0].factor2.tostr() + ';' + self.closed1[0].answer.tostr() + ';' + self.closed1[0].operator.tostr() + ';\n') eq = (self.closed1[0].factor1.tostr() + self.closed1[0].operator.tostr() + self.closed1[0].factor2.tostr() + '=' + self.closed1[0].answer.tostr()) elif self.allowed == 2: aim = (self.closed2[0].factor1.tostr() + ';' + self.closed2[0].factor2.tostr() + ';' + self.closed2[0].answer.tostr() + ';' + self.closed2[0].operator.tostr() + ';\n') eq = (self.closed2[0].factor1.tostr() + self.closed2[0].operator.tostr() + self.closed2[0].factor2.tostr() + '=' + self.closed2[0].answer.tostr()) else: warn = QMessageBox.about(self, '无法保存', '抱歉,不可解等式无法保存!') flag = 1 lib = open('../data/library.txt', 'r+') equations = lib.readlines() for equation in equations: if aim == equation: warn = QMessageBox.about(self, '当前等式已存在', '感谢您的贡献!但您要添加的等式已在库中。') flag = 1 break if flag == 0: lib.writelines(aim) # 刷新等式库 self.lib.combobox.addItem(eq) lib.close() else: warn = QMessageBox.about(self, '无法保存', '抱歉,未被求解并证明可解的等式无法保存!') # 清空lcd显示 def lcdClear(self): self.lcd1.display('') self.lcd2.display('') self.lcd3.display('') self.lcdop.setText('') self.tips.setText('') # 清空所有需保存的变量 def varClear(self): self.closed1.clear() self.closed2.clear() self.showlist.clear() self.now = 0 self.allowed = 0 self.initeq = 0 # 清除输入及变量 def clearAction(self): self.facin1.clear() self.facin2.clear() self.opin.clear() self.ansin.clear() self.lcdClear() self.varClear() # 重写关闭函数 def closeEvent(self, QCloseEvent): reply = QMessageBox.question(self, '退出程序', "确认要退出吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: QCloseEvent.accept() else: QCloseEvent.ignore() # 关闭窗口确认 def sureClose(self): reply = QMessageBox.question(self, '退出程序', "确认要退出吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: qApp.quit()
class ImageDisplay(QWidget): video_infos = ['vidéo : {}','nb frames : {}','taille : {}','FPS : {}','durée : {:.2f} sec'] video_keys = ['videoname','nframes','size','fps','duration'] algo_traj = ['barycentre','minmax'] def __init__(self, mainWindow): # acall the base class constructor: super().__init__(mainWindow) self.mw = mainWindow # Attributs (objets persistants) self.img_lbl = QLabel(self) # to display the current image self.img_lbl.installEventFilter(self) # filter to catch evenements self.selectTargetRect = None # display a rectangle to show teh target color selection self.rubberBand = QRubberBand(QRubberBand.Line, self) # Boutons pour avancer/reculer self.btn_prev = QPushButton(QIcon("icones/go-prev.png"), "", self) self.btn_next = QPushButton(QIcon("icones/go-next.png"), "", self) self.btn_first = QPushButton(QIcon("icones/go-first.png"), "", self) self.btn_last = QPushButton(QIcon("icones/go-last.png"), "", self) self.btn_traj = QPushButton(QIcon("icones/extract.png"), "Extraire...", self) self.btn_clear = QPushButton(QIcon("icones/clear.png"), "Effacer courbes...", self) self.btn_exportCSV = QPushButton(QIcon("icones/exportCSV.png"), "Export CSV", self) self.btn_algo = QComboBox(self) self.image_index = QLabel(self) # widget QSpinBox self.images_step = QSpinBox(parent=self) self.images_firstRank = QSpinBox(parent=self) self.images_lastRank = QSpinBox(parent=self) # QLabel to display the target color self.target_color_label = QLabel("target color",parent=self) self.picked_color = QLabel(self) self.video_path = None # Chemin de la dernière vidéo self.images_dir = None # Dossier contenant les images self.__img_idx = None # Rang de l'image affichée self.img_path = None # nom du chemin de l'image courante self.nb_img = None # nombre d'images self.video_name = None # nom de la video ("aaaaaa.mp4") self.video_nframes = None # nombre d'images dans la video self.video_size = None # taille (width, height) des images self.video_FPS = None # nombre d'images par seconde self.video_duration = None # durée de la video en secondes self.videoLabels = [] # liste de QLabel contenant les infos vidéo self.dico_video = {} # dictionnaire des méta-données self.dico_unit = {} # dictionary "pixels", "mm" self.scale_pixel = None # nombre de pixels pour conversion en mm self.scale_mm = None # nbre de mm pour scale_pixel self.valid_scale = False # données de l'échelle valides ou pas self.pix_to_mm_coeff= 1. # le coefficient de converion pixels -> mm self.dicoScale = {} # dictionnaire des QWidget d'info scale self.lbl_epsilon = None # label epsilon self.epsi_spin = None # boite de choix de epsilon # créer l'onglet de visualisation image """ self.__initUI() self.scaleInfoVisible(False) self.__epsilonVisible(False) def __initUI(self): # Onglet "Visualisation images" vbox = QVBoxLayout() # Ligne 1 : extraction trajec self.picked_color.setFrameStyle(QFrame.StyledPanel | QFrame.Plain); line1 = QHBoxLayout() line1.addStretch(1) line1.addWidget(self.btn_algo) line1.addWidget(self.btn_traj) line1.addWidget(self.target_color_label) line1.addWidget(self.picked_color) line1.addWidget(self.btn_clear) line1.addWidget(self.btn_exportCSV) line1.addStretch(1) # Ligne 2 : infos video + visu image line2 = QHBoxLayout() # boîte d'infos sur la vidéo infoVBox = QVBoxLayout() for _ in ImageDisplay.video_infos: label = QLabel(self) label.setFrameStyle(QFrame.StyledPanel | QFrame.Plain); infoVBox.addWidget(label) self.videoLabels.append(label) infoVBox.addStretch() widget = QLabel("Conversion pixels -> mm", self) self.dicoScale['Pixels-mm'] = widget infoVBox.addWidget(widget) grid = QGridLayout() infoVBox.addLayout(grid) widget = QLabel("pixels ",self) self.dicoScale['pixels'] = widget grid.addWidget(widget,1,1) self.scale_pixel = QLineEdit(self) self.dicoScale['pixelsForMM'] = self.scale_pixel grid.addWidget(self.scale_pixel,1,2) widget = QLabel("millimètres ",self) self.dicoScale['millimeters'] = widget grid.addWidget(widget,2,1) self.scale_mm = QLineEdit(self) self.dicoScale['mmForPixels'] = self.scale_mm grid.addWidget(self.scale_mm,2,2) self.lbl_epsilon = QLabel("Epsilon ",self) grid.addWidget(self.lbl_epsilon,5,1) self.epsi_spin = QSpinBox(self) self.epsi_spin.setRange(1,50) self.epsi_spin.setSingleStep(1) self.epsi_spin.setValue(10) grid.addWidget(self.epsi_spin,5,2) infoVBox.addStretch() line2.addLayout(infoVBox) line2.addStretch(1) line2.addWidget(self.img_lbl) # le QLabel por afficher l'image line2.addStretch(1) # line 3 : navigation boutons self.image_index.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.image_index.setText(" ") line3 = QHBoxLayout() line3.addStretch(1) line3.addWidget(self.btn_first) line3.addWidget(self.btn_prev) line3.addWidget(self.image_index) line3.addWidget(self.btn_next) line3.addWidget(self.btn_last) line3.addStretch(1) # line 4 : first , step, last image selection line4 = QHBoxLayout() line4.addStretch(1) line4.addWidget(self.images_firstRank) line4.addWidget(self.images_step) line4.addWidget(self.images_lastRank) line4.addStretch(1) vbox.addLayout(line1) vbox.addStretch(1) vbox.addLayout(line2) vbox.addStretch(1) vbox.addLayout(line3) vbox.addLayout(line4) self.setLayout(vbox) self.buttonsState() self.__buttonsConnect() self.__setVideoLabelVisible(False) def __setVideoLabelVisible(self, state): for label in self.videoLabels: label.setVisible(state) def __buttonsConnect(self): self.btn_traj.clicked.connect(self.extract_trajectoire) self.btn_clear.clicked.connect(self.mw.clearPlots) self.btn_exportCSV.clicked.connect(self.mw.ExportCSV) self.btn_prev.clicked.connect(self.prev_image) self.btn_next.clicked.connect(self.next_image) self.btn_first.clicked.connect(self.first_image) self.btn_last.clicked.connect(self.last_image) self.images_step.valueChanged.connect(self.__step_changed) self.images_firstRank.valueChanged.connect(self.__first_rank_changed) self.images_lastRank.valueChanged.connect(self.__last_rank_changed) def buttonsState(self, importCSV=False): self.btn_traj.setEnabled(False) self.picked_color.setText("X") self.picked_color.setEnabled(False) self.btn_traj.setStatusTip('Extrait la trajectoire de la cible'+ 'dont la couleur a été choisie') self.target_color_label.setEnabled(False) self.picked_color.setStyleSheet('background-color : rgb(255, 255, 255)') self.btn_clear.setEnabled(False) self.btn_clear.setStatusTip('Nettoye tous les tracés des onglets'+ '<trajectoire> et <X(t), Y(t)>') self.btn_exportCSV.setEnabled(False) texte = "Export des données dans un fichier CSV" self.btn_exportCSV.setStatusTip(texte) if not importCSV: self.btn_algo.addItems(ImageDisplay.algo_traj) self.btn_algo.setEnabled(False) self.btn_prev.setEnabled(False) self.btn_prev.setStatusTip("affiche l'image précédente") self.btn_next.setEnabled(False) self.btn_next.setStatusTip("affiche l'image suivante") self.btn_first.setEnabled(False) self.btn_first.setStatusTip("affiche la première image à traiter") self.btn_last.setEnabled(False) self.btn_last.setStatusTip("affiche la dernière image à traiter") # SpinBoxes parameters: self.images_step.setRange(1,1000) self.images_step.setSingleStep(1) self.images_step.setValue(1) self.images_step.setPrefix("step: ") self.images_step.setEnabled(False) self.images_step.setStatusTip("Fixe le pas pour passer d'une image à l'autre") self.images_firstRank.setRange(1,1000) self.images_firstRank.setSingleStep(1) self.images_firstRank.setValue(1) self.images_firstRank.setPrefix("first: ") self.images_firstRank.setEnabled(False) self.images_firstRank.setStatusTip("Fixe le rang de la première image à traiter") self.images_lastRank.setRange(1,10000) self.images_lastRank.setSingleStep(1) self.images_lastRank.setValue(1) self.images_lastRank.setPrefix("last: ") self.images_lastRank.setEnabled(False) self.images_lastRank.setStatusTip("Fixe le rang de la dernière image à traiter") def __first_rank_changed(self, val): if self.img_idx is None: return if self.img_idx < val: self.img_idx = val self.show_image() def __last_rank_changed(self, val): if self.img_idx is None: return if self.img_idx > val: self.img_idx = val self.show_image() def __step_changed(self, val): if self.img_idx is None: return def setTextInfoVideoGrid(self): for field, name, key in zip(self.videoLabels, ImageDisplay.video_infos, ImageDisplay.video_keys): mess = name.format(self.dico_video.get(key,'?')) field.setText(mess) self.__setVideoLabelVisible(True) def scaleInfoVisible(self, state): for widget in self.dicoScale.values(): widget.setVisible(state) def __epsilonVisible(self, state): self.lbl_epsilon.setVisible(state) self.epsi_spin.setVisible(state) def open_video(self): '''Lance un sélecteur de fichier pour choisir la vidéo à traiter.''' fname = QFileDialog.getOpenFileName(None, 'Choisir une vidéo', self.mw.cur_dir, 'Fichier vidéo (*.mp4)') if fname[0] != '' : # un fichier vidéo a été chosi : vp = fname[0] if self.video_path == vp : name = os.path.basename(vp) rep = QMessageBox.question(self, # widget parent de QMessageBox 'Question', # texte du bandeau de la fenêtre 'Voulez-vous recharger le fichier video {} ?'.format(name), QMessageBox.Yes | QMessageBox.No, # afficher les boutons Yes et No QMessageBox.No) # bouton No sélectionné par défaut if rep == QMessageBox.No: return # fichier vidéo à traiter => faire le split des images : self.video_path = vp self.extract_images_from_video() def load_images_from_directory(self): '''Charge les images '*.png' contenue dans le répertoire des images choisi avec un sélecteur graphique.''' # Choix du répertoire avec un sélecteur de fichier : dname = QFileDialog.getExistingDirectory(None, 'Choisir un dossier images', self.mw.image_dir) if dname != '' : # un répertoire valide a été choisi : self.video_path = None self.images_dir = dname + "/" try: # Lecture du fichier ascii des méta-données with open(self.images_dir + "metaData.txt", "r") as F: data = F.read() exec('self.dico_video = '+data) except: rep = QMessageBox.critical( None, # widget parent de QMessageBox 'Erreur', # bandeau de la fenêtre 'Pas de fichier de méta-données dans le répertoire'+\ ' <{}>'.format(os.path.basename(dname)), QMessageBox.Ok) return print("méta données :", self.dico_video) self.parse_meta_data() self.setTextInfoVideoGrid() # Mettre à jour l'application avec les nouvelles images chargées : self.update_images() def extract_trajectoire(self): '''Méthode utilisée pour extraire la trajectoire du centre de la cible pour toutes les images de la vidéo.''' # Récupérer l'algorithme de calcul du centre de la cible : algo = self.btn_algo.currentText() # Définition de la liste dans laquelle on va récupérer les coordonnées # du centre cible pour toutes les images : target_pos = [] # Création d'un objet ProgressBar qui va lancer le travail # d'extraction de la cible dans les images tout en affichant une # barre d'avancement : first = self.images_firstRank.value() last = self.images_lastRank.value() step = self.images_step.value() last = last - (last - first) % step first_last_step = (first, last, step) pg = ProgressBar(self.images_dir, self) pg.configure_for_target_extraction(self.mw.target_RGB, algo, self.epsi_spin.value(), target_pos, first_last_step) ret = pg.exec_() # lance la barre et le travail d'extraction... print("retour de pg.exec_() :",ret) if ret != 0: self.mw.target_pos = None return target_pos = np.array(target_pos) width, height = self.video_size # l'axe verticale est retourné et decalé: target_pos[1] = height - target_pos[1] self.scale_XY() self.mw.target_pos = target_pos self.display_plots() # remettre le bouton extraire_trajectoire disabled: self.btn_exportCSV.setEnabled(True) def display_plots(self): self.mw.clearPlots() # Plot trajectory (X(t), Y(t)) : self.mw.onePlot.setEnabled(True) self.mw.onePlot.Plot() # Plot curves X(t) and Y(t) self.mw.twoPlots_xy.setEnabled(True) self.mw.tabs.setCurrentWidget(self.mw.twoPlots_xy) self.mw.twoPlots_xy.Plot() # Plot curves VX(t) and VY(t) self.mw.twoPlots_VxVy.setEnabled(True) self.mw.tabs.setCurrentWidget(self.mw.twoPlots_xy) self.mw.twoPlots_VxVy.Plot() def extract_images_from_video(self) : # name of the video file without path and suffix: videoname = os.path.basename(self.video_path)[:-4] # directory where to put extracted iamges: self.images_dir = self.mw.image_dir + videoname + "/" if os.path.isdir(self.images_dir) : print("Effacement de tous les fichiers de '{}'"\ .format(self.images_dir)) for fn in os.listdir(self.images_dir) : os.remove(self.images_dir+fn) else : os.mkdir(self.images_dir) video = cv2.VideoCapture(self.video_path) self.dico_video['nframes'] = int(video.get(cv2.CAP_PROP_FRAME_COUNT)) self.dico_video['size'] = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))) self.dico_video['fps'] = int(video.get(cv2.CAP_PROP_FPS)) self.dico_video['duration'] = video.get(cv2.CAP_PROP_FRAME_COUNT)/video.get(cv2.CAP_PROP_FPS) self.dico_video['videoname'] = os.path.basename(self.video_path) self.parse_meta_data() self.dico_video["videoname"] = videoname+".mp4" self.setTextInfoVideoGrid() # Création d'un objet ProgressBar qui va lancer le travail # d'extraction des images tout en affichant une barre d'avancement : pg = ProgressBar(self.images_dir, self) pg.configure_for_video_extraction(video, self.mw.image_fmt) ret = pg.exec_() print("retour de pg.exec_() :", ret) if ret != 0: return # MAJ de la liste des fichiers images : self.update_images() # écriture des méta-data dans le fichier 'nom_video'.info with open(self.mw.image_dir+videoname+"/metaData.txt", "w") as F: F.write(str(self.dico_video)) def computeTargetColor(self, draw_selection=False): col_min,row_min,col_max,row_max = self.selection.getCoords() print("Pixels selectionnés : lignes [{},{}] colonnes [{},{}]".\ format(row_min, row_max, col_min, col_max)) tab = imread(self.img_path) self.target_pix = tab[row_min:row_max+1, col_min:col_max+1, :] R = round(self.target_pix[:,:,0].mean()) G = round(self.target_pix[:,:,1].mean()) B = round(self.target_pix[:,:,2].mean()) self.mw.target_RGB = np.array([R, G, B], dtype=int) print("RGB sélection dans <{}> :".format(os.path.basename(self.img_path)), self.mw.target_RGB) draw_selection = self.mw.flags["drawTargetSelection"] if draw_selection: self.show_image() print("drawTargetSelection") #if self.selectTargetRect is not None : del self.selectTargetRect # create painter instance with pixmap self.selectTargetRect = QPainter(self.img_lbl.pixmap()) # set rectangle color and thickness self.penRectangle = QPen(QColor(0,0,0)) self.penRectangle.setWidth(2) # draw rectangle on painter self.selectTargetRect.begin(self) self.selectTargetRect.setPen(self.penRectangle) self.selectTargetRect.drawRect(col_min,row_min, col_max-col_min,row_max-row_min) self.selectTargetRect.setOpacity(0.1) self.selectTargetRect.end() #self.show_image() self.btn_traj.setEnabled(True) self.btn_algo.setEnabled(True) self.btn_clear.setEnabled(True) self.target_color_label.setEnabled(True) self.picked_color.setStyleSheet('background-color : rgb({},{},{})'.format(R, G, B)) @property def img_idx(self): return self.__img_idx @img_idx.setter def img_idx(self, index): self.__img_idx = index self.image_index.setText(str(index)) def update_images(self) : '''Méthode à exécuter quand de nouvelles images sont apparues après une extraction d'images depuis une vidéo par exemple. Cette méthode : - met à jour des attributs qui dépendant de la liste des images, - met à jour l'état de certains boutons - fait afficher la première image et un message d'information.''' if self.images_dir is None : self.__img_idx = None #self.btn_prev.setEnabled(False) self.btn_prev.setStatusTip("") #self.btn_next.setEnabled(False) self.btn_next.setStatusTip("") self.images_step.setEnabled(False) self.images_firstRank.setEnabled(False) self.images_lastRank.setEnabled(False) else : self.buttonsState() self.mw.clearPlots() self.mw.twoPlots_VxVy.reset() # liste des noms des fichiers image pour avoir leur nombre : file_names = [ f for f in os.listdir(self.images_dir) \ if f.endswith('.png')] file_names.sort() self.nb_img = len(file_names) # Update spinBox: self.images_step.setEnabled(True) self.images_firstRank.setEnabled(True) self.images_lastRank.setEnabled(True) self.images_firstRank.setValue(1) self.images_step.setValue(1) self.images_lastRank.setValue(self.nb_img) self.images_firstRank.setMaximum(self.nb_img) self.images_lastRank.setMaximum(self.nb_img) self.images_step.setMaximum(self.nb_img) # MAJ des boutons prev et next self.img_idx = self.images_firstRank.value() self.btn_prev.setEnabled(True) self.btn_first.setEnabled(True) self.btn_prev.setStatusTip("charge l'image précédente") self.btn_next.setEnabled(True) self.btn_last.setEnabled(True) self.btn_next.setStatusTip("afficher "+self.mw.image_fmt.format(\ self.img_idx+self.images_step.value())) self.show_image() self.scaleInfoVisible(True) self.__epsilonVisible(True) self.mw.tabs.setCurrentWidget(self) self.scale_mm.clear() self.scale_mm.setText("???") self.scale_pixel.clear() try: text = str(self.video_size[1]) except: text = "" self.scale_pixel.setText(text) self.mw.twoPlots_VxVy.reset() if self.mw.flags["displayInfo"]: rep = QMessageBox.information( None, # widget parent de QMessageBox 'Information', # bandeau de la fenêtre 'Vous pouvez maintenant sélectionner une couleur de cible'+\ 'avec la souris...', QMessageBox.Ok) def show_image(self): '''Affiche l'image dont le numéro est donné par l'attribut 'img_idx'.''' if self.img_idx is None : self.img_path = '' else : self.img_path = self.images_dir+self.mw.image_fmt.format(self.img_idx) pixmap = QPixmap(self.img_path) self.img_lbl.setPixmap(pixmap) self.img_lbl.setStatusTip(os.path.basename(self.img_path)) def first_image(self) : if self.img_idx == None : return self.img_idx = self.images_firstRank.value() self.mw.statusBar().showMessage("") self.show_image() def prev_image(self) : if self.img_idx == None : return if self.img_idx >= self.images_firstRank.value() + self.images_step.value(): self.img_idx -= self.images_step.value() self.mw.statusBar().showMessage("") self.show_image() def last_image(self) : if self.img_idx == None : return self.img_idx = self.images_lastRank.value() # rank of last image to process self.mw.statusBar().showMessage("") self.show_image() def next_image(self) : if self.img_idx == None : return if self.img_idx <= self.images_lastRank.value()-self.images_step.value(): self.img_idx += self.images_step.value() self.mw.statusBar().showMessage("") self.show_image() def parse_meta_data(self): self.video_nframes = self.dico_video.get('nframes', None) self.video_size = self.dico_video.get('size', None) self.video_FPS = self.dico_video.get('fps', None) self.video_duration = self.dico_video.get('duration', None) self.video_name = self.dico_video.get('videoname',"none.mp4") if self.mw.flags["debug"]: info= " nb images : {},\n taille image : {},\n FPS : {} image/sec,\n durée : {.2f} sec." info = info.format(self.video_nframes, self.video_size, self.video_FPS, self.video_duration) QMessageBox.about(None, # widget parent de QMessageBox 'Informations video {}'.format(self.video_name), info) def eventFilter(self, object, event): if object == self.img_lbl : if event.type() == QEvent.MouseButtonPress: self.mousePressInLabel(event) return True elif event.type() == QEvent.MouseButtonRelease: self.mouseReleaseInLabel(event) return True elif event.type() == QEvent.MouseMove: self.mouseMoveInLabel(event) return True return False def mousePressInLabel(self, event): if event.button() == Qt.LeftButton: self.pt1 = event.pos() self.pt1_rect = self.img_lbl.mapTo(self, self.pt1) print("\nCoord. pt1 image :",self.pt1) self.rubberBand.setGeometry(QRect(self.pt1_rect, QSize())) self.rubberBand.show() self.mw.statusBar().showMessage('sélection en cours....') def mouseMoveInLabel(self, event): if not self.pt1.isNull(): pt = self.img_lbl.mapTo(self,event.pos()) self.rubberBand.setGeometry(QRect(self.pt1_rect, pt).normalized()) def mouseReleaseInLabel(self, event): if event.button() == Qt.LeftButton: self.pt2 = event.pos() print("Coord. pt2 image :", self.pt2) self.rubberBand.hide() self.selection = QRect(self.pt1, self.pt2).normalized() print(self.selection) self.computeTargetColor() def scale_XY(self): self.valid_scale = False self.pix_to_mm_coeff = 1. try : pixels = float(self.scale_pixel.text()) mm = float(self.scale_mm.text()) except : if self.mw.flags["displayInfo"]: info = 'Les données de conversion Pixels -> mm n\'ont pas été ' info += 'complétées.. les ordonnées des tracés seront en pixels.' rep = QMessageBox.information(None, # parent de QMessageBox 'Info', # bandeau de la fenêtre info, QMessageBox.Ok) return self.valid_scale = True self.pix_to_mm_coeff = mm/pixels print("valid scale : ", self.pix_to_mm_coeff)
class GameCreateWidget(QWidget): def __init__(self, main): super(GameCreateWidget, self).__init__() self.main_win = main self.setObjectName("GameCreateWidget") h_layout = QHBoxLayout() form_layout = QFormLayout() form_layout.setContentsMargins(20, 50, 20, 50) self.game_name_value = QLineEdit() form_layout.addRow("游戏名称:", self.game_name_value) self.game_desc_value = QTextEdit() form_layout.addRow("游戏简介:", self.game_desc_value) self.game_appid_value = QLineEdit() form_layout.addRow("游戏ID:", self.game_appid_value) self.game_appkey_value = QLineEdit() form_layout.addRow("客户端Key:", self.game_appkey_value) h_layout2 = QHBoxLayout() self.keystore_path = QLineEdit() select_key_btn = QPushButton("浏览") select_key_btn.setStyleSheet('QPushButton{border-radius: 0px;}') select_key_btn.clicked.connect(self.select_keystore) h_layout2.addWidget(self.keystore_path) h_layout2.addWidget(select_key_btn) form_layout.addRow("KeyStore:", h_layout2) self.keystore_pwd_value = QLineEdit() form_layout.addRow("KeyPass:"******"Alias:", self.keystore_alias_value) self.keystore_aliaspwd_value = QLineEdit() form_layout.addRow("AliasPass:"******"添加Icon") icon_add_btn.setFixedWidth(100) icon_add_btn.clicked.connect(self.add_icon) v_layout2.addWidget(icon_add_btn, alignment=Qt.AlignHCenter) v_layout2.addStretch(6) create_btn = QPushButton("创 建") create_btn.setFixedWidth(100) create_btn.clicked.connect(self.create) v_layout2.addWidget(create_btn, alignment=Qt.AlignRight | Qt.AlignBottom) v_layout2.addStretch(1) back_btn = QPushButton("返 回") back_btn.setFixedWidth(100) back_btn.clicked.connect(self.back) v_layout2.addWidget(back_btn, alignment=Qt.AlignRight | Qt.AlignBottom) h_layout.addLayout(v_layout2, 1) self.setLayout(h_layout) self.game = {} self.icon_path = None def select_keystore(self): fname = QFileDialog.getOpenFileName( self, '选择签名文件', os.path.join(os.path.expanduser('~'), "Desktop")) if fname[0]: self.keystore_path.setText(fname[0]) self.keystore_pwd_value.clear() self.keystore_alias_value.clear() self.keystore_aliaspwd_value.clear() def add_icon(self): fname = QFileDialog.getOpenFileName( self, '选择icon', os.path.join(os.path.expanduser('~'), "Desktop"), ("Images (*.png)")) if fname[0]: pix = QPixmap(fname[0]) if pix.width() != 512 or pix.height() != 512: QMessageBox.warning(self, "警告", "必须上传512*512.png图片") return self.icon_img.setPixmap(pix) self.icon_path = fname[0] def back(self): if len(self.main_win.games) > 0: self.main_win.set_game_list_widget(self.main_win.games) else: self.main_win.set_main_widget() def create(self): if self.game_name_value.text().strip() == "": QMessageBox.warning(self, "警告", "游戏名称不能为空!") return if self.game_appid_value.text().strip() == "": QMessageBox.warning(self, "警告", "游戏Id不能为空!") return if self.game_appkey_value.text().strip() == "": QMessageBox.warning(self, "警告", "客户端Key不能为空!") return if self.keystore_path.text().strip() == "": QMessageBox.warning(self, "警告", "必须上传keystore签名文件!") return if self.keystore_pwd_value.text().strip() == "": QMessageBox.warning(self, "警告", "keystore密码不能为空!") return if self.keystore_alias_value.text().strip() == "": QMessageBox.warning(self, "警告", "alias不能为空!") return if self.keystore_aliaspwd_value.text().strip() == "": QMessageBox.warning(self, "警告", "alias密码不能为空!") return self.game['name'] = self.game_name_value.text().strip() self.game['desc'] = self.game_desc_value.toPlainText().strip() self.game['id'] = self.game_appid_value.text().strip() self.game['key'] = self.game_appkey_value.text().strip() if os.path.exists(Utils.get_full_path('games/' + self.game['id'])): QMessageBox.warning(self, "警告", "游戏已存在!") return if not os.path.exists(Utils.get_full_path('games')): os.makedirs(Utils.get_full_path('games')) os.mkdir(Utils.get_full_path('games/' + self.game['id'])) keystore = os.path.basename(self.keystore_path.text().strip()) self.game['keystore'] = keystore self.game['keypwd'] = self.keystore_pwd_value.text().strip() self.game['alias'] = self.keystore_alias_value.text().strip() self.game['aliaspwd'] = self.keystore_aliaspwd_value.text().strip() os.mkdir(Utils.get_full_path('games/' + self.game['id'] + '/keystore')) keystore_path = Utils.get_full_path('games/' + self.game['id'] + '/keystore/' + keystore) Utils.copy_file(self.keystore_path.text().strip(), keystore_path) os.mkdir(Utils.get_full_path('games/' + self.game['id'] + '/icon')) if self.icon_path is not None: icon_file = Utils.get_full_path('games/' + self.game['id'] + '/icon/icon.png') Utils.copy_file(self.icon_path, icon_file) self.main_win.games.append(self.game) Utils.add_game(Utils.get_full_path('games/games.xml'), self.game) self.main_win.game_index = len(self.main_win.games) - 1 self.main_win.set_game_list_widget(self.main_win.games)
class LLT_ConjAdd(QMainWindow): def __init__(self): super(LLT_ConjAdd, self).__init__() self.w = QWidget() self.setCentralWidget(self.w) #construct GUI self.setWindowTitle("Verb Conjugations") self.setGeometry(0, 0, 900, 600) self.conjDicList = [] self.wordList = [] self.newDic = {'INF': '', 'IND': '', 'SUB': '', 'IMP': ''} self.headingLab = QLabel("Add New Conjugation Table") self.wordInfLab = QLabel("Infinitive") self.wordInfLab.setAlignment(Qt.AlignRight) self.infEntry = QLineEdit() #INDICATIVE FORM TABLE self.indLab = QLabel("Indicative") self.indYoLab = QLabel("Yo") self.indYoLab.setAlignment(Qt.AlignRight) self.indTuLab = QLabel("Tú") self.indTuLab.setAlignment(Qt.AlignRight) self.indUstLab = QLabel("Él/la, Ud") self.indUstLab.setAlignment(Qt.AlignRight) self.indNosLab = QLabel("Nosotros") self.indNosLab.setAlignment(Qt.AlignRight) self.indUstdsLab = QLabel("Ellos/as, Uds") self.indUstdsLab.setAlignment(Qt.AlignRight) self.indPresLab = QLabel("Present") self.indPretLab = QLabel("Preterite") self.indImpLab = QLabel("Imperfect") self.indFutLab = QLabel("Future") self.indCondLab = QLabel("Conditional") self.entryGridInd = QGridLayout() for i in range(5): for j in range(5): self.entry = QLineEdit() self.entryGridInd.addWidget(self.entry, i, j) #SUBJUNCTIVE FORM TABLE self.subLab = QLabel("Subjunctive") self.subYoLab = QLabel("Yo") self.subYoLab.setAlignment(Qt.AlignRight) self.subTuLab = QLabel("Tú") self.subTuLab.setAlignment(Qt.AlignRight) self.subUstLab = QLabel("Él/la, Ud") self.subUstLab.setAlignment(Qt.AlignRight) self.subNosLab = QLabel("Nosotros/as") self.subNosLab.setAlignment(Qt.AlignRight) self.subUstdsLab = QLabel("Ellos/as, Uds") self.subUstdsLab.setAlignment(Qt.AlignRight) self.subPresLab = QLabel("Present") self.subImpLab = QLabel("Imperfect") self.subFutLab = QLabel("Future") self.entryGridSub = QGridLayout() for i in range(5): for j in range(3): self.entry = QLineEdit() self.entryGridSub.addWidget(self.entry, i, j) #IMPERATIVE FORM TABLE self.impvLab = QLabel("Imperative") self.impvTu = QLabel("Tú") self.impvTu.setAlignment(Qt.AlignRight) self.impvUd = QLabel("Usted") self.impvUd.setAlignment(Qt.AlignRight) self.impvNos = QLabel("Nosotros/as") self.impvNos.setAlignment(Qt.AlignRight) self.impvUdes = QLabel("Ustedes") self.impvUdes.setAlignment(Qt.AlignRight) self.impvAffLab = QLabel("Affirmative") self.impvNegLab = QLabel("Negative") self.entryGridImpv = QGridLayout() for i in range(4): for j in range(2): self.entry = QLineEdit() self.entryGridImpv.addWidget(self.entry, i, j) self.checkBut = QPushButton("Check") self.checkBut.clicked.connect(self.check) self.saveBut = QPushButton("Save") self.saveBut.clicked.connect(self.save) self.newBut = QPushButton("New Word") self.newBut.clicked.connect(self.new) self.clearBut = QPushButton("Clear") self.clearBut.clicked.connect(self.clear) self.quitBut = QPushButton("Quit") self.quitBut.clicked.connect(self.quit) self.theGrid = QGridLayout() self.theGrid.addWidget(self.headingLab, 0, 0) self.theGrid.addWidget(self.wordInfLab, 1, 0) self.theGrid.addWidget(self.infEntry, 1, 1) self.theGrid.addWidget(self.indLab, 3, 0) self.theGrid.addWidget(self.indPresLab, 3, 1) self.theGrid.addWidget(self.indPretLab, 3, 2) self.theGrid.addWidget(self.indImpLab, 3, 3) self.theGrid.addWidget(self.indFutLab, 3, 4) self.theGrid.addWidget(self.indCondLab, 3, 5) self.theGrid.addWidget(self.indYoLab, 4, 0) self.theGrid.addWidget(self.indTuLab, 5, 0) self.theGrid.addWidget(self.indUstLab, 6, 0) self.theGrid.addWidget(self.indNosLab, 7, 0) self.theGrid.addWidget(self.indUstdsLab, 8, 0) self.theGrid.addLayout(self.entryGridInd, 4, 1, 5, 5) self.theGrid.addWidget(self.subLab, 11, 0) self.theGrid.addWidget(self.subPresLab, 11, 1) self.theGrid.addWidget(self.subImpLab, 11, 2) self.theGrid.addWidget(self.subFutLab, 11, 3) self.theGrid.addWidget(self.subYoLab, 12, 0) self.theGrid.addWidget(self.subTuLab, 13, 0) self.theGrid.addWidget(self.subUstLab, 14, 0) self.theGrid.addWidget(self.subNosLab, 15, 0) self.theGrid.addWidget(self.subUstdsLab, 16, 0) self.theGrid.addLayout(self.entryGridSub, 12, 1, 5, 3) self.theGrid.addWidget(self.impvLab, 19, 0) self.theGrid.addWidget(self.impvAffLab, 19, 1) self.theGrid.addWidget(self.impvNegLab, 19, 2) self.theGrid.addWidget(self.impvTu, 20, 0) self.theGrid.addWidget(self.impvUd, 21, 0) self.theGrid.addWidget(self.impvNos, 22, 0) self.theGrid.addWidget(self.impvUdes, 23, 0) self.theGrid.addLayout(self.entryGridImpv, 20, 1, 4, 2) self.theGrid.addWidget(self.checkBut, 19, 5) self.theGrid.addWidget(self.saveBut, 20, 5) self.theGrid.addWidget(self.clearBut, 21, 5) self.theGrid.addWidget(self.newBut, 22, 5) self.theGrid.addWidget(self.quitBut, 23, 5) for i in range(24): self.theGrid.setRowStretch(i, 1) for j in range(6): self.theGrid.setColumnStretch(j, 1) self.w.setLayout(self.theGrid) self.getDic() def check(self): word = self.infEntry.text().upper() if word in self.wordList: msgBox = QMessageBox() msgBox.setText(word + ' already in dictionary') msgBox.exec_() else: msgBox = QMessageBox() msgBox.setText(word + ' not in dictionary yet') msgBox.exec_() def save(self): infinitive = self.infEntry.text().upper() if infinitive in self.wordList: msgBox = QMessageBox() msgBox.setText(infinitive + ' already in dictionary') msgBox.exec_() else: self.wordList.append(infinitive) indList = [] subList = [] impList = [] for i in range(self.entryGridInd.count()): item = self.entryGridInd.itemAt(i) child = item.widget() indList.append(child.text().upper()) for i in range(self.entryGridSub.count()): item = self.entryGridSub.itemAt(i) child = item.widget() subList.append(child.text().upper()) for i in range(self.entryGridImpv.count()): item = self.entryGridImpv.itemAt(i) child = item.widget() impList.append(child.text().upper()) self.newDic['INF'] = infinitive self.newDic['IND'] = indList self.newDic['SUB'] = subList self.newDic['IMP'] = impList self.conjDicList.append(self.newDic) c = open('conj.txt', 'w') json.dump(self.conjDicList, c) c.close() msgBox = QMessageBox() msgBox.setText(infinitive + ' has been saved') msgBox.exec_() self.newDic = {'INF': '', 'IND': '', 'SUB': '', 'IMP': ''} def new(self): confirm = QMessageBox.question( self.w, 'New Word', 'Are you sure you want to clear all entries \nand start a new word?', QMessageBox.Yes | QMessageBox.No) if confirm == QMessageBox.Yes: self.infEntry.clear() for i in range(self.entryGridInd.count()): item = self.entryGridInd.itemAt(i) child = item.widget() child.clear() for i in range(self.entryGridSub.count()): item = self.entryGridSub.itemAt(i) child = item.widget() child.clear() for i in range(self.entryGridImpv.count()): item = self.entryGridImpv.itemAt(i) child = item.widget() child.clear() else: pass def clear(self): confirm = QMessageBox.question( self.w, 'Clear', 'Are you sure you want to clear all entries?', QMessageBox.Yes | QMessageBox.No) if confirm == QMessageBox.Yes: self.infEntry.clear() for i in range(self.entryGridInd.count()): item = self.entryGridInd.itemAt(i) child = item.widget() child.clear() for i in range(self.entryGridSub.count()): item = self.entryGridSub.itemAt(i) child = item.widget() child.clear() for i in range(self.entryGridImpv.count()): item = self.entryGridImpv.itemAt(i) child = item.widget() child.clear() else: pass def quit(self): confirm = QMessageBox.question(self.w, 'Quit', 'Are you sure you want to exit?', QMessageBox.Yes | QMessageBox.No) if confirm == QMessageBox.Yes: self.close() else: pass def getDic(self): try: c = open('conj.txt', 'r') self.conjDicList = json.load(c) c.close() for item in self.conjDicList: self.wordList.append(item['INF']) except: self.conjDicList = []
class LLT_EditWord(QMainWindow): def __init__(self): super(LLT_EditWord, self).__init__() self.w = QWidget() self.setCentralWidget(self.w) self.verbDic = [] self.nounDic = [] self.adjDic = [] self.phraseDic = [] self.wordList = [] self.verbList = [] self.nounList = [] self.adjList = [] self.phraseList = [] self.index = int(0) self.w.setWindowTitle("Edit Word") self.w.setGeometry(0,0,500, 500) self.vRad = QRadioButton("Verb") self.vRad.setChecked(True) self.nRad = QRadioButton("Noun") self.aRad = QRadioButton("Adjective") self.pRad = QRadioButton("Phrase") self.okBut = QPushButton("OK") self.okBut.clicked.connect(self.OK) self.lookLab = QLabel("Lookup: ") self.lookEntry = QLineEdit() self.lookEntry.setEnabled(False) self.lookBut = QPushButton("Search") self.lookBut.clicked.connect(self.search) self.lookBut.setEnabled(False) self.entryLab = QLabel("Word: ") self.wordEntry = QLineEdit() self.wordEntry.setEnabled(False) self.tranLab = QLabel("Translation: ") self.tranEntry = QLineEdit() self.tranEntry.setEnabled(False) self.saveBut = QPushButton("Save") self.saveBut.clicked.connect(self.save) self.clearBut = QPushButton("Reset") self.clearBut.clicked.connect(self.reset) self.newBut = QPushButton("New word") self.newBut.clicked.connect(self.new) self.exitBut = QPushButton("Exit") self.exitBut.clicked.connect(self.exit) grid = QGridLayout() grid.addWidget(self.vRad, 0, 0) grid.addWidget(self.nRad, 0, 1) grid.addWidget(self.aRad, 0, 2) grid.addWidget(self.pRad, 0, 3) grid.addWidget(self.okBut, 0, 4) grid.addWidget(self.lookLab, 1, 0) grid.addWidget(self.lookEntry, 1, 1, 1, 2) grid.addWidget(self.lookBut, 1, 4) grid.addWidget(self.entryLab, 2, 0) grid.addWidget(self.wordEntry, 2, 1, 1, 3) grid.addWidget(self.tranLab, 3, 0) grid.addWidget(self.tranEntry, 3, 1, 1, 3) grid.addWidget(self.saveBut, 4, 0) grid.addWidget(self.clearBut, 4, 1) grid.addWidget(self.newBut, 4, 2) grid.addWidget(self.exitBut, 4, 3) self.getDics() self.setLists() self.w.setLayout(grid) self.w.show() def search(self): searchWord = self.lookEntry.text().upper() currentDic = [] currentList = [] if self.vRad.isChecked(): currentDic = self.verbDic currentList = self.verbList elif self.nRad.isChecked(): currentDic = self.nounDic currentList = self.nounList elif self.aRad.isChecked(): currentDic = self.adjDic currentList = self.adjList elif self.pRad.isChecked(): currentDic = self.phraseDic currentList = self.phraseList else: msgBox = QMessageBox() msgBox.setText("You must select a dictionary before continuing.") msgBox.exec_() self.vRad.setEnabled(True) self.nRad.setEnabled(True) self.aRad.setEnabled(True) self.pRad.setEnabled(True) self.lookEntry.setEnabled(False) self.lookBut.setEnabled(False) self.wordEntry.setEnabled(False) self.tranEntry.setEnabled(False) if searchWord in self.wordList: self.lookEntry.setEnabled(False) self.lookBut.setEnabled(False) self.wordEntry.setEnabled(True) self.tranEntry.setEnabled(True) self.index = currentList.index(searchWord) oldWord = currentDic[self.index] self.wordEntry.setPlaceholderText(oldWord[0]) self.tranEntry.setPlaceholderText(oldWord[1]) else: msgBox = QMessageBox() msgBox.setText("Word not currently saved in dictionary.") msgBox.exec_(); def OK(self): self.vRad.setEnabled(False) self.nRad.setEnabled(False) self.aRad.setEnabled(False) self.pRad.setEnabled(False) self.lookEntry.setEnabled(True) self.lookBut.setEnabled(True) def save(self): spanWord = self.wordEntry.text().upper() tranWord = self.tranEntry.text().upper() if spanWord in self.wordList: msgBox = QMessageBox() msgBox.setText(spanWord + ' already in dictionary') msgBox.exec_(); else: self.wordList.append(spanWord) newWord = [spanWord,tranWord] self.wordEntry.setEnabled(False) self.tranEntry.setEnabled(False) if self.vRad.isChecked(): self.verbDic[self.index]= newWord v = open('verb.txt','w') json.dump(self.verbDic, v) v.close() elif self.nRad.isChecked(): self.nounDic[self.index]= newWord n = open('noun.txt','w') json.dump(self.nounDic, n) n.close() elif self.aRad.isChecked(): self.adjDic[self.index]= newWord a = open('adj.txt','w') json.dump(self.adjDic, a) a.close() elif self.pRad.isChecked(): self.phraseDic[self.index]= newWord p = open('phrase.txt','w') json.dump(self.phraseDic, p) p.close() else: msgBox = QMessageBox() msgBox.setText("You must select a dictionary before saving word.") msgBox.exec_(); def reset(self): self.vRad.setEnabled(True) self.nRad.setEnabled(True) self.aRad.setEnabled(True) self.pRad.setEnabled(True) self.lookEntry.setEnabled(False) self.lookBut.setEnabled(False) self.wordEntry.setEnabled(False) self.tranEntry.setEnabled(False) self.wordEntry.clear() self.tranEntry.clear() self.lookEntry.setPlaceholderText('') self.wordEntry.setPlaceholderText('') self.tranEntry.setPlaceholderText('') def new(self): self.vRad.setEnabled(True) self.nRad.setEnabled(True) self.aRad.setEnabled(True) self.pRad.setEnabled(True) self.wordEntry.setEnabled(False) self.tranEntry.setEnabled(False) self.wordEntry.clear() self.tranEntry.clear() self.lookEntry.setPlaceholderText('') self.wordEntry.setPlaceholderText('') self.tranEntry.setPlaceholderText('') def exit(self): confirm = QMessageBox.question(self.w, 'Quit', 'Are you sure you want to exit?', QMessageBox.Yes | QMessageBox.No) if confirm == QMessageBox.Yes: self.close() else: pass def getDics(self): try: v=open('verb.txt','r') self.verbDic=json.load(v) v.close() except: self.verbDic = [] try: n=open('noun.txt','r') self.nounDic=json.load(n) n.close() except: self.nounDic = [] try: p=open('phrase.txt','r') self.phraseDic=json.load(p) p.close() except: self.phraseDic = [] try: a=open('adj.txt','r') self.adjDic=json.load(a) a.close() except: self.phraseDic = [] def setLists(self): for item in self.verbDic: self.wordList.append(item[0]) self.verbList.append(item[0]) for item in self.nounDic: self.wordList.append(item[0]) self.nounList.append(item[0]) for item in self.adjDic: self.wordList.append(item[0]) self.adjList.append(item[0]) for item in self.phraseDic: self.wordList.append(item[0]) self.phraseList.append(item[0])