class Example(QWidget): def __init__(self): super().__init__() self.menu = ["Чизбургер", "Гамбургер", "Кока-кола", "Нагетсы"] self.initUI() def initUI(self): self.setGeometry(400, 300, 300, 400) self.setWindowTitle('Заказ в Макдональдсе') self.check_b = [QCheckBox(self) for i in self.menu] self.btn = QPushButton('Заказать', self) self.btn.clicked.connect(self.run) self.btn.move(10, 20 * (len(self.check_b) + 1)) for i in range(len(self.check_b)): self.check_b[i].setText(self.menu[i]) self.check_b[i].move(10, 20 * i) self.result = QPlainTextEdit(self) self.result.setEnabled(False) self.result.move(10, 20 * (len(self.check_b) + 3)) def run(self): self.result.clear() result = [i.text() for i in self.check_b if i.isChecked()] result.insert(0, "Ваш заказ\n") self.result.appendPlainText("\n".join(result))
class Example(QWidget): def __init__(self): super().__init__() self.menu = ["Бургер", "Молочный коктель", "Картофель фри", "Нагецы", "Кока-кола", "Бигмак", "Чизбургер"] self.initUI() def initUI(self): self.setGeometry(400, 300, 300, 400) self.setWindowTitle('15_3') self.check_b = [QCheckBox(self) for i in self.menu] self.btn = QPushButton('Заказать', self) self.btn.clicked.connect(self.run) self.btn.move(10, 20 * (len(self.check_b) + 1)) for i in range(len(self.check_b)): self.check_b[i].setText(self.menu[i]) self.check_b[i].move(10,20*i) self.result = QPlainTextEdit(self) self.result.setEnabled(True) self.result.move(10,20*(len(self.check_b)+3)) def run(self): self.result.clear() result = [i.text() for i in self.check_b if i.isChecked()] self.result.appendPlainText("\n".join(result))
class BoxInfoCustom(QGroupBox): """ Clase con caja de información personalizada. """ def __init__(self, title): QGroupBox.__init__(self, title) self.vbox = QVBoxLayout() self.textInfo = QPlainTextEdit() self.textInfo.setReadOnly(True) self.info = "" self.basic_styles = "font-size: 14px; color: black; font-weight: normal; font-family: Helvetica, Arial, sans-serif;" self.setInfo() self.setLayout(self.vbox) self.vbox.addWidget(self.textInfo) def updateBox(self, info=None, styles=None): self.info = "" if info is None else info self.basic_styles = self.basic_styles if styles is None else styles self.setInfo() def cleanBox(self): self.textInfo.clear() def setInfo(self): self.cleanBox() self.textInfo.insertPlainText(self.info) self.textInfo.setStyleSheet(self.basic_styles)
class BarraHerramientasVentana(QMainWindow): def __init__(self): super().__init__() self.inicializarGui() def inicializarGui(self): self.setWindowTitle('Editor Básico de Texto') self.setFixedSize(400, 300) barra_herramientas = self.addToolBar('Archivo') mni_nuevo_archivo = QAction(QIcon('parte17/new.png'), 'Nuevo', self) mni_nuevo_archivo.triggered.connect(self.crear_archivo) barra_herramientas.addAction(mni_nuevo_archivo) mni_abrir_archivo = QAction(QIcon('parte17/open.png'), 'Abrir', self) mni_abrir_archivo.triggered.connect(self.abrir_archivo) barra_herramientas.addAction(mni_abrir_archivo) mni_guardar_archivo = QAction(QIcon('parte17/save.png'), 'Guardar', self) mni_guardar_archivo.triggered.connect(self.guardar_archivo) barra_herramientas.addAction(mni_guardar_archivo) self.contenido = QPlainTextEdit(self) self.contenido.move(10, 50) self.contenido.setFixedWidth(380) self.contenido.setFixedHeight(240) def crear_archivo(self): self.contenido.clear() def abrir_archivo(self): archivo, ok = QFileDialog.getOpenFileName( self, 'Seleccionar archivo de texto...', 'C:\\', 'Archivo de texto (*.txt)') if ok: with open(archivo, 'r') as f: self.contenido.insertPlainText(''.join(f.readlines())) def guardar_archivo(self): archivo, ok = QFileDialog.getSaveFileName( self, 'Guardar archivo de texto...', 'C:\\', 'Archivo de texto (*.txt)') if ok: with open(archivo, 'w') as f: f.write(self.contenido.toPlainText())
class Example(QWidget): lst = [] def __init__(self): super().__init__() self.initUI() def initUI(self): self.setGeometry(480, 370, 480, 370) self.setWindowTitle('Заказ в Макдональдсе') self.te = QPlainTextEdit(self) self.te.move(200, 20) self.te.resize(250, 350) self.btn = QPushButton('Создать новый', self) self.btn.resize(160, 20) self.btn.move(20, 60) self.btn.clicked.connect(self.create_file) self.btn1 = QPushButton('Сохранить файл', self) self.btn1.resize(160, 20) self.btn1.move(20, 100) self.btn1.clicked.connect(self.end_work) self.btn2 = QPushButton('Открыть файл', self) self.btn2.resize(160, 20) self.btn2.move(20, 140) self.btn2.clicked.connect(self.open_file) self.le = QLineEdit(self) self.le.resize(160, 20) self.le.move(20, 20) def create_file(self): self.f = open(self.le.text(), 'w') def open_file(self): with open(self.le.text(), 'r') as f: text = f.read() self.te.appendPlainText(text) self.f = open(self.le.text(), 'w') def end_work(self): self.f.write(self.te.toPlainText()) self.f.close() self.te.clear()
class TextSubTab(QWidget): def __init__(self, sending=True): super(QWidget, self).__init__() layout = QHBoxLayout() self.text_message = QPlainTextEdit() self.text_message.setDisabled(not sending) layout.addWidget(self.text_message) self.setLayout(layout) def append_text_message(self, message): self.text_message.appendPlainText(message) def clear_text_message(self): self.text_message.clear()
class TopViewWindow(QWidget): closed = pyqtSignal() def __init__(self, parent=None): super(TopViewWindow, self).__init__(parent) self.initUI() def initUI(self): layout = QVBoxLayout() self.setWindowTitle( QtWidgets.QApplication.instance().applicationName() + ' - Top') self.text_box = QPlainTextEdit() self.text_box.setReadOnly(True) layout.addWidget(self.text_box) self.setLayout(layout) center_point = QDesktopWidget().availableGeometry().center() window_size = (800, 600) self.setGeometry(center_point.x() - window_size[0] // 2, center_point.y() - window_size[1] // 2, window_size[0], window_size[1]) self.show() self.action_timer = QTimer(self) self.action_timer.setSingleShot(False) self.action_timer.setInterval(1000) self.action_timer.timeout.connect(self.update_data) self.action_timer.start(1000) def update_data(self): try: output = subprocess.run(["top", "-b", "-n1"], capture_output=True) self.text_box.clear() self.text_box.setPlainText(output.stdout) except (ValueError, OSError, subprocess.SubprocessError) as e: self.action_timer.stop() QMessageBox.critical(self, "Error!", f"Program execution error: {str(e)}", QMessageBox.Ok) def closeEvent(self, event): self.closed.emit() event.accept()
class QPlainTextEditLogger(logging.Handler): def __init__(self, parent): super().__init__() self.messages = '' self.widget = QPlainTextEdit(parent) self.widget.setReadOnly(True) def emit(self, record): msg = self.format(record) self.messages += msg self.widget.appendPlainText(msg) def getTexttoFile(self): return self.widget.toPlainText() def deleteTextinGUI(self): self.widget.clear()
class factorial_GUI(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowTitle('Factorial') self.resize(500, 300) self.center() inputLabel = QLabel('Enter an integer') self.inputEdit = QLineEdit() clearButton = QPushButton('Clear') self.result = QPlainTextEdit('0') self.result.setReadOnly(True) grid = QGridLayout() grid.addWidget(inputLabel, 1, 0) grid.addWidget(self.inputEdit, 1, 1) grid.addWidget(clearButton, 2, 0) grid.addWidget(self.result, 2, 1) self.setLayout(grid) self.inputEdit.returnPressed.connect(self.onChanged) clearButton.clicked.connect(self.clear) self.show() def onChanged(self): val = self.inputEdit.text() try: r = factorial(int(val)) r = format(r, ',') self.result.setPlainText(r) except: msg = '"%s" is not an integer' % (val) self.result.setPlainText(msg) def clear(self): self.inputEdit.clear() self.result.clear() def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft())
class Focus(QWidget): def __init__(self): super().__init__() self.setGeometry(600, 400, 285, 310) self.setWindowTitle('Заказ в Макдональдсе') menu = ['Чизбургер', 'Кока-кола', 'Гамбургер', 'Нагетсы'] r = [] x = 10 y = 10 self.kt = [] for i in range(4): r.append(i) r[i] = QCheckBox(menu[i], self) r[i].move(x, y) y += 17 r[i].stateChanged.connect(self.conv) y += 10 self.btn = QPushButton('Заказать', self) self.btn.move(x, y) self.btn.resize(90, 45) y += 60 self.btn.clicked.connect(self.conv2) self.txt = QPlainTextEdit(self) self.txt.setGeometry(x, y, 100, 150) self.txt.setReadOnly(True) def conv(self, state): if state: self.kt.append(self.sender().text()) else: self.kt.remove(self.sender().text()) def conv2(self): self.txt.clear() if len(self.kt) > 0: self.txt.appendPlainText('Ваш заказ:') self.txt.appendPlainText('') for i in range(len(self.kt)): self.txt.appendPlainText(self.kt[i]) else: self.txt.appendPlainText('Вы ничего не заказали :(')
class QtLogging(logging.Handler): def __init__(self,parent, logger): super().__init__() self.widget = QDockWidget("Show log", parent) self._log_widget = QPlainTextEdit(self.widget) self._log_widget.setReadOnly(True) self.widget.setWidget(self._log_widget) self.records = [] self.limit = 1000 logger.addHandler(self) def emit(self, record): msg = self.format(record) if len(self.records) > self.limit: self.records = self.records[int(self.limit / 2):] self._log_widget.clear() self._log_widget.appendPlainText("\n".join(self.records)) self.records.append(msg) self._log_widget.appendPlainText(msg)
class InputTab(SerafinInputTab): def __init__(self, parent): super().__init__(parent) canvas = LineMapCanvas() self.map = MapViewer(canvas) self.has_map = False self.data = None self.mesh = None self.lines = [] self.line_interpolators = [] self.line_interpolators_internal = [] # without intersection points self._initWidgets() # some instance attributes will be set there self._setLayout() self._bindEvents() def _initWidgets(self): # create the button open lines self.btnOpenLines = QPushButton('Load\nLines', self, icon=self.style().standardIcon( QStyle.SP_DialogOpenButton)) self.btnOpenLines.setToolTip('<b>Open</b> a .i2s or .shp file') self.btnOpenLines.setFixedSize(105, 50) self.btnOpenLines.setEnabled(False) # create some text fields displaying the IO files info self.linesNameBox = QPlainTextEdit() self.linesNameBox.setReadOnly(True) self.linesNameBox.setFixedHeight(50) # create the map button self.btnMap = QPushButton('Locate lines\non map', self, icon=self.style().standardIcon( QStyle.SP_DialogHelpButton)) self.btnMap.setFixedSize(135, 50) self.btnMap.setEnabled(False) def _bindEvents(self): self.btnOpen.clicked.connect(self.btnOpenSerafinEvent) self.btnOpenLines.clicked.connect(self.btnOpenLinesEvent) self.btnMap.clicked.connect(self.btnMapEvent) def _setLayout(self): mainLayout = QVBoxLayout() mainLayout.addItem(QSpacerItem(10, 10)) mainLayout.setSpacing(15) hlayout = QHBoxLayout() hlayout.addItem(QSpacerItem(30, 1)) hlayout.setAlignment(Qt.AlignLeft) hlayout.addWidget(self.btnOpen) hlayout.addItem(QSpacerItem(30, 1)) hlayout.addWidget(self.langBox) hlayout.addItem(QSpacerItem(30, 1)) hlayout.addWidget(self.btnOpenLines) hlayout.addWidget(self.btnMap) mainLayout.addLayout(hlayout) mainLayout.addItem(QSpacerItem(10, 10)) glayout = QGridLayout() glayout.addWidget(QLabel(' Input file'), 1, 1) glayout.addWidget(self.inNameBox, 1, 2) glayout.addWidget(QLabel(' Summary'), 2, 1) glayout.addWidget(self.summaryTextBox, 2, 2) glayout.addWidget(QLabel(' Lines file'), 3, 1) glayout.addWidget(self.linesNameBox, 3, 2) glayout.setAlignment(Qt.AlignLeft) glayout.setSpacing(10) mainLayout.addLayout(glayout) mainLayout.addItem(QSpacerItem(10, 10)) mainLayout.addWidget(QLabel(' Message logs')) mainLayout.addWidget(self.logTextBox.widget) self.setLayout(mainLayout) def _reinitInput(self): self.reset() self.data = None self.has_map = False self.btnMap.setEnabled(False) self.mesh = None self.btnOpenLines.setEnabled(False) self.parent.reset() def _resetDefaultOptions(self): nb_nonempty = 0 self.line_interpolators = [] self.line_interpolators_internal = [] for line in self.lines: line_interpolators, distances, \ line_interpolators_internal, distances_internal = self.mesh.get_line_interpolators(line) if line_interpolators: nb_nonempty += 1 self.line_interpolators.append((line_interpolators, distances)) self.line_interpolators_internal.append( (line_interpolators_internal, distances_internal)) if nb_nonempty == 0: self.lines = [] self.line_interpolators = [] self.line_interpolators_internal = [] self.linesNameBox.clear() self.parent.reset() else: old_filename = self.linesNameBox.toPlainText().split('\n')[0] self.linesNameBox.clear() self.linesNameBox.appendPlainText( old_filename + '\n' + 'The file contains {} open polyline{}.' '{} line{} the mesh continuously.'.format( len(self.lines), 's' if len(self.lines) > 1 else '', nb_nonempty, 's intersect' if nb_nonempty > 1 else ' intersects')) self.has_map = False self.btnMap.setEnabled(True) self.parent.getInput() def btnOpenSerafinEvent(self): canceled, filename = super().open_event() if canceled: return self._reinitInput() success, data = self.read_2d(filename) if not success: return # record the mesh for future visualization and calculations self.parent.inDialog() meshLoader = LoadMeshDialog('interpolation', data.header) self.mesh = meshLoader.run() self.parent.outDialog() if meshLoader.thread.canceled: self.linesNameBox.clear() self.parent.reset() return self.data = data self.btnOpenLines.setEnabled(True) self._resetDefaultOptions() def btnOpenLinesEvent(self): success, filename, polylines = open_polylines() if not success: return self.lines = polylines logging.info('Finished reading the lines file %s' % filename) nb_nonempty, indices_nonempty, \ self.line_interpolators, self.line_interpolators_internal = self.mesh.get_line_interpolators(self.lines) if nb_nonempty == 0: QMessageBox.critical(self, 'Error', 'No line intersects the mesh continuously.', QMessageBox.Ok) return logging.info('Finished reading the lines file %s' % filename) self.linesNameBox.clear() self.linesNameBox.appendPlainText( filename + '\n' + 'The file contains {} open polyline{}.' '{} line{} the mesh continuously.'.format( len(self.lines), 's' if len(self.lines) > 1 else '', nb_nonempty, 's intersect' if nb_nonempty > 1 else ' intersects')) self.has_map = False self.btnMap.setEnabled(True) self.parent.getInput() def btnMapEvent(self): if not self.has_map: self.map.canvas.reinitFigure( self.mesh, self.lines, [poly.id for poly in self.lines], list( islice( cycle(['b', 'r', 'g', 'y', 'k', 'c', '#F28AD6', 'm']), len(self.lines)))) self.has_map = True self.map.canvas.draw() self.has_map = True self.map.show()
class CLIWidget(QWidget): def __init__(self, parent, cli_iface): super(CLIWidget, self).__init__(parent) self._cli_iface = cli_iface self._command_line = CommitableComboBoxWithHistory(self) self._command_line.setToolTip('Enter the command here') self._command_line.setSizeAdjustPolicy(QComboBox.AdjustToContents) self._command_line.setFont(get_monospace_font()) self._command_line.on_commit = self._do_execute self._command_line_completer = QCompleter() self._command_line_completer.setCaseSensitivity(Qt.CaseSensitive) self._command_line_completer.setModel(self._command_line.model()) self._command_line.setCompleter(self._command_line_completer) self._execute_button = make_icon_button('flash', 'Execute command', self, on_clicked=self._do_execute) self._response_box = QPlainTextEdit(self) self._response_box.setToolTip('Command output will be printed here') self._response_box.setReadOnly(True) self._response_box.setLineWrapMode(QPlainTextEdit.NoWrap) self._response_box.setFont(get_monospace_font()) self._response_box.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) try: self._log_viewer.setPlaceholderText('Command output will be printed here') except AttributeError: # Old PyQt pass layout = QVBoxLayout(self) controls_layout = QHBoxLayout(self) controls_layout.addWidget(self._command_line, 1) controls_layout.addWidget(self._execute_button) layout.addLayout(controls_layout) layout.addWidget(self._response_box, 1) self.setLayout(layout) def _do_execute(self): self._response_box.clear() command = self._command_line.currentText() if not command.strip(): return self._command_line.add_current_text_to_history() def callback(lines): self.setEnabled(True) if lines is None: self.window().show_message('Command response timed out') self._response_box.setPlainText('<RESPONSE TIMED OUT>') else: self.window().show_message('Command response received') self._response_box.setPlainText(lines) self.setEnabled(False) self._cli_iface.execute_raw_command(command, callback)
class comic_meta_data_editor(QDialog): configGroup = "ComicsProjectManagementTools" # Translatable genre dictionary that has it's translated entries added to the genrelist and from which the untranslated items are taken. acbfGenreList = {"science_fiction": str(i18n("Science Fiction")), "fantasy": str(i18n("Fantasy")), "adventure": str(i18n("Adventure")), "horror": str(i18n("Horror")), "mystery": str(i18n("Mystery")), "crime": str(i18n("Crime")), "military": str(i18n("Military")), "real_life": str(i18n("Real Life")), "superhero": str(i18n("Superhero")), "humor": str(i18n("Humor")), "western": str(i18n("Western")), "manga": str(i18n("Manga")), "politics": str(i18n("Politics")), "caricature": str(i18n("Caricature")), "sports": str(i18n("Sports")), "history": str(i18n("History")), "biography": str(i18n("Biography")), "education": str(i18n("Education")), "computer": str(i18n("Computer")), "religion": str(i18n("Religion")), "romance": str(i18n("Romance")), "children": str(i18n("Children")), "non-fiction": str(i18n("Non Fiction")), "adult": str(i18n("Adult")), "alternative": str(i18n("Alternative")), "artbook": str(i18n("Artbook")), "other": str(i18n("Other"))} acbfAuthorRolesList = {"Writer": str(i18n("Writer")), "Adapter": str(i18n("Adapter")), "Artist": str(i18n("Artist")), "Penciller": str(i18n("Penciller")), "Inker": str(i18n("Inker")), "Colorist": str(i18n("Colorist")), "Letterer": str(i18n("Letterer")), "Cover Artist": str(i18n("Cover Artist")), "Photographer": str(i18n("Photographer")), "Editor": str(i18n("Editor")), "Assistant Editor": str(i18n("Assistant Editor")), "Designer": str(i18n("Designer")), "Translator": str(i18n("Translator")), "Other": str(i18n("Other"))} def __init__(self): super().__init__() # Get the keys for the autocompletion. self.genreKeysList = [] self.characterKeysList = [] self.ratingKeysList = {} self.formatKeysList = [] self.otherKeysList = [] self.authorRoleList = [] for g in self.acbfGenreList.values(): self.genreKeysList.append(g) for r in self.acbfAuthorRolesList.values(): self.authorRoleList.append(r) mainP = Path(os.path.abspath(__file__)).parent self.get_auto_completion_keys(mainP) extraKeyP = Path(QDir.homePath()) / Application.readSetting(self.configGroup, "extraKeysLocation", str()) self.get_auto_completion_keys(extraKeyP) # Setup the dialog. self.setLayout(QVBoxLayout()) mainWidget = QTabWidget() self.layout().addWidget(mainWidget) self.setWindowTitle(i18n("Comic Metadata")) buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.layout().addWidget(buttons) buttons.accepted.connect(self.accept) buttons.rejected.connect(self.reject) # Title, concept, summary, genre, characters, format, rating, language, series, other keywords metadataPage = QWidget() mformLayout = QFormLayout() metadataPage.setLayout(mformLayout) self.lnTitle = QLineEdit() self.lnTitle.setToolTip(i18n("The proper title of the comic.")) self.teSummary = QPlainTextEdit() self.teSummary.setToolTip(i18n("What will you tell others to entice them to read your comic?")) self.lnGenre = QLineEdit() genreCompletion = multi_entry_completer() genreCompletion.setModel(QStringListModel(self.genreKeysList)) self.lnGenre.setCompleter(genreCompletion) genreCompletion.setCaseSensitivity(False) self.lnGenre.setToolTip(i18n("The genre of the work. Prefilled values are from the ACBF, but you can fill in your own. Separate genres with commas. Try to limit the amount to about two or three.")) self.lnCharacters = QLineEdit() characterCompletion = multi_entry_completer() characterCompletion.setModel(QStringListModel(self.characterKeysList)) characterCompletion.setCaseSensitivity(False) characterCompletion.setFilterMode(Qt.MatchContains) # So that if there is a list of names with last names, people can type in a last name. self.lnCharacters.setCompleter(characterCompletion) self.lnCharacters.setToolTip(i18n("The names of the characters that this comic revolves around. Comma-separated.")) self.lnFormat = QLineEdit() formatCompletion = multi_entry_completer() formatCompletion.setModel(QStringListModel(self.formatKeysList)) formatCompletion.setCaseSensitivity(False) self.lnFormat.setCompleter(formatCompletion) ratingLayout = QHBoxLayout() self.cmbRatingSystem = QComboBox() self.cmbRatingSystem.addItems(self.ratingKeysList.keys()) self.cmbRatingSystem.setEditable(True) self.cmbRating = QComboBox() self.cmbRating.setEditable(True) self.cmbRatingSystem.currentIndexChanged.connect(self.slot_refill_ratings) ratingLayout.addWidget(self.cmbRatingSystem) ratingLayout.addWidget(self.cmbRating) self.lnSeriesName = QLineEdit() self.lnSeriesName.setToolTip(i18n("If this is part of a series, enter the name of the series and the number.")) self.spnSeriesNumber = QSpinBox() self.spnSeriesNumber.setPrefix(i18n("No. ")) self.spnSeriesVol = QSpinBox() self.spnSeriesVol.setPrefix(i18n("Vol. ")) seriesLayout = QHBoxLayout() seriesLayout.addWidget(self.lnSeriesName) seriesLayout.addWidget(self.spnSeriesVol) seriesLayout.addWidget(self.spnSeriesNumber) otherCompletion = multi_entry_completer() otherCompletion.setModel(QStringListModel(self.otherKeysList)) otherCompletion.setCaseSensitivity(False) otherCompletion.setFilterMode(Qt.MatchContains) self.lnOtherKeywords = QLineEdit() self.lnOtherKeywords.setCompleter(otherCompletion) self.lnOtherKeywords.setToolTip(i18n("Other keywords that do not fit in the previously mentioned sets. As always, comma-separated.")) self.cmbLanguage = language_combo_box() self.cmbCountry = country_combo_box() self.cmbLanguage.currentIndexChanged.connect(self.slot_update_countries) self.cmbReadingMode = QComboBox() self.cmbReadingMode.addItem(i18n("Left to Right")) self.cmbReadingMode.addItem(i18n("Right to Left")) self.cmbCoverPage = QComboBox() self.cmbCoverPage.setToolTip(i18n("Which page is the cover page? This will be empty if there are no pages.")) mformLayout.addRow(i18n("Title:"), self.lnTitle) mformLayout.addRow(i18n("Cover page:"), self.cmbCoverPage) mformLayout.addRow(i18n("Summary:"), self.teSummary) mformLayout.addRow(i18n("Language:"), self.cmbLanguage) mformLayout.addRow("", self.cmbCountry) mformLayout.addRow(i18n("Reading direction:"), self.cmbReadingMode) mformLayout.addRow(i18n("Genre:"), self.lnGenre) mformLayout.addRow(i18n("Characters:"), self.lnCharacters) mformLayout.addRow(i18n("Format:"), self.lnFormat) mformLayout.addRow(i18n("Rating:"), ratingLayout) mformLayout.addRow(i18n("Series:"), seriesLayout) mformLayout.addRow(i18n("Other:"), self.lnOtherKeywords) mainWidget.addTab(metadataPage, i18n("Work")) # The page for the authors. authorPage = QWidget() authorPage.setLayout(QVBoxLayout()) explanation = QLabel(i18n("The following is a table of the authors that contributed to this comic. You can set their nickname, proper names (first, middle, last), role (penciller, inker, etc), email and homepage.")) explanation.setWordWrap(True) self.authorModel = QStandardItemModel(0, 8) labels = [i18n("Nick Name"), i18n("Given Name"), i18n("Middle Name"), i18n("Family Name"), i18n("Role"), i18n("Email"), i18n("Homepage"), i18n("Language")] self.authorModel.setHorizontalHeaderLabels(labels) self.authorTable = QTableView() self.authorTable.setModel(self.authorModel) self.authorTable.verticalHeader().setDragEnabled(True) self.authorTable.verticalHeader().setDropIndicatorShown(True) self.authorTable.verticalHeader().setSectionsMovable(True) self.authorTable.verticalHeader().sectionMoved.connect(self.slot_reset_author_row_visual) delegate = author_delegate() delegate.setCompleterData(self.authorRoleList, 4) delegate.setLanguageData(len(labels) - 1) self.authorTable.setItemDelegate(delegate) author_button_layout = QWidget() author_button_layout.setLayout(QHBoxLayout()) btn_add_author = QPushButton(i18n("Add Author")) btn_add_author.clicked.connect(self.slot_add_author) btn_remove_author = QPushButton(i18n("Remove Author")) btn_remove_author.clicked.connect(self.slot_remove_author) author_button_layout.layout().addWidget(btn_add_author) author_button_layout.layout().addWidget(btn_remove_author) authorPage.layout().addWidget(explanation) authorPage.layout().addWidget(self.authorTable) authorPage.layout().addWidget(author_button_layout) mainWidget.addTab(authorPage, i18n("Authors")) # The page with publisher information. publisherPage = QWidget() publisherLayout = QFormLayout() publisherPage.setLayout(publisherLayout) self.publisherName = QLineEdit() self.publisherName.setToolTip(i18n("The name of the company, group or person who is responsible for the final version the reader gets.")) publishDateLayout = QHBoxLayout() self.publishDate = QDateEdit() self.publishDate.setDisplayFormat(QLocale().system().dateFormat()) currentDate = QPushButton(i18n("Set Today")) currentDate.setToolTip(i18n("Sets the publish date to the current date.")) currentDate.clicked.connect(self.slot_set_date) publishDateLayout.addWidget(self.publishDate) publishDateLayout.addWidget(currentDate) self.publishCity = QLineEdit() self.publishCity.setToolTip(i18n("Traditional publishers are always mentioned in source with the city they are located.")) self.isbn = QLineEdit() self.license = license_combo_box() # Maybe ought to make this a QLineEdit... self.license.setEditable(True) self.license.completer().setCompletionMode(QCompleter.PopupCompletion) dataBaseReference = QVBoxLayout() self.ln_database_name = QLineEdit() self.ln_database_name.setToolTip(i18n("If there is an entry in a comics data base, that should be added here. It is unlikely to be a factor for comics from scratch, but useful when doing a conversion.")) self.cmb_entry_type = QComboBox() self.cmb_entry_type.addItems(["IssueID", "SeriesID", "URL"]) self.cmb_entry_type.setEditable(True) self.ln_source = QLineEdit() self.ln_source.setToolTip(i18n("Whether the comic is an adaptation of an existing source, and if so, how to find information about that source. So for example, for an adapted webcomic, the official website url should go here.")) self.label_uuid = QLabel() self.label_uuid.setToolTip(i18n("By default this will be filled with a generated universal unique identifier. The ID by itself is merely so that comic book library management programs can figure out if this particular comic is already in their database and whether it has been rated. Of course, the UUID can be changed into something else by manually changing the JSON, but this is advanced usage.")) self.ln_database_entry = QLineEdit() dbHorizontal = QHBoxLayout() dbHorizontal.addWidget(self.ln_database_name) dbHorizontal.addWidget(self.cmb_entry_type) dataBaseReference.addLayout(dbHorizontal) dataBaseReference.addWidget(self.ln_database_entry) publisherLayout.addRow(i18n("Name:"), self.publisherName) publisherLayout.addRow(i18n("City:"), self.publishCity) publisherLayout.addRow(i18n("Date:"), publishDateLayout) publisherLayout.addRow(i18n("ISBN:"), self.isbn) publisherLayout.addRow(i18n("Source:"), self.ln_source) publisherLayout.addRow(i18n("UUID:"), self.label_uuid) publisherLayout.addRow(i18n("License:"), self.license) publisherLayout.addRow(i18n("Database:"), dataBaseReference) mainWidget.addTab(publisherPage, i18n("Publisher")) """ Ensure that the drag and drop of authors doesn't mess up the labels. """ def slot_reset_author_row_visual(self): headerLabelList = [] for i in range(self.authorTable.verticalHeader().count()): headerLabelList.append(str(i)) for i in range(self.authorTable.verticalHeader().count()): logicalI = self.authorTable.verticalHeader().logicalIndex(i) headerLabelList[logicalI] = str(i + 1) self.authorModel.setVerticalHeaderLabels(headerLabelList) """ Set the publish date to the current date. """ def slot_set_date(self): self.publishDate.setDate(QDate().currentDate()) def slot_update_countries(self): code = self.cmbLanguage.codeForCurrentEntry() self.cmbCountry.set_country_for_locale(code) """ Append keys to autocompletion lists from the directory mainP. """ def get_auto_completion_keys(self, mainP=Path()): genre = Path(mainP / "key_genre") characters = Path(mainP / "key_characters") rating = Path(mainP / "key_rating") format = Path(mainP / "key_format") keywords = Path(mainP / "key_other") authorRole = Path(mainP / "key_author_roles") if genre.exists(): for t in list(genre.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.genreKeysList: self.genreKeysList.append(str(l).strip("\n")) file.close() if characters.exists(): for t in list(characters.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.characterKeysList: self.characterKeysList.append(str(l).strip("\n")) file.close() if format.exists(): for t in list(format.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.formatKeysList: self.formatKeysList.append(str(l).strip("\n")) file.close() if rating.exists(): for t in list(rating.glob('**/*.csv')): file = open(str(t), "r", newline="", encoding="utf-8") ratings = csv.reader(file) title = os.path.basename(str(t)) r = 0 for row in ratings: listItem = [] if r is 0: title = row[1] else: listItem = self.ratingKeysList[title] item = [] item.append(row[0]) item.append(row[1]) listItem.append(item) self.ratingKeysList[title] = listItem r += 1 file.close() if keywords.exists(): for t in list(keywords.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.otherKeysList: self.otherKeysList.append(str(l).strip("\n")) file.close() if authorRole.exists(): for t in list(authorRole.glob('**/*.txt')): file = open(str(t), "r", errors="replace") for l in file: if str(l).strip("\n") not in self.authorRoleList: self.authorRoleList.append(str(l).strip("\n")) file.close() """ Refill the ratings box. This is called whenever the rating system changes. """ def slot_refill_ratings(self): if self.cmbRatingSystem.currentText() in self.ratingKeysList.keys(): self.cmbRating.clear() model = QStandardItemModel() for i in self.ratingKeysList[self.cmbRatingSystem.currentText()]: item = QStandardItem() item.setText(i[0]) item.setToolTip(i[1]) model.appendRow(item) self.cmbRating.setModel(model) """ Add an author with default values initialised. """ def slot_add_author(self): listItems = [] listItems.append(QStandardItem(i18n("Anon"))) # Nick name listItems.append(QStandardItem(i18n("John"))) # First name listItems.append(QStandardItem()) # Middle name listItems.append(QStandardItem(i18n("Doe"))) # Last name listItems.append(QStandardItem()) # role listItems.append(QStandardItem()) # email listItems.append(QStandardItem()) # homepage language = QLocale.system().name().split("_")[0] if language == "C": language = "en" listItems.append(QStandardItem(language)) # Language self.authorModel.appendRow(listItems) """ Remove the selected author from the author list. """ def slot_remove_author(self): self.authorModel.removeRow(self.authorTable.currentIndex().row()) """ Load the UI values from the config dictionary given. """ def setConfig(self, config): if "title" in config.keys(): self.lnTitle.setText(config["title"]) self.teSummary.clear() if "pages" in config.keys(): self.cmbCoverPage.clear() for page in config["pages"]: self.cmbCoverPage.addItem(page) if "cover" in config.keys(): if config["cover"] in config["pages"]: self.cmbCoverPage.setCurrentText(config["cover"]) if "summary" in config.keys(): self.teSummary.appendPlainText(config["summary"]) if "genre" in config.keys(): genreList = [] genreListConf = config["genre"] totalMatch = 100 if isinstance(config["genre"], dict): genreListConf = config["genre"].keys() totalMatch = 0 for genre in genreListConf: genreKey = genre if genre in self.acbfGenreList: genreKey = self.acbfGenreList[genre] if isinstance(config["genre"], dict): genreValue = config["genre"][genre] if genreValue > 0: genreKey = str(genreKey + "(" + str(genreValue) + ")") genreList.append(genreKey) self.lnGenre.setText(", ".join(genreList)) if "characters" in config.keys(): self.lnCharacters.setText(", ".join(config["characters"])) if "format" in config.keys(): self.lnFormat.setText(", ".join(config["format"])) if "rating" in config.keys(): self.cmbRating.setCurrentText(config["rating"]) else: self.cmbRating.setCurrentText("") if "ratingSystem" in config.keys(): self.cmbRatingSystem.setCurrentText(config["ratingSystem"]) else: self.cmbRatingSystem.setCurrentText("") if "otherKeywords" in config.keys(): self.lnOtherKeywords.setText(", ".join(config["otherKeywords"])) if "seriesName" in config.keys(): self.lnSeriesName.setText(config["seriesName"]) if "seriesVolume" in config.keys(): self.spnSeriesVol.setValue(config["seriesVolume"]) if "seriesNumber" in config.keys(): self.spnSeriesNumber.setValue(config["seriesNumber"]) if "language" in config.keys(): code = config["language"] if "_" in code: self.cmbLanguage.setEntryToCode(code.split("_")[0]) self.cmbCountry.setEntryToCode(code.split("_")[-1]) elif "-" in code: self.cmbLanguage.setEntryToCode(code.split("-")[0]) self.cmbCountry.setEntryToCode(code.split("-")[-1]) else: self.cmbLanguage.setEntryToCode(code) if "readingDirection" in config.keys(): if config["readingDirection"] is "leftToRight": self.cmbReadingMode.setCurrentIndex(int(Qt.LeftToRight)) else: self.cmbReadingMode.setCurrentIndex(int(Qt.RightToLeft)) else: self.cmbReadingMode.setCurrentIndex(QLocale(self.cmbLanguage.codeForCurrentEntry()).textDirection()) if "publisherName" in config.keys(): self.publisherName.setText(config["publisherName"]) if "publisherCity" in config.keys(): self.publishCity.setText(config["publisherCity"]) if "publishingDate" in config.keys(): self.publishDate.setDate(QDate.fromString(config["publishingDate"], Qt.ISODate)) if "isbn-number" in config.keys(): self.isbn.setText(config["isbn-number"]) if "source" in config.keys(): self.ln_source.setText(config["source"]) elif "acbfSource" in config.keys(): self.ln_source.setText(config["acbfSource"]) if "uuid" in config.keys(): self.label_uuid.setText(config["uuid"]) else: uuid = str() if "acbfID" in config.keys(): uuid = config["acbfID"] uuid = uuid.strip("{") uuid = uuid.strip("}") uuidVerify = uuid.split("-") if len(uuidVerify[0])!=8 or len(uuidVerify[1])!=4 or len(uuidVerify[2])!=4 or len(uuidVerify[3])!=4 or len(uuidVerify[4])!=12: uuid = QUuid.createUuid().toString() self.label_uuid.setText(uuid) config["uuid"] = uuid if "license" in config.keys(): self.license.setCurrentText(config["license"]) else: self.license.setCurrentText("") # I would like to keep it ambiguous whether the artist has thought about the license or not. if "authorList" in config.keys(): authorList = config["authorList"] for i in range(len(authorList)): author = authorList[i] if len(author.keys()) > 0: listItems = [] listItems = [] listItems.append(QStandardItem(author.get("nickname", ""))) listItems.append(QStandardItem(author.get("first-name", ""))) listItems.append(QStandardItem(author.get("initials", ""))) listItems.append(QStandardItem(author.get("last-name", ""))) role = author.get("role", "") if role in self.acbfAuthorRolesList.keys(): role = self.acbfAuthorRolesList[role] listItems.append(QStandardItem(role)) listItems.append(QStandardItem(author.get("email", ""))) listItems.append(QStandardItem(author.get("homepage", ""))) listItems.append(QStandardItem(author.get("language", ""))) self.authorModel.appendRow(listItems) else: self.slot_add_author() dbRef = config.get("databaseReference", {}) self.ln_database_name.setText(dbRef.get("name", "")) self.ln_database_entry.setText(dbRef.get("entry", "")) stringCmbEntryType = self.cmb_entry_type.itemText(0) self.cmb_entry_type.setCurrentText(dbRef.get("type", stringCmbEntryType)) """ Store the GUI values into the config dictionary given. @return the config diactionary filled with new values. """ def getConfig(self, config): text = self.lnTitle.text() if len(text) > 0 and text.isspace() is False: config["title"] = text elif "title" in config.keys(): config.pop("title") config["cover"] = self.cmbCoverPage.currentText() listkeys = self.lnGenre.text() if len(listkeys) > 0 and listkeys.isspace() is False: preSplit = self.lnGenre.text().split(",") genreMatcher = re.compile(r'\((\d+)\)') genreList = {} totalValue = 0 for key in preSplit: m = genreMatcher.search(key) if m: genre = str(genreMatcher.sub("", key)).strip() match = int(m.group()[:-1][1:]) else: genre = key.strip() match = 0 if genre in self.acbfGenreList.values(): i = list(self.acbfGenreList.values()).index(genre) genreList[list(self.acbfGenreList.keys())[i]] = match else: genreList[genre] = match totalValue += match # Normalize the values: for key in genreList.keys(): if genreList[key] > 0: genreList[key] = round(genreList[key] / totalValue * 100) config["genre"] = genreList elif "genre" in config.keys(): config.pop("genre") listkeys = self.lnCharacters.text() if len(listkeys) > 0 and listkeys.isspace() is False: config["characters"] = self.lnCharacters.text().split(", ") elif "characters" in config.keys(): config.pop("characters") listkeys = self.lnFormat.text() if len(listkeys) > 0 and listkeys.isspace() is False: config["format"] = self.lnFormat.text().split(", ") elif "format" in config.keys(): config.pop("format") config["ratingSystem"] = self.cmbRatingSystem.currentText() config["rating"] = self.cmbRating.currentText() listkeys = self.lnOtherKeywords.text() if len(listkeys) > 0 and listkeys.isspace() is False: config["otherKeywords"] = self.lnOtherKeywords.text().split(", ") elif "otherKeywords" in config.keys(): config.pop("otherKeywords") text = self.teSummary.toPlainText() if len(text) > 0 and text.isspace() is False: config["summary"] = text elif "summary" in config.keys(): config.pop("summary") if len(self.lnSeriesName.text()) > 0: config["seriesName"] = self.lnSeriesName.text() config["seriesNumber"] = self.spnSeriesNumber.value() if self.spnSeriesVol.value() > 0: config["seriesVolume"] = self.spnSeriesVol.value() config["language"] = str(self.cmbLanguage.codeForCurrentEntry()+"-"+self.cmbCountry.codeForCurrentEntry()) if self.cmbReadingMode.currentIndex() is int(Qt.LeftToRight): config["readingDirection"] = "leftToRight" else: config["readingDirection"] = "rightToLeft" authorList = [] for row in range(self.authorTable.verticalHeader().count()): logicalIndex = self.authorTable.verticalHeader().logicalIndex(row) listEntries = ["nickname", "first-name", "initials", "last-name", "role", "email", "homepage", "language"] author = {} for i in range(len(listEntries)): entry = self.authorModel.data(self.authorModel.index(logicalIndex, i)) if entry is None: entry = " " if entry.isspace() is False and len(entry) > 0: if listEntries[i] == "role": if entry in self.acbfAuthorRolesList.values(): entryI = list(self.acbfAuthorRolesList.values()).index(entry) entry = list(self.acbfAuthorRolesList.keys())[entryI] author[listEntries[i]] = entry elif listEntries[i] in author.keys(): author.pop(listEntries[i]) authorList.append(author) config["authorList"] = authorList config["publisherName"] = self.publisherName.text() config["publisherCity"] = self.publishCity.text() config["publishingDate"] = self.publishDate.date().toString(Qt.ISODate) config["isbn-number"] = self.isbn.text() config["source"] = self.ln_source.text() config["license"] = self.license.currentText() if self.ln_database_name.text().isalnum() and self.ln_database_entry.text().isalnum(): dbRef = {} dbRef["name"] = self.ln_database_name.text() dbRef["entry"] = self.ln_database_entry.text() dbRef["type"] = self.cmb_entry_type.currentText() config["databaseReference"] = dbRef return config
class MainWindow(QMainWindow, Ui_MainWindow): # Maintain the list of browser windows so that they do not get garbage # collected. _window_list = [] def __init__(self): super(MainWindow, self).__init__() MainWindow._window_list.append(self) self.setupUi(self) # Qt Designer (at least to v4.2.1) can't handle arbitrary widgets in a # QToolBar - even though uic can, and they are in the original .ui # file. Therefore we manually add the problematic widgets. self.lblAddress = QLabel("Address", self.tbAddress) self.tbAddress.insertWidget(self.actionGo, self.lblAddress) self.addressEdit = QLineEdit(self.tbAddress) self.tbAddress.insertWidget(self.actionGo, self.addressEdit) self.addressEdit.returnPressed.connect(self.actionGo.trigger) self.actionBack.triggered.connect(self.WebBrowser.GoBack) self.actionForward.triggered.connect(self.WebBrowser.GoForward) self.actionStop.triggered.connect(self.WebBrowser.Stop) self.actionRefresh.triggered.connect(self.WebBrowser.Refresh) self.actionHome.triggered.connect(self.search) self.actionSearch.triggered.connect(self.WebBrowser.GoSearch) self.pb = QProgressBar(self.statusBar()) self.pb.setTextVisible(False) self.pb.hide() self.statusBar().addPermanentWidget(self.pb) self.WebBrowser.dynamicCall('GoHome()') self.setWindowTitle("PyQt messagebox example - pythonprogramminglanguage.com") self.text_box = QPlainTextEdit(self) self.text_box.insertPlainText("You can write text here.\n") self.text_box.move(950,910) self.text_box.resize(300,80) def closeEvent(self, e): MainWindow._window_list.remove(self) e.accept() def on_WebBrowser_TitleChange(self, title): self.setWindowTitle("Qt WebBrowser - " + title) def on_WebBrowser_ProgressChange(self, a, b): if a <= 0 or b <= 0: self.pb.hide() return self.pb.show() self.pb.setRange(0, b) self.pb.setValue(a) def on_WebBrowser_CommandStateChange(self, cmd, on): if cmd == 1: self.actionForward.setEnabled(on) elif cmd == 2: self.actionBack.setEnabled(on) def on_WebBrowser_BeforeNavigate(self): self.actionStop.setEnabled(True) def on_WebBrowser_NavigateComplete(self, _): self.actionStop.setEnabled(False) @pyqtSlot() def on_actionGo_triggered(self): self.WebBrowser.dynamicCall('Navigate(const QString&)', self.addressEdit.text()) @pyqtSlot() def on_actionNewWindow_triggered(self): window = MainWindow() window.show() window.addressEdit.setText(self.addressEdit.text()) window.actionStop.setEnabled(True) window.on_actionGo_triggered() @pyqtSlot() def on_actionAbout_triggered(self): QMessageBox.about(self, "About WebBrowser", "This Example has been created using the ActiveQt integration into Qt Designer.\n" "It demonstrates the use of QAxWidget to embed the Internet Explorer ActiveX\n" "control into a Qt application.") @pyqtSlot() def on_actionAboutQt_triggered(self): QMessageBox.aboutQt(self, "About Qt") def search(self): global count global flag global start # print (count) self.text_box.hide() self.text_box.clear() if(flag == 0): self.addressEdit.setText(instruction[0]) self.actionGo.trigger() flag = 1 else: if(count > 18): MainWindow._window_list.remove(self) exit() elif(count == 18): self.addressEdit.setText("file:///E:/courses/sem7/ell890(CN)/STIMULUS/end.html") self.actionGo.trigger() elif (count%3==0): self.addressEdit.setText("file:///E:/courses/sem7/ell890(CN)/STIMULUS/"+search_instruction[int(count/3)]+".html") self.actionGo.trigger() elif(count%3==1): print (int(count/3)) print ("website Loading.....") end = time.time() print (end - start) self.addressEdit.setText(urls[int(count/3)]) self.actionGo.trigger() end = time.time() self.text_box.show() self.text_box.insertPlainText(msg[int(count/3)]) else: print ("website navigation completed") end = time.time() print (end - start) self.addressEdit.setText("file:///E:/courses/sem7/ell890(CN)/STIMULUS/fixation.html") self.actionGo.trigger() # time.sleep(15) # self.search() count = count + 1
class InputTab(SerafinInputTab): def __init__(self, parent): super().__init__(parent) self.ref_data = None self.test_data = None self.ref_mesh = None self.polygons = [] self.selected_polygon = None self.ref_mesh = None self.polygon_added = False # is the intersection between the mesh and the selected polygon calculated? # initialize the map for locating polygons canvas = PolygonMapCanvas() self.map = MapViewer(canvas) self.has_map = False self._initWidgets() self._setLayout() self._bindEvents() def _initWidgets(self): # create the button open the reference file self.btnOpen.setText('Load\nReference') # create the button open the test file self.btnOpenTest = QPushButton('Load\nTest', self, icon=self.style().standardIcon(QStyle.SP_DialogOpenButton)) self.btnOpenTest.setToolTip('<b>Open</b> a Serafin file') self.btnOpenTest.setFixedSize(105, 50) self.btnOpenTest.setEnabled(False) # create the button open the polygon file self.btnOpenPolygon = QPushButton('Load polygons\n(optional)', self, icon=self.style().standardIcon(QStyle.SP_DialogOpenButton)) self.btnOpenPolygon.setToolTip('<b>Open</b> a .i2s or .shp file') self.btnOpenPolygon.setFixedSize(135, 50) self.btnOpenPolygon.setEnabled(False) # create the button for locating polygons on map self.locatePolygons = QPushButton('Locate polygons\non map', icon=self.style().standardIcon(QStyle.SP_DialogHelpButton)) self.locatePolygons.setToolTip('<b>Open</b> a map with polygons') self.locatePolygons.setFixedSize(135, 50) self.locatePolygons.setEnabled(False) # create some text fields displaying the IO files info self.testNameBox = QLineEdit() self.testNameBox.setReadOnly(True) self.testNameBox.setFixedHeight(30) self.testNameBox.setMinimumWidth(600) self.testSummaryTextBox = QPlainTextEdit() self.testSummaryTextBox.setReadOnly(True) self.testSummaryTextBox.setMinimumHeight(40) self.testSummaryTextBox.setMaximumHeight(50) self.testSummaryTextBox.setMinimumWidth(600) self.polygonNameBox = QPlainTextEdit() self.polygonNameBox.setReadOnly(True) self.polygonNameBox.setFixedHeight(50) self.polygonNameBox.setMinimumWidth(600) # create combo box widgets for choosing the variable self.varBox = QComboBox() self.varBox.setFixedSize(400, 30) # create combo box widgets for choosing the polygon self.polygonBox = QComboBox() self.polygonBox.setFixedSize(400, 30) def _bindEvents(self): self.btnOpen.clicked.connect(self.btnOpenRefEvent) self.btnOpenTest.clicked.connect(self.btnOpenTestEvent) self.btnOpenPolygon.clicked.connect(self.btnOpenPolygonEvent) self.locatePolygons.clicked.connect(self.locatePolygonsEvent) self.polygonBox.currentTextChanged.connect(self.selectPolygonEvent) self.map.closeEvent = lambda event: self.locatePolygons.setEnabled(True) def _setLayout(self): mainLayout = QVBoxLayout() mainLayout.addItem(QSpacerItem(10, 20)) mainLayout.setSpacing(15) hlayout = QHBoxLayout() hlayout.setAlignment(Qt.AlignLeft) hlayout.addItem(QSpacerItem(50, 1)) hlayout.addWidget(self.btnOpen) hlayout.addWidget(self.btnOpenTest) hlayout.addItem(QSpacerItem(30, 1)) hlayout.addWidget(self.langBox) hlayout.addItem(QSpacerItem(30, 1)) hlayout.addWidget(self.btnOpenPolygon) hlayout.addWidget(self.locatePolygons) hlayout.setSpacing(10) mainLayout.addLayout(hlayout) mainLayout.addItem(QSpacerItem(10, 10)) glayout = QGridLayout() glayout.addWidget(QLabel(' Reference'), 1, 1) glayout.addWidget(self.inNameBox, 1, 2) glayout.addWidget(QLabel(' Summary'), 2, 1) glayout.addWidget(self.summaryTextBox, 2, 2) glayout.addWidget(QLabel(' Test'), 3, 1) glayout.addWidget(self.testNameBox, 3, 2) glayout.addWidget(QLabel(' Summary'), 4, 1) glayout.addWidget(self.testSummaryTextBox, 4, 2) glayout.addWidget(QLabel(' Polygons'), 5, 1) glayout.addWidget(self.polygonNameBox, 5, 2) glayout.setAlignment(Qt.AlignLeft) glayout.setVerticalSpacing(10) mainLayout.addLayout(glayout) mainLayout.addItem(QSpacerItem(10, 10)) glayout = QGridLayout() glayout.addWidget(QLabel(' Select the variable to compare'), 1, 1) glayout.addWidget(self.varBox, 1, 2) glayout.addWidget(QLabel(' Select the comparison domain'), 2, 1) glayout.addWidget(self.polygonBox, 2, 2) glayout.setSpacing(10) mainLayout.addLayout(glayout) mainLayout.setAlignment(glayout, Qt.AlignTop | Qt.AlignLeft) mainLayout.addItem(QSpacerItem(30, 15)) mainLayout.addWidget(QLabel(' Message logs')) mainLayout.addWidget(self.logTextBox.widget) self.setLayout(mainLayout) self.setLayout(mainLayout) def _reinitRef(self): self.reset() self.ref_mesh = None self.ref_data = None self.polygon_added = False self.selected_polygon = None self.polygons = [] self.test_data = None self.testSummaryTextBox.clear() self.testNameBox.clear() self.polygonNameBox.clear() self.varBox.clear() self.polygonBox.clear() self.btnOpenTest.setEnabled(False) self.btnOpenPolygon.setEnabled(False) self.locatePolygons.setEnabled(False) self.map.hide() self.has_map = False self.parent.reset() def _reinitTest(self, filename): self.test_data = None self.testNameBox.setText(filename) self.testSummaryTextBox.clear() self.varBox.clear() def locatePolygonsEvent(self): if not self.has_map: self.map.canvas.reinitFigure(self.ref_mesh, self.polygons, ['Polygon %d' % (i+1) for i in range(len(self.polygons))]) self.has_map = True self.locatePolygons.setEnabled(False) self.map.show() def selectPolygonEvent(self, text): if not text: return elif text == 'Entire mesh': self.selected_polygon = None else: polygon_index = int(text.split()[1]) - 1 self.selected_polygon = self.polygons[polygon_index] self.polygon_added = False def btnOpenRefEvent(self): canceled, filename = super().open_event() if canceled: return self._reinitRef() success, data = self.read_2d(filename) if not success: return self.ref_data = data # record the mesh self.parent.inDialog() meshLoader = LoadMeshDialog('comparison', self.ref_data.header) self.ref_mesh = meshLoader.run() self.parent.outDialog() if meshLoader.thread.canceled: self.summaryTextBox.clear() self.ref_data = None return self.parent.add_reference() self.btnOpenTest.setEnabled(True) self.btnOpenPolygon.setEnabled(True) self.polygonBox.addItem('Entire mesh') def btnOpenTestEvent(self): canceled, filename = super().open_event() if canceled: return self._reinitTest(filename) success, data = self.read_2d(filename, update=False) if not success: return # check if the mesh is identical to the reference if not self.ref_data.header.same_2d_mesh(data.header): QMessageBox.critical(self, 'Error', 'The mesh is not identical to the reference.', QMessageBox.Ok) return # check if the test file has common variables with the reference file common_vars = [(var_ID, var_names) for var_ID, var_names in zip(self.ref_data.header.var_IDs, self.ref_data.header.var_names) if var_ID in data.header.var_IDs] if not common_vars: QMessageBox.critical(self, 'Error', 'No common variable with the reference file.', QMessageBox.Ok) return self.test_data = data self.testNameBox.setText(filename) self.testSummaryTextBox.appendPlainText(self.test_data.header.summary()) self.parent.add_test() for var_ID, var_name in common_vars: self.varBox.addItem(var_ID + ' (%s)' % var_name.decode(Serafin.SLF_EIT).strip()) def btnOpenPolygonEvent(self): success, filename, polygons = open_polygons() if not success: return self.polygons = polygons self.map.close() self.map.has_figure = False self.polygonNameBox.clear() self.polygonNameBox.appendPlainText(filename + '\n' + 'The file contains {} polygon{}.'.format( len(self.polygons), 's' if len(self.polygons) > 1 else '')) self.polygonBox.clear() self.polygonBox.addItem('Entire mesh') for i in range(len(self.polygons)): self.polygonBox.addItem('Polygon %d' % (i+1)) self.locatePolygons.setEnabled(True)
class Assembler(QMainWindow): def __init__(self, parent=None): super(Assembler, self).__init__(parent) self.resize(800, 600) self.filename = None self.filetuple = None self.dirty = False # Refers to Data Page only. self.nb = None centralwidget = QWidget(self) gridLayout = QGridLayout(centralwidget) self.tabWidget = QTabWidget(centralwidget) # textbox self.tab = QWidget() font = QFont() font.setFamily("Inconsolata") font.setPointSize(14) self.tab.setFont(font) gridLayout_3 = QGridLayout(self.tab) self.plainTextEdit = QPlainTextEdit(self.tab) self.plainTextEdit.installEventFilter(self) self.plainTextEdit.setAcceptDrops(True) gridLayout_3.addWidget(self.plainTextEdit, 0, 0, 1, 1) self.tabWidget.addTab(self.tab, "") self.tab_2 = QWidget() self.tab_2.setFont(font) gridLayout_2 = QGridLayout(self.tab_2) self.plainTextEdit_2 = QPlainTextEdit(self.tab_2) gridLayout_2.addWidget(self.plainTextEdit_2, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_2, "") self.tab_3 = QWidget() self.tab_3.setFont(font) gridLayout_3 = QGridLayout(self.tab_3) self.checkbox = QCheckBox("Cloning genes by tailed primers (no pYPKa_A vectors constructed)") self.checkbox.setChecked(True) gridLayout_3.addWidget(self.checkbox, 0, 0, 0, 0) self.tabWidget.addTab(self.tab_3, "") gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1) self.setCentralWidget(centralwidget) menubar = QMenuBar(self) menubar.setGeometry(QRect(0, 0, 800, 29)) menu_File = QMenu(menubar) self.menu_Solve = QMenu(menubar) self.menu_Help = QMenu(menubar) self.setMenuBar(menubar) self.statusbar = QStatusBar(self) self.setStatusBar(self.statusbar) self.action_New = QAction(self) self.actionSave_As = QAction(self) self.action_Save = QAction(self) self.action_Open = QAction(self) self.action_Quit = QAction(self) self.action_About = QAction(self) self.actionShow_CCPL = QAction(self) self.action_Solve = QAction(self) self.action_OpenNB = QAction(self) self.action_CCPL = QAction(self) self.action_Help = QAction(self) menu_File.addAction(self.action_New) menu_File.addAction(self.action_Open) menu_File.addAction(self.actionSave_As) menu_File.addAction(self.action_Save) menu_File.addSeparator() menu_File.addAction(self.action_Quit) self.menu_Solve.addAction(self.action_Solve) self.menu_Solve.addAction(self.action_OpenNB) self.menu_Help.addAction(self.action_About) #self.menu_Help.addAction(self.action_CCPL) #self.menu_Help.addAction(self.action_Help) menubar.addAction(menu_File.menuAction()) menubar.addAction(self.menu_Solve.menuAction()) menubar.addAction(self.menu_Help.menuAction()) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),\ "Data Page") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),\ "Assembly log") self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3),\ "Settings") menu_File.setTitle("&File") self.menu_Solve.setTitle("&Assemble") self.menu_Help.setTitle("&About") self.tabWidget.setCurrentIndex(0) self.action_New.setText("&New") self.action_Open.setText("&Open") self.actionSave_As.setText("Save &As") self.action_Save.setText("&Save") self.action_Quit.setText("&Quit") self.action_Solve.setText("&Assemble") self.action_OpenNB.setText("&Open &pathway") self.action_About.setText("&About") #self.action_CCPL.setText("&CCPL") #self.action_Help.setText("&Help") self.action_Quit.triggered.connect(self.close) allToolBar = self.addToolBar("AllToolBar") allToolBar.setObjectName("AllToolBar") self.addActions(allToolBar, (self.action_Open, self.actionSave_As, self.action_Save, self.action_Solve, self.action_OpenNB, self.action_Quit )) self.action_New.triggered.connect(self.fileNew) self.action_Open.triggered.connect(self.fileOpen) self.actionSave_As.triggered.connect(self.fileSaveAs) self.action_Save.triggered.connect(self.fileSave) self.action_Solve.triggered.connect(self.solveAssembly) self.action_OpenNB.triggered.connect(self.openNB) self.action_About.triggered.connect(self.aboutBox) #self.action_CCPL.triggered.connect(self.displayCCPL) #self.action_Help.triggered.connect(self.help) self.plainTextEdit.textChanged.connect(self.setDirty) self.action_New = self.editAction(self.action_New, None,\ 'ctrl+N', 'filenew', 'New File.') self.action_Open = self.editAction(self.action_Open, None, 'ctrl+O', 'fileopen', 'Open File.') self.actionSave_As = self.editAction(self.actionSave_As,\ None, 'ctrl+A', 'filesaveas',\ 'Save and Name File.') self.action_Save = self.editAction(self.action_Save, None, 'ctrl+S', 'filesave', 'Save File.') self.action_Solve = self.editAction(self.action_Solve, None, '', 'solve', 'Assemble.') self.action_OpenNB = self.editAction(self.action_OpenNB, None, '', 'ipynb', 'Open pathway.') self.action_About = self.editAction(self.action_About, None, 'ctrl+B', 'about','Pop About Box.') self.action_CCPL = self.editAction(self.action_CCPL, None, 'ctrl+G', 'licence', 'Show Licence') self.action_Help = self.editAction(self.action_Help, None, 'ctrl+H', 'help', 'Show Help Page.') self.action_Quit = self.editAction(self.action_Quit, None, 'ctrl+Q', 'quit', 'Quit the program.') self.plainTextEdit_2.setReadOnly(True) self.setWindowTitle("ypkpathway") self.setWindowIcon(QIcon( resource_filename("ypkpathway","icons/ypkpathway.png"))) self.plainTextEdit.setFocus() def eventFilter(self, object, event): #print(event.type(), QEvent.DragEnter, object, self.plainTextEdit) if (object is self.plainTextEdit): if (event.type() == QEvent.DragEnter): if event.mimeData().hasUrls(): event.accept() # must accept the dragEnterEvent or else the dropEvent can't occur !!! print("accept") else: event.ignore() print("ignore") if (event.type() == QEvent.Drop): if event.mimeData().hasUrls(): # if file or link is dropped urlcount = len(event.mimeData().urls()) # count number of drops url = event.mimeData().urls()[0] # get first url object.setPlainText('abc') # assign first url to editline event.accept() # doesnt appear to be needed print(456) return True return False # lets the event continue to the edit return False def setDirty(self): '''On change of text in textEdit window, set the flag "dirty" to True''' index = self.tabWidget.currentIndex() if index is not 0: return if self.dirty: return True self.dirty = True self.updateStatus('self.dirty set to True') def clearDirty(self): 'Clear dirty flag' self.dirty = False def fileNew(self): '''Clear both Data Page and Solution Page.''' self.plainTextEdit.setPlainText(' ') self.plainTextEdit_2.setPlainText(' ') self.clearDirty() self.filename = None def okToContinue(self): if self.dirty: reply = QMessageBox.question(self, "Data Loader - Unsaved Changes", "Save unsaved changes?", QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel) if reply == QMessageBox.Cancel: return False elif reply == QMessageBox.Yes: self.clearDirty() return self.fileSave() return True def okRead(self): 'Pop-up a warning message.' reply = QMessageBox.warning(self, "Warning", '''\nFile Open and Save only in Data Page \n\(Use SaveAs for the Assembly log)''', QMessageBox.Ok) return True def fileOpen(self): '''Open a file in Data Page (with index == 0)''' if self.tabWidget.currentIndex(): self.okRead() return if not self.okToContinue(): return dir_ = (os.path.dirname(str(self.filename)) if self.filename is not None else ".") filetuple = QFileDialog.getOpenFileName(self,"Open File", dir_,) self.filename = filetuple[0] # QFileDialog returns a tuple x with x[0] = file name and # x[1] = type of filter. if self.filename: self.loadFile(self.filename) self.updateStatus('New file opened.') def loadFile(self, fname=None): fl = open(fname, "r") text = fl.read() self.plainTextEdit.setPlainText(text) self.dirty = False def fileSave(self): '''Save file with current file name.''' if self.tabWidget.currentIndex(): self.okRead() return if self.filename is None: return self.fileSaveAs() else: flname = self.filename if flname: tempText = self.plainTextEdit.toPlainText() with open(flname, 'w') as fl: fl.write(tempText) self.dirty = False self.updateStatus('File saved.') return True else: self.updateStatus('Failed to save... ') return False self.filename = None self.dirty = False def fileSaveAs(self): '''Save file with a new name.''' qpr = self.qprintline fname = self.filename or "NoName.txt" self.filename = str(QFileDialog.getSaveFileName(self,"ypkpathway - Save File", fname)) flname = self.filename or "NoName.txt" self.filename = flname fl = open(flname, 'w') tempText = str(self.plainTextEdit.toPlainText()) fl.write(tempText) fl.close() self.dirty = False self.updateStatus('File saved.') def solveAssembly(self): printline = self.qprintline self.plainTextEdit_2.clear() self.tabWidget.setCurrentIndex(1) flbase = os.path.basename(str(self.filename)) title = 'Assembly log for ' + flbase printline('='*len(title)) printline(title) printline('='*len(title)) #print(type(self.plainTextEdit.toPlainText())) #qstringobj = self.plainTextEdit.toPlainText().encode('utf-8') #print(type(qstringobj)) #<class 'PyQt4.QtCore.QString'> #print(qstringobj.toUtf8()[3268:3279]) #print(str(qstringobj.toUtf8()[3268:3279])) #print(type(rawtext), "rawtext") #codec0 = .QTextCodec.codecForName("UTF-16"); #rawtext = unicode(codec0.fromUnicode(tmp), 'UTF-16') #unicode(qstringobj.toUtf8(), encoding="UTF-8").decode() qstringobj = self.plainTextEdit.toPlainText() #import sys;sys.exit(42) pth = parse( qstringobj ) #import sys;sys.exit(42) if len(pth)==0: printline("No of sequences found in Data window") return if self.filename is None: self.fileSaveAs() dir_, ext = os.path.splitext( str(self.filename)) fl, log = ypkpathway.pathway( pth, dir_, pYPKa_A = not self.checkbox.isChecked(), print = printline) if not fl: return with open(os.path.join(dir_, "log.txt"),"w") as f: f.write(log) shutil.copy2( str(self.filename), os.path.join(dir_, "INDATA_"+os.path.basename(str(self.filename)))) printline('') printline('\n\nAssembly finished.') printline('click on the Open pathway button above to open the pathway in the default web browser') self.nb = fl.path def qprintline(self, line): '''Append one line to Solution Page.''' self.plainTextEdit_2.appendPlainText(line.rstrip()) #.decode("utf8")) QApplication.processEvents() def openNB(self): if self.nb: subprocess.Popen(["ipython", "notebook", self.nb]) def aboutBox(self): from PyQt5.QtCore import QT_VERSION_STR from PyQt5.Qt import PYQT_VERSION_STR from sip import SIP_VERSION_STR from ._version import get_versions __version__ = get_versions()["version"][:5] del get_versions from IPython import __version__ as IPython_version QMessageBox.about(self, "About ypkpathway", """<b>Planning of yeast pathway kit constructions.</b> <p>version: {}<br> Copyright 2015-2017 Björn Johansson. This software is released under a BSD style license. This software comes with no warranties expressed or implied.<br><br> Python version: {}<br><br> IPython version: {}<br> Qt version: {}<br> SIP version: {}<br> PyQt version: {}<br> pydna version: {}<br></p> """.format(__version__, sys.version, IPython_version, QT_VERSION_STR, SIP_VERSION_STR, PYQT_VERSION_STR, pydna.__version__[:5])) def displayCCPL(self): '''Read and display CCPL licence.''' self.plainTextEdit.setPlainText(open('CCPL.txt').read()) self.dirty = False self.filename = 'COPYING.txt' self.updateStatus('CCPL displayed.') def help(self): '''Read and display a help file- currently the README.txt.''' self.plainTextEdit.setPlainText(open('README.md').read()) self.dirty = False self.filename = 'README.txt' self.updateStatus('README displayed.') def addActions(self, target, actions): '''Actions are added to Tool Bar.''' for action in actions: if action is None: target.addSeparator() else: target.addAction(action) def editAction(self, action, slot=None, shortcut=None, icon=None, tip=None): '''This method adds to action: icon, shortcut, ToolTip,\ StatusTip and can connect triggered action to slot ''' if icon is not None: action.setIcon(QIcon(":/%s.png" % (icon))) if shortcut is not None: action.setShortcut(shortcut) if tip is not None: action.setToolTip(tip) action.setStatusTip(tip) if slot is not None: action.triggered.connect(slot) return action def qreadline(self, lineNo): '''Read one line from Data Page (lineNo starts with 0)''' return str(self.plainTextEdit.document().\ findBlockByLineNumber(lineNo).text()).rstrip() def updateStatus(self, message): '''Keep status current.''' if self.filename is not None: flbase = os.path.basename(str(self.filename)) self.setWindowTitle(str("ypkpathway - " +\ flbase + "[*]") ) self.statusBar().showMessage(message, 5000) self.setWindowModified(self.dirty)
class SendTab(QWidget): TITLE = "Send" HOVER = "Use your seed to cosign a transaction." # FIXME (add support and UX for this) UNITS = "sats" def __init__(self): super().__init__() vbox = QVBoxLayout(self) self.psbtLabel = QLabel( "<b>Partially Signed Bitcoin Transaction</b> (required)") self.psbtLabel.setToolTip( "What your online computer is asking you to sign, in base64 format." ) self.psbtEdit = QPlainTextEdit("") self.psbtEdit.setPlaceholderText( "Something like this:\n\ncHNidP8BAH0CAAAAA...") # Network toggle # https://www.tutorialspoint.com/pyqt/pyqt_qradiobutton_widget.htm self.network_label = QLabel("<b>Bitcoin Network</b>") self.network_label.setToolTip(BITCOIN_NETWORK_TOOLTIP) hbox = QHBoxLayout(self) self.infernetwork_button = QRadioButton("Automatic") self.infernetwork_button.setToolTip( "Non-experts should choose this option." "<br/><br/>" "The current PSBT serialization format does not encode which network the transaction is on, but this software can usually infer the network based on the BIP32 path used. " "If the address displayed is in the wrong format (<i>bc1...</i> vs <i>tb1...</i>) then you may need to manually select the network." ) self.infernetwork_button.setChecked(True) self.mainnet_button = QRadioButton("Mainnet") self.mainnet_button.setToolTip(BITCOIN_MAINNET_TOOLTIP) self.mainnet_button.setChecked(False) self.testnet_button = QRadioButton("Testnet") self.testnet_button.setToolTip(BITCOIN_TESTNET_TOOLTIP) self.testnet_button.setChecked(False) for widget in ( self.infernetwork_button, self.mainnet_button, self.testnet_button, ): hbox.addWidget(widget) hbox.setAlignment(Qt.AlignCenter) self.psbtSubmitButton = QPushButton("Decode Transaction") self.psbtSubmitButton.clicked.connect(self.decode_psbt) self.fullSeedLabel = QLabel("<b>Full 24-Word Seed Phrase</b>") self.fullSeedLabel.setToolTip( "Needed to sign the PSBT. You can first decode the transaction and inspect it without supplying your seed phrase." ) self.fullSeedEdit = QPlainTextEdit("") self.fullSeedEdit.setPlaceholderText( "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo" ) self.fullSeedSubmitButton = QPushButton("Sign Transaction") self.fullSeedSubmitButton.clicked.connect(self.sign_psbt) self.psbtDecodedLabel = QLabel("") self.psbtDecodedLabel.setToolTip( "The summary of what this transaction does. Multiwallet statelessly verifies all inputs belong to the same quorum and that any change is properly returned." ) self.psbtDecodedROEdit = QPlainTextEdit("") self.psbtDecodedROEdit.setReadOnly(True) self.psbtDecodedROEdit.setHidden(True) self.psbtSignedLabel = QLabel("") self.psbtSignedLabel.setToolTip( "Signed version for your online computer, which will aggregate signatures and then broadcast to the bitcoin network (once it has the required <i>m-of-n</i> signatures)." ) self.psbtSignedROEdit = QPlainTextEdit("") self.psbtSignedROEdit.setReadOnly(True) self.psbtSignedROEdit.setHidden(True) self.qrButton = QPushButton() self.qrButton.setText("QR") self.qrButton.setToolTip( "For transmitting to your online computer via webcam." "<br/><br/>" "This is a great way to preserve your airgap.") self.qrButton.setHidden(True) self.qrButton.clicked.connect(self.make_qr_popup) for widget in ( self.psbtLabel, self.psbtEdit, self.network_label, ): vbox.addWidget(widget) vbox.addLayout(hbox) for widget in ( self.psbtSubmitButton, self.fullSeedLabel, self.fullSeedEdit, self.fullSeedSubmitButton, self.psbtDecodedLabel, self.psbtDecodedROEdit, self.psbtSignedLabel, self.psbtSignedROEdit, self.qrButton, ): vbox.addWidget(widget) self.setLayout(vbox) def decode_psbt(self): return self.process_psbt(sign_tx=False) def sign_psbt(self): return self.process_psbt(sign_tx=True) def make_qr_popup(self): return qr_dialog( qwidget=self, qr_text=self.psbtSignedROEdit.toPlainText(), window_title=self.psbtSignedLabel.text(), ) def process_psbt(self, sign_tx=True): # Clear any previous submission in case of errors self.psbtDecodedLabel.setText("") self.psbtDecodedROEdit.clear() self.psbtDecodedROEdit.setHidden(True) self.psbtSignedLabel.setText("") self.psbtSignedROEdit.clear() self.psbtSignedROEdit.setHidden(True) self.qrButton.setHidden(True) self.qrButton.setText("") # TODO: why setText and not hide? if self.infernetwork_button.isChecked(): PARSE_WITH_TESTNET = None elif self.mainnet_button.isChecked(): PARSE_WITH_TESTNET = False elif self.testnet_button.isChecked(): PARSE_WITH_TESTNET = True else: # This shouldn't be possible raise Exception( "Invalid Network Selection: No Radio Button Chosen") psbt_str = _clean_submisission(self.psbtEdit.toPlainText()) if not psbt_str: return _msgbox_err( main_text="No PSBT Supplied", informative_text="Enter a PSBT to decode and/or sign.", ) try: psbt_obj = PSBT.parse_base64(b64=psbt_str, testnet=PARSE_WITH_TESTNET) except Exception as e: if type(e) is ValueError and str(e) == "Mainnet/Testnet mixing": # TODO: less hackey way to catch this error? return _msgbox_err( main_text="PSBT Network Error", informative_text= "The network you selected doesn't match the PSBT.", detailed_text=str(e), ) else: return _msgbox_err( main_text="PSBT Parse Error", informative_text="Are you sure that's a valid PSBT?", detailed_text=str(e), ) # Parse TX self.TX_FEE_SATS = psbt_obj.tx_obj.fee() self.IS_TESTNET = psbt_obj.tx_obj.testnet # Validate multisig transaction # TODO: abstract some of this into buidl library? # Below is confusing because we perform both validation and coordinate signing. # This tool only supports a TX with the following constraints: # We sign ALL inputs and they have the same multisig wallet (quorum + pubkeys) # There can only be 1 output (sweep transaction) or 2 outputs (spend + change). # If there is change, we validate it has the same multisig wallet as the inputs we sign. # Gather TX info and validate inputs_desc = [] for cnt, psbt_in in enumerate(psbt_obj.psbt_ins): psbt_in.validate() # redundant but explicit if type(psbt_in.witness_script) != WitnessScript: return _msgbox_err( main_text="Input #{cnt} does not contain a witness script", informative_text= "This tool can only sign p2wsh transactions.", ) # Determine quroum_m (and that it hasn't changed between inputs) try: quorum_m = OP_CODE_NAMES[ psbt_in.witness_script.commands[0]].split("OP_")[1] except Exception: return _msgbox_err( main_text="Non-p2wsh Input", informative_text= f"Witness script for input #{cnt} is not p2wsh", detailed_text=f"PSBT Input:\n {psbt_in}", ) # for calculating msig fingerprint root_xfp_hexes = [] for _, details in psbt_in.named_pubs.items(): root_xfp_hexes.append(details.root_fingerprint.hex()) input_desc = { "quorum": f"{quorum_m}-of-{len(root_xfp_hexes)}", "root_xfp_hexes": root_xfp_hexes, "prev_txhash": psbt_in.tx_in.prev_tx.hex(), "prev_idx": psbt_in.tx_in.prev_index, "n_sequence": psbt_in.tx_in.sequence, "sats": psbt_in.tx_in.value(), # TODO: would be possible for transaction to be p2sh-wrapped p2wsh (can we tell?) "addr": psbt_in.witness_script.address(testnet=self.IS_TESTNET), # "p2sh_addr": psbt_in.witness_script.p2sh_address(testnet=self.IS_TESTNET), "witness_script": str(psbt_in.witness_script), "msig_digest": _calculate_msig_digest(quorum_m=quorum_m, root_xfp_hexes=root_xfp_hexes), } inputs_desc.append(input_desc) if not all(x["msig_digest"] == inputs_desc[0]["msig_digest"] for x in inputs_desc): return _msgbox_err( main_text="Inputs Contain Conflicting Wallet Quorums", informative_text= "This transaction is not inherently bad, but transactions of this type are only possible for experts. Please construct 1 or more transactions with one input instead.", detailed_text=f"For developers: {inputs_desc}", ) TOTAL_INPUT_SATS = sum([x["sats"] for x in inputs_desc]) # This too only supports TXs with 1-2 outputs (sweep TX OR spend+change TX): if len(psbt_obj.psbt_outs) > 2: return _msgbox_err( main_text="Too Many Outputs", informative_text= f"Multiwallet does not support batching, and your transaction has {len(psbt_obj.psbt_outs)} outputs.", detailed_text= "Please construct a transaction with <= 2 outputs.", ) spend_addr, output_spend_sats = "", 0 outputs_desc = [] for cnt, psbt_out in enumerate(psbt_obj.psbt_outs): psbt_out.validate() # redundant but explicit output_desc = { "sats": psbt_out.tx_out.amount, "addr_type": psbt_out.tx_out.script_pubkey.__class__.__name__.rstrip( "ScriptPubKey"), } if psbt_out.witness_script: output_desc["addr"] = psbt_out.witness_script.address( testnet=self.IS_TESTNET) else: output_desc["addr"] = psbt_out.tx_out.script_pubkey.address( testnet=self.IS_TESTNET) if psbt_out.named_pubs: # Validate below that this is correct and abort otherwise output_desc["is_change"] = True root_xfp_hexes = [] # for calculating msig fingerprint for _, details in psbt_out.named_pubs.items(): root_xfp_hexes.append(details.root_fingerprint.hex()) # Determine quroum_m (and that it hasn't changed between inputs) try: quorum_m = OP_CODE_NAMES[ psbt_out.witness_script.commands[0]].split("OP_")[1] except Exception: return _msgbox_err( main_text="Non-p2wsh Change Output", informative_text= "This transaction may be trying to trick you into sending change to a third party.", detailed_text= f"Witness script for output #{cnt} is not p2wsh: {psbt_out}", ) output_msig_digest = _calculate_msig_digest( quorum_m=quorum_m, root_xfp_hexes=root_xfp_hexes) if output_msig_digest != inputs_desc[0]["msig_digest"]: return _msgbox_err( main_text="Invalid Change Detected", informative_text= f"Output #{cnt} is claiming to be change but has different multisig wallet(s)! Do a sweep transaction (1-output) if you want this wallet to cosign.", detailed_text=f"For developers: {outputs_desc}", ) else: output_desc["is_change"] = False spend_addr = output_desc["addr"] output_spend_sats = output_desc["sats"] outputs_desc.append(output_desc) # Sanity check if len(outputs_desc) != len(psbt_obj.psbt_outs): return _msgbox_err( main_text="PSBT Parse Error", informative_text= f"{len(outputs_desc)} outputs in TX summary doesn't match {len(psbt_obj.psbt_outs)} outputs in PSBT.", ) # Confirm if 2 outputs we only have 1 change and 1 spend (can't be 2 changes or 2 spends) if len(outputs_desc) == 2: if all(x["is_change"] == outputs_desc[0]["is_change"] for x in outputs_desc): return _msgbox_err( main_text="Change-Only Transaction with 2 Outputs", informative_text= "Transactions with 2 outputs that are BOTH change are not allowed, as only experts can properly validate them. Please construct a transaction with fewer outputs.", detailed_text=f"For developers: {outputs_desc}", ) TX_SUMMARY = " ".join([ inputs_desc[0]["quorum"], "PSBT sends", _format_satoshis(output_spend_sats, in_btc=self.UNITS == "btc"), "to", spend_addr, "with a fee of", _format_satoshis(self.TX_FEE_SATS, in_btc=self.UNITS == "btc"), f"({round(self.TX_FEE_SATS / TOTAL_INPUT_SATS * 100, 2)}% of spend)", ]) self.psbtDecodedLabel.setText( f"<b>Decoded Transaction Summary</b> - {'Testnet' if self.IS_TESTNET else 'Mainnet'}" ) self.psbtDecodedROEdit.setHidden(False) self.psbtDecodedROEdit.appendPlainText(TX_SUMMARY) # TODO: surface this to user somehow to_print = [] to_print.append("DETAILED VIEW") to_print.append(f"TXID: {psbt_obj.tx_obj.id()}") to_print.append( f"Network: {'Testnet' if psbt_obj.tx_obj.testnet else 'Mainnet'}") to_print.append("-" * 80) to_print.append(f"{len(inputs_desc)} Input(s):") for cnt, input_desc in enumerate(inputs_desc): to_print.append(f" input #{cnt}") for k in input_desc: to_print.append(f" {k}: {input_desc[k]}") to_print.append("-" * 80) to_print.append(f"{len(outputs_desc)} Output(s):") for cnt, output_desc in enumerate(outputs_desc): to_print.append(f" output #{cnt}") for k in output_desc: to_print.append(f" {k}: {output_desc[k]}") print("\n".join(to_print)) seed_phrase = _clean_submisission(self.fullSeedEdit.toPlainText()) if not sign_tx: return if not seed_phrase: return _msgbox_err( main_text="No Seed Phrase Supplied", informative_text="Cannot sign transaction without seed phrase", ) seed_phrase_num = len(seed_phrase.split()) if seed_phrase_num not in (12, 15, 18, 21, 24): return _msgbox_err( main_text="Enter 24 word seed-phrase", informative_text=f"You entered {seed_phrase_num} words", ) try: hd_priv = HDPrivateKey.from_mnemonic(seed_phrase, testnet=self.IS_TESTNET) except Exception as e: return _msgbox_err( main_text="Invalid BIP39 Seed Phrase", informative_text="Transaction NOT signed", detailed_text=str(e), ) # Derive list of child private keys we'll use to sign the TX root_paths = set() for cnt, psbt_in in enumerate(psbt_obj.psbt_ins): # Redundant safety check: bad_txhash = inputs_desc[cnt][ "prev_txhash"] != psbt_in.tx_in.prev_tx.hex() bad_idx = inputs_desc[cnt]["prev_idx"] != psbt_in.tx_in.prev_index if bad_txhash or bad_idx: return _msgbox_err( main_text="PSBT Parse Error", informative_text="Transaction NOT signed", detailed_text= f"For developers: Input #{cnt} prev_txhash or prev_idx mismatch: \n{PSBT.serialize_base64()}", ) for _, details in psbt_in.named_pubs.items(): if details.root_fingerprint.hex() == hd_priv.fingerprint().hex( ): root_paths.add(details.root_path) if not root_paths: return _msgbox_err( main_text="Wrong Seed", informative_text= "Seed supplied does not correspond to transaction input(s). Does it belong to another wallet?", ) private_keys = [ hd_priv.traverse(root_path).private_key for root_path in root_paths ] try: if psbt_obj.sign_with_private_keys(private_keys) is True: self.psbtSignedLabel.setText("<b>Signed PSBT to Broadcast</b>") self.psbtSignedROEdit.setHidden(False) self.psbtSignedROEdit.appendPlainText( psbt_obj.serialize_base64()) self.qrButton.setHidden(False) self.qrButton.setText("QR") self.qrButton.setIcon(create_qr_icon()) else: return _msgbox_err( main_text="Transaction Not Signed", informative_text="Couldn't find private key to sign with", detailed_text= "This should've been checked earlier and should not be possible!", ) except Exception as e: return _msgbox_err( main_text="Transaction Not Signed", informative_text="There was an error during signing.", detailed_text=f"For developers: {e}", )
class ErrorDistributionTab(QWidget): def __init__(self, inputTab): super().__init__() self.input = inputTab self.ewsd = None self.xlim = None self.ylim = None # set up a custom plot viewer self.plotViewer = PlotViewer() self.plotViewer.exitAct.setEnabled(False) self.plotViewer.menuBar.setVisible(False) self.XLimitsAct = QAction('Change X limits', self, triggered=self.changeXlimits, enabled=False, icon=self.style().standardIcon(QStyle.SP_DialogNoButton)) self.YLimitsAct = QAction('Change Y limits', self, triggered=self.changeYlimits, enabled=False, icon=self.style().standardIcon(QStyle.SP_DialogNoButton)) self.plotViewer.toolBar.addAction(self.XLimitsAct) self.plotViewer.toolBar.addAction(self.YLimitsAct) self.plotViewer.toolBar.addSeparator() self.plotViewer.toolBar.addAction(self.plotViewer.xLabelAct) self.plotViewer.toolBar.addSeparator() self.plotViewer.toolBar.addAction(self.plotViewer.yLabelAct) self.plotViewer.toolBar.addSeparator() self.plotViewer.toolBar.addAction(self.plotViewer.titleAct) # put it in a group box to get a nice border gb = QGroupBox() ly = QHBoxLayout() ly.addWidget(self.plotViewer) gb.setLayout(ly) gb.setStyleSheet('QGroupBox {border: 8px solid rgb(108, 122, 137); border-radius: 6px }') gb.setMinimumWidth(600) # create the reference time selection widget self.timeSelection = DoubleTimeSelection() # create the compute button self.btnCompute = QPushButton('Compute', icon=self.style().standardIcon(QStyle.SP_DialogApplyButton)) self.btnCompute.setFixedSize(105, 50) self.btnCompute.clicked.connect(self.btnComputeEvent) # create the color map button self.btnColorMap = QPushButton('2D View', icon=self.style().standardIcon(QStyle.SP_DialogHelpButton)) self.btnColorMap.setFixedSize(105, 50) self.btnColorMap.clicked.connect(self.btnColorMapEvent) self.btnColorMap.setEnabled(False) # initialize the map for 2D view canvas = ColorMapCanvas() self.map = MapViewer(canvas) self.has_map = False self.map.closeEvent = lambda event: self.btnColorMap.setEnabled(True) # create the stats box self.resultBox = QPlainTextEdit() self.resultBox.setMinimumWidth(400) self.resultBox.setMaximumWidth(600) # set layout mainLayout = QVBoxLayout() mainLayout.addItem(QSpacerItem(10, 10)) mainLayout.addWidget(self.timeSelection) vlayout = QVBoxLayout() hlayout = QHBoxLayout() hlayout.addWidget(self.btnColorMap) hlayout.addWidget(self.btnCompute) hlayout.setSpacing(10) vlayout.addLayout(hlayout) vlayout.setAlignment(hlayout, Qt.AlignTop | Qt.AlignRight) vlayout.addItem(QSpacerItem(10, 10)) vlayout.addWidget(self.resultBox) vlayout.setAlignment(Qt.AlignHCenter) hlayout = QHBoxLayout() hlayout.addLayout(vlayout) hlayout.addWidget(gb, Qt.AlignHCenter) hlayout.setSpacing(10) mainLayout.addLayout(hlayout) self.setLayout(mainLayout) # template for text output self.template = '=== EWSD distribution between Ref (frame {}) and Test (frame {}) ===\n'\ 'Mean \t{:<30}\n' \ 'Variance \t{:<30}\n' \ 'Min \t{:<30}\n' \ 'Quartile 25 \t{:<30}\n' \ 'Median \t{:<30}\n' \ 'Quartile 75 \t{:<30}\n' \ 'Max \t{:<30}\n' def add_reference(self): self.timeSelection.initRef(self.input.ref_data.header.nb_frames) def add_test(self): self.timeSelection.initTest(self.input.test_data.header.nb_frames) def reset(self): self.ewsd = None self.xlim = None self.ylim = None self.has_map = False self.timeSelection.clearText() self.resultBox.clear() self.plotViewer.defaultPlot() self.plotViewer.current_title = 'Distribution of EWSD (element-wise signed deviation)' self.plotViewer.current_ylabel = 'Frequency' self.plotViewer.current_xlabel = 'EWSD' self.XLimitsAct.setEnabled(False) self.YLimitsAct.setEnabled(False) self.btnColorMap.setEnabled(False) def changeXlimits(self): value, ok = QInputDialog.getText(self, 'Change X limits', 'Enter the new X limits', text=', '.join(map(lambda x: '{:+f}'.format(x), self.plotViewer.canvas.axes.get_xlim()))) if not ok: return try: xmin, xmax = map(float, value.split(',')) except ValueError: QMessageBox.critical(self, 'Error', 'Invalid input.', QMessageBox.Ok) return self.xlim = xmin, xmax self.updateHistogram() self.has_map = False def changeYlimits(self): value, ok = QInputDialog.getText(self, 'Change Y limits', 'Enter the new Y limits', text=', '.join(map(lambda x: '{:+f}'.format(x), self.plotViewer.canvas.axes.get_ylim()))) if not ok: return try: self.ylim = tuple(map(float, value.split(','))) except ValueError: QMessageBox.critical(self, 'Error', 'Invalid input.', QMessageBox.Ok) return self.plotViewer.canvas.axes.set_ylim(self.ylim) self.plotViewer.canvas.draw() def updateStats(self, ref_time, test_time): ewsd = np.array(list(self.ewsd.values())) quantile25, median, quantile75 = np.percentile(ewsd, [25, 50, 75]) self.resultBox.appendPlainText(self.template.format(ref_time+1, test_time+1, np.mean(ewsd), np.var(ewsd, ddof=1), np.min(ewsd), quantile25, median, quantile75, np.max(ewsd))) def updateHistogram(self): ewsd = list(self.ewsd.values()) if self.xlim is not None: ewsd = list(filter(lambda x: self.xlim[0] <= x <= self.xlim[1], ewsd)) weights = np.ones_like(ewsd) / self.input.ref_mesh.nb_triangles_inside # make frequency histogram self.plotViewer.canvas.axes.clear() self.plotViewer.canvas.axes.grid(linestyle='dotted') self.plotViewer.canvas.axes.hist(ewsd, bins=settings.NB_BINS_EWSD, weights=weights, histtype='bar', color='g', edgecolor='k', alpha=0.5) self.plotViewer.canvas.axes.set_xlabel(self.plotViewer.current_xlabel) self.plotViewer.canvas.axes.set_ylabel(self.plotViewer.current_ylabel) self.plotViewer.canvas.axes.set_title(self.plotViewer.current_title) if self.ylim is not None: self.plotViewer.canvas.axes.set_ylim(self.ylim) self.plotViewer.canvas.draw() self.btnColorMap.setEnabled(True) self.XLimitsAct.setEnabled(True) self.YLimitsAct.setEnabled(True) def btnComputeEvent(self): self.xlim = None self.ylim = None self.has_map = False ref_time = int(self.timeSelection.refIndex.text()) - 1 test_time = int(self.timeSelection.testIndex.text()) - 1 selected_variable = self.input.varBox.currentText().split('(')[0][:-1] try: with Serafin.Read(self.input.ref_data.filename, self.input.ref_data.language) as input_stream: input_stream.header = self.input.ref_data.header input_stream.time = self.input.ref_data.time ref_values = input_stream.read_var_in_frame(ref_time, selected_variable) with Serafin.Read(self.input.test_data.filename, self.input.test_data.language) as input_stream: input_stream.header = self.input.test_data.header input_stream.time = self.input.test_data.time test_values = input_stream.read_var_in_frame(test_time, selected_variable) except (Serafin.SerafinRequestError, Serafin.SerafinValidationError) as e: QMessageBox.critical(None, 'Serafin Error', e.message, QMessageBox.Ok, QMessageBox.Ok) return values = test_values - ref_values self.ewsd = self.input.ref_mesh.element_wise_signed_deviation(values) self.updateStats(ref_time, test_time) self.updateHistogram() def btnColorMapEvent(self): if not self.has_map: reply = QMessageBox.question(self, 'Show distribution in 2D', 'This may take some time. Are you sure to proceed?', QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.No: return selected_variable = self.input.varBox.currentText().split('(')[0][:-1] self.map.canvas.reinitFigure(self.input.ref_mesh, self.ewsd, selected_variable, self.xlim, self.input.ref_mesh.polygon) self.has_map = True self.btnColorMap.setEnabled(False) self.map.show()
class MergeCellsChanger(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): vbox = QVBoxLayout() hbox_col_bar = QHBoxLayout() lb_col_count = QLabel('병합할 열 개수 ', self) self.sb_col_count = QSpinBox(self) self.textarea = QPlainTextEdit(self) hbox_btn_bar = QHBoxLayout() btn_make = QPushButton(self) btn_clear = QPushButton(self) #setting Layout Box hbox_col_bar.addWidget(lb_col_count) hbox_col_bar.addWidget(self.sb_col_count) hbox_btn_bar.addWidget(btn_make) hbox_btn_bar.addWidget(btn_clear) vbox.addLayout(hbox_col_bar) vbox.addWidget(self.textarea) vbox.addLayout(hbox_btn_bar) # setting widget attribute self.sb_col_count.setMinimum(1) self.textarea.setPlaceholderText('내용 붙여넣기') self.textarea.setPlainText("") btn_make.setText('생성하기') btn_make.clicked.connect(self.make_excel) btn_clear.setText('내용 지우기') btn_clear.clicked.connect(lambda clear: self.textarea.clear()) self.setLayout(vbox) self.setWindowTitle('QPushButton') self.center() self.show() # A 65 / a 97 def make_excel(self): merged_col = self.sb_col_count.value() text = self.textarea.toPlainText().strip().split('\n') row_count = self.textarea.document().lineCount() # 행 개수 if text[0] == "": # NULL QMessageBox.about(self, "오류", '내용을 입력하세요') else: # Not NULL start_col = 1 end_col = start_col + merged_col - 1 # 엑셀 사용 wb = openpyxl.Workbook() sheet = wb.active # 시트에 병합된 셀 동적 생성, 해당 셀에 값 넣기 for i in range(0, row_count): sheet.merge_cells(start_row=i + 1, start_column=start_col, end_row=i + 1, end_column=end_col) sheet.cell(row=i + 1, column=1).value = text[i].strip() folder_path = ".\\MCC_Folder\\" filename = folder_path + "MCC.xlsx" # .\\MCC_Folder\\MCC.xlsx tmp_filename = folder_path + "~$MCC.xlsx" if os.path.isdir(folder_path): # 경로에 폴더 있을 시 if os.path.isfile(tmp_filename): # 파일 실행중일 때(~$ 임시 파일이 있을 시) now = self.get_time() # 현재시간 filename = folder_path + "MCC_%s.xlsx" % now # 현재 시간으로 파일명 생성 else: # 경로에 폴더 없을 시 폴더 생성 os.mkdir(folder_path) wb.save(filename) QMessageBox.about(self, "성공", "파일이 생성되었습니다") # 파일 저장할때 날짜 형식 가져오는 함수 def get_time(self): now = time.strftime('%y%m%d_%H%M%S') return str(now) # gui 중앙 위치 def center(self): # geometry of the main window qr = self.frameGeometry() # center point of screen cp = QDesktopWidget().availableGeometry().center() # move rectangle's center point to screen's center point qr.moveCenter(cp) # top left of rectangle becomes top left of window centering it self.move(qr.topLeft())
class SubscriberWindow(QDialog): WINDOW_NAME_PREFIX = 'Subscriber' def __init__(self, parent, node, active_data_type_detector): super(SubscriberWindow, self).__init__(parent) self.setWindowTitle(self.WINDOW_NAME_PREFIX) self.setAttribute(Qt.WA_DeleteOnClose) # This is required to stop background timers! self._node = node self._active_data_type_detector = active_data_type_detector self._active_data_type_detector.message_types_updated.connect(self._update_data_type_list) self._message_queue = queue.Queue() self._subscriber_handle = None self._update_timer = QTimer(self) self._update_timer.setSingleShot(False) self._update_timer.timeout.connect(self._do_redraw) self._update_timer.start(100) self._log_viewer = QPlainTextEdit(self) self._log_viewer.setReadOnly(True) self._log_viewer.setLineWrapMode(QPlainTextEdit.NoWrap) self._log_viewer.setFont(get_monospace_font()) self._log_viewer.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) try: self._log_viewer.setPlaceholderText('Received messages will be printed here in YAML format') except AttributeError: # Old PyQt pass self._num_rows_spinbox = QSpinBox(self) self._num_rows_spinbox.setToolTip('Number of rows to display; large number will impair performance') self._num_rows_spinbox.valueChanged.connect( lambda: self._log_viewer.setMaximumBlockCount(self._num_rows_spinbox.value())) self._num_rows_spinbox.setMinimum(1) self._num_rows_spinbox.setMaximum(1000000) self._num_rows_spinbox.setValue(100) self._num_errors = 0 self._num_messages_total = 0 self._num_messages_past_filter = 0 self._msgs_per_sec_estimator = RateEstimator() self._num_messages_total_label = QuantityDisplay(self, 'Total', 'msgs') self._num_messages_past_filter_label = QuantityDisplay(self, 'Accepted', 'msgs') self._msgs_per_sec_label = QuantityDisplay(self, 'Accepting', 'msg/sec') self._type_selector = CommitableComboBoxWithHistory(self) self._type_selector.setToolTip('Name of the message type to subscribe to') self._type_selector.setInsertPolicy(QComboBox.NoInsert) completer = QCompleter(self._type_selector) completer.setCaseSensitivity(Qt.CaseSensitive) completer.setModel(self._type_selector.model()) self._type_selector.setCompleter(completer) self._type_selector.on_commit = self._do_start self._type_selector.setFont(get_monospace_font()) self._type_selector.setSizeAdjustPolicy(QComboBox.AdjustToContents) self._type_selector.setFocus(Qt.OtherFocusReason) self._active_filter = None self._filter_bar = FilterBar(self) self._filter_bar.on_filter = self._install_filter self._start_stop_button = make_icon_button('video-camera', 'Begin subscription', self, checkable=True, on_clicked=self._toggle_start_stop) self._pause_button = make_icon_button('pause', 'Pause updates, non-displayed messages will be queued in memory', self, checkable=True) self._clear_button = make_icon_button('trash-o', 'Clear output and reset stat counters', self, on_clicked=self._do_clear) self._show_all_message_types = make_icon_button('puzzle-piece', 'Show all known message types, not only those that are ' 'currently being exchanged over the bus', self, checkable=True, on_clicked=self._update_data_type_list) layout = QVBoxLayout(self) controls_layout = QHBoxLayout(self) controls_layout.addWidget(self._start_stop_button) controls_layout.addWidget(self._pause_button) controls_layout.addWidget(self._clear_button) controls_layout.addWidget(self._filter_bar.add_filter_button) controls_layout.addWidget(self._show_all_message_types) controls_layout.addWidget(self._type_selector, 1) controls_layout.addWidget(self._num_rows_spinbox) layout.addLayout(controls_layout) layout.addWidget(self._filter_bar) layout.addWidget(self._log_viewer, 1) stats_layout = QHBoxLayout(self) stats_layout.addWidget(self._num_messages_total_label) stats_layout.addWidget(self._num_messages_past_filter_label) stats_layout.addWidget(self._msgs_per_sec_label) layout.addLayout(stats_layout) self.setLayout(layout) # Initial updates self._update_data_type_list() def _install_filter(self, f): self._active_filter = f def _apply_filter(self, yaml_message): """This function will throw if the filter expression is malformed!""" if self._active_filter is None: return True return self._active_filter.match(yaml_message) def _on_message(self, e): # Global statistics self._num_messages_total += 1 # Rendering and filtering try: text = uavcan.to_yaml(e) if not self._apply_filter(text): return except Exception as ex: self._num_errors += 1 text = '!!! [%d] MESSAGE PROCESSING FAILED: %s' % (self._num_errors, ex) else: self._num_messages_past_filter += 1 self._msgs_per_sec_estimator.register_event(e.transfer.ts_monotonic) # Sending the text for later rendering try: self._message_queue.put_nowait(text) except queue.Full: pass def _toggle_start_stop(self): try: if self._subscriber_handle is None: self._do_start() else: self._do_stop() finally: self._start_stop_button.setChecked(self._subscriber_handle is not None) def _do_stop(self): if self._subscriber_handle is not None: self._subscriber_handle.remove() self._subscriber_handle = None self._pause_button.setChecked(False) self.setWindowTitle(self.WINDOW_NAME_PREFIX) def _do_start(self): self._do_stop() self._do_clear() try: selected_type = self._type_selector.currentText().strip() if not selected_type: return data_type = uavcan.TYPENAMES[selected_type] except Exception as ex: show_error('Subscription error', 'Could not load requested data type', ex, self) return try: self._subscriber_handle = self._node.add_handler(data_type, self._on_message) except Exception as ex: show_error('Subscription error', 'Could not create requested subscription', ex, self) return self.setWindowTitle('%s [%s]' % (self.WINDOW_NAME_PREFIX, selected_type)) self._start_stop_button.setChecked(True) def _do_redraw(self): self._num_messages_total_label.set(self._num_messages_total) self._num_messages_past_filter_label.set(self._num_messages_past_filter) estimated_rate = self._msgs_per_sec_estimator.get_rate_with_timestamp() self._msgs_per_sec_label.set('N/A' if estimated_rate is None else ('%.0f' % estimated_rate[0])) if self._pause_button.isChecked(): return self._log_viewer.setUpdatesEnabled(False) while True: try: text = self._message_queue.get_nowait() except queue.Empty: break else: self._log_viewer.appendPlainText(text + '\n') self._log_viewer.setUpdatesEnabled(True) def _update_data_type_list(self): logger.info('Updating data type list') if self._show_all_message_types.isChecked(): items = self._active_data_type_detector.get_names_of_all_message_types_with_data_type_id() else: items = self._active_data_type_detector.get_names_of_active_messages() self._type_selector.clear() self._type_selector.addItems(items) def _do_clear(self): self._num_messages_total = 0 self._num_messages_past_filter = 0 self._do_redraw() self._log_viewer.clear() def closeEvent(self, qcloseevent): try: self._subscriber_handle.close() except Exception: pass super(SubscriberWindow, self).closeEvent(qcloseevent) @staticmethod def spawn(parent, node, active_data_type_detector): SubscriberWindow(parent, node, active_data_type_detector).show()
class Dialog(QDialog): MESSAGE = "<p>Message boxes have a caption, a text, and up to three " \ "buttons, each with standard or custom texts.</p>" \ "<p>Click a button to close the message box. Pressing the Esc " \ "button will activate the detected escape button (if any).</p>" def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.openFilesPath = '' self.errorMessageDialog = QErrorMessage(self) frameStyle = QFrame.Sunken | QFrame.Panel self.issueLabel = QLabel() self.issueLabel.setFrameStyle(frameStyle) self.issueLabel = QLabel("Insert Issue id", self) self.issueText = QLineEdit() self.issueText = QLineEdit(self) self.openFileNameLabel = QLabel() self.openFileNameLabel.setFrameStyle(frameStyle) self.openFileNameButton = QPushButton("Browse File") self.newReqLabel = QLabel() self.newReqLabel.setFrameStyle(frameStyle) self.newReqLabel = QLabel("Insert Requirement", self) self.newReqText = QPlainTextEdit() self.newReqText.setFrameStyle(frameStyle) self.newReqText = QPlainTextEdit(self) self.addTable = QVBoxLayout() self.resultViewButton = QPushButton("View Result") self.addButton = QPushButton("Add") self.vizViewButton = QPushButton("View Visualizer") self.web = QWebEngineView() self.openFileNameButton.clicked.connect(self.setOpenFileName) self.resultViewButton.clicked.connect(self.setLabelResult) self.addButton.clicked.connect(self.storeResult) self.vizViewButton.clicked.connect(self.open_webbrowser) self.headline = QFont("Arial", 14, QFont.Bold) self.Issueidlabel = QLabel() self.Issueidlabel.setFrameStyle(frameStyle) self.Issueidlabel = QLabel("IssueID", self) self.Issueidlabel.setFont(self.headline) self.similaritylabel = QLabel() self.similaritylabel.setFrameStyle(frameStyle) self.similaritylabel = QLabel("Similarity", self) self.similaritylabel.setFont(self.headline) self.Requirementlabel = QLabel() self.Requirementlabel.setFrameStyle(frameStyle) self.Requirementlabel = QLabel("Requirement", self) self.Requirementlabel.setFont(self.headline) self.label1 = QLabel() self.label1.setFrameStyle(frameStyle) self.label1 = QLabel("", self) self.label2 = QLabel() self.label2.setFrameStyle(frameStyle) self.label2 = QLabel("", self) self.label3 = QLabel() self.label3.setFrameStyle(frameStyle) self.label3 = QLabel("", self) self.label4 = QLabel() self.label4.setFrameStyle(frameStyle) self.label4 = QLabel("", self) self.label5 = QLabel() self.label5.setFrameStyle(frameStyle) self.label5 = QLabel("", self) self.label6 = QLabel() self.label6.setFrameStyle(frameStyle) self.label6 = QLabel("", self) self.label7 = QLabel() self.label7.setFrameStyle(frameStyle) self.label7 = QLabel("", self) self.label8 = QLabel() self.label8.setFrameStyle(frameStyle) self.label8 = QLabel("", self) self.label9 = QLabel() self.label9.setFrameStyle(frameStyle) self.label9 = QLabel("", self) self.label10 = QLabel() self.label10.setFrameStyle(frameStyle) self.label10 = QLabel("", self) self.label11 = QLabel() self.label11.setFrameStyle(frameStyle) self.label11 = QLabel("", self) self.label12 = QLabel() self.label12.setFrameStyle(frameStyle) self.label12 = QLabel("", self) self.label13 = QLabel() self.label13.setFrameStyle(frameStyle) self.label13 = QLabel("", self) self.label14 = QLabel() self.label14.setFrameStyle(frameStyle) self.label14 = QLabel("", self) self.label15 = QLabel() self.label15.setFrameStyle(frameStyle) self.label15 = QLabel("", self) self.native = QCheckBox() self.native.setText("Use native file dialog.") self.native.setChecked(True) if sys.platform not in ("win32", "darwin"): self.native.hide() layout = QGridLayout() layout.setColumnStretch(1, 1) layout.setColumnMinimumWidth(1, 250) layout.addWidget(self.openFileNameButton, 6, 0) layout.addWidget(self.openFileNameLabel, 6, 1) layout.addWidget(self.issueLabel, 7, 0) layout.addWidget(self.issueText, 7, 1) layout.addWidget(self.web, 8, 1) layout.addWidget(self.newReqLabel, 9, 0) layout.addWidget(self.newReqText, 9, 1) layout.addWidget(self.resultViewButton, 11, 2) layout.addWidget(self.addButton, 11, 0) layout.addWidget(self.Issueidlabel, 15, 0) layout.addWidget(self.similaritylabel, 15, 1) layout.addWidget(self.Requirementlabel, 15, 2) layout.addWidget(self.label1, 16, 0) layout.addWidget(self.label2, 16, 1) layout.addWidget(self.label3, 16, 2) layout.addWidget(self.label4, 17, 0) layout.addWidget(self.label5, 17, 1) layout.addWidget(self.label6, 17, 2) layout.addWidget(self.label7, 18, 0) layout.addWidget(self.label8, 18, 1) layout.addWidget(self.label9, 18, 2) layout.addWidget(self.label10, 19, 0) layout.addWidget(self.label11, 19, 1) layout.addWidget(self.label12, 19, 2) layout.addWidget(self.label13, 20, 0) layout.addWidget(self.label14, 20, 1) layout.addWidget(self.label15, 20, 2) layout.addWidget(self.vizViewButton, 25, 0) width = 1000 # setting the fixed width of window self.setFixedWidth(width) self.setLayout(layout) self.setWindowTitle("Change Impact Analysis") def initUI(self): self.createTable() # Add box layout, add table to box layout and add box layout to widget self.layout = QVBoxLayout() self.layout.addWidget(self.tableWidget) self.setLayout(self.layout) # Show widget self.show() def setExistingDirectory(self): options = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly directory = QFileDialog.getExistingDirectory( self, "QFileDialog.getExistingDirectory()", self.directoryLabel.text(), options=options) if directory: self.directoryLabel.setText(directory) def setOpenFileName(self): options = QFileDialog.Options() if not self.native.isChecked(): options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", self.openFileNameLabel.text(), "All Files (*);;Text Files (*.txt)", options=options) if fileName: self.openFileNameLabel.setText(fileName) def storeResult(self): issueid = self.issueText.text() reqtext = self.newReqText.toPlainText() temp_filename = "temp.csv" pr.append(issueid, reqtext, temp_filename) self.issueText.clear() self.newReqText.clear() def setLabelResult(self): add = self.storeResult temp_filename = "temp.csv" df = pd.read_csv(temp_filename) for index, row in df.iterrows(): print(row["Issue_key"], row["Requirement"]) issueid = row["Issue_key"] reqtext = row["Requirement"] filename = self.openFileNameLabel.text() ending = filename.split('.')[-1] if ending == "csv": df = pd.read_csv(filename) df.to_csv(filename, index=False) # pr.append(issueid, reqtext, filename) file_uploaded = filename if not os.path.exists('docx'): os.makedirs('docx') if not os.path.exists('txt'): os.makedirs('txt') if not os.path.exists('candidates'): os.makedirs('candidates') path = "docx/" pr.csvToDocx(filename) pr.convertDocxToText(path) filenames = os.listdir('./txt') pr.docToVec(filenames) cia_model = "sl_doc2vec.model" pr.vecToCsv(cia_model) result1 = pr.similarDocs(cia_model, reqtext) model_test = "clustering_model2.pkl" vecs = "vecs.csv" txt_folder = "txt/" candidates_fld = 'candidates/' result2 = pr.cluster(model_test, filename, vecs, txt_folder, candidates_fld, reqtext) pr.append(issueid, reqtext, filename) tableValues1 = [] tableValues2 = [] for i in result2[0]: tableValues1.append(result2[1][i[0]]) tableValues2.append(str(i[1])) print("successfully finished!") filename = file_uploaded df = pd.read_csv(str(filename)) content = [] for f in df['Issue_key'].values: for i in tableValues1: if i in df['Issue_key'].values: content.append(df.loc[df['Issue_key'] == i, 'Requirement']) from string import digits res = ''.join(filter(lambda x: not x.isdigit(), content[0])) self.label3.setText(res) self.label3.adjustSize() self.label3.setWordWrap(True) res2 = ''.join(filter(lambda x: not x.isdigit(), content[1])) self.label6.setText(res2) self.label6.adjustSize() self.label6.setWordWrap(True) res3 = ''.join(filter(lambda x: not x.isdigit(), content[2])) self.label9.setText(res3) self.label9.setWordWrap(True) res4 = ''.join(filter(lambda x: not x.isdigit(), content[3])) self.label12.setText(res4) self.label12.setWordWrap(True) res5 = ''.join(filter(lambda x: not x.isdigit(), content[4])) self.label15.setText(res5) self.label15.setWordWrap(True) self.label1.setText(tableValues1[0]) self.label2.setText(tableValues2[0]) self.label4.setText(tableValues1[1]) self.label5.setText(tableValues2[1]) self.label7.setText(tableValues1[2]) self.label8.setText(tableValues2[2]) self.label10.setText(tableValues1[3]) self.label11.setText(tableValues2[3]) self.label13.setText(tableValues1[4]) self.label14.setText(tableValues2[4]) fig = go.Figure(data=[ go.Table(columnorder=[1, 2, 3], columnwidth=[80, 80, 400], header=dict(values=[['<b>IssueId</b><br>'], ['<b>Similarity</b>'], ['<b>Requirement</b>']], line_color='darkslategray', fill_color='royalblue', align=['left', 'center'], font=dict(color='white', size=12), height=40)) ]) else: print("Problem detected with uploaded file") os.remove('temp.csv') def createTable(self): # Create table self.tableWidget = QTableWidget() self.tableWidget.setRowCount(4) self.tableWidget.setColumnCount(2) self.tableWidget.setItem(0, 0, QTableWidgetItem("Cell (1,1)")) self.tableWidget.setItem(0, 1, QTableWidgetItem("Cell (1,2)")) self.tableWidget.setItem(1, 0, QTableWidgetItem("Cell (2,1)")) self.tableWidget.setItem(1, 1, QTableWidgetItem("Cell (2,2)")) self.tableWidget.setItem(2, 0, QTableWidgetItem("Cell (3,1)")) self.tableWidget.setItem(2, 1, QTableWidgetItem("Cell (3,2)")) self.tableWidget.setItem(3, 0, QTableWidgetItem("Cell (4,1)")) self.tableWidget.setItem(3, 1, QTableWidgetItem("Cell (4,2)")) self.tableWidget.move(55, 70) # table selection change self.tableWidget.doubleClicked.connect(self.on_click) def open_webbrowser(self): webbrowser.open( 'http://projector.tensorflow.org/?config=https://raw.githubusercontent.com/Bitseat/embeddings_projector/master/req_plot_config.json' ) #btn.clicked.connect(open_webbrowser) @pyqtSlot() def on_click(self): print("\n") for currentQTableWidgetItem in self.tableWidget.selectedItems(): print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text())
class ExampleWindow(QMainWindow): def __init__(self): super().__init__() self.title = 'Proyecto Paradigmas' self.initUI() def initUI(self): QMainWindow.__init__(self) self.setMinimumSize(QSize(1310, 800)) self.setWindowTitle("Proyecto Paradigmas") # Add text field self.b = QPlainTextEdit(self) self.b.insertPlainText("Definiciones y Reglas\n") self.b.move(10, 30) self.b.resize(900, 360) self.b.setStyleSheet("""QPlainTextEdit {background-color: #333; color: #00FF00; font-size: 20px; font-family: Courier;}""") self.c = QPlainTextEdit(self) self.c.insertPlainText("Pruebas y Testeo.\n") self.c.move(10, 400) self.c.resize(640, 390) self.c.setStyleSheet("""QPlainTextEdit {background-color: #333; color: #00FF00; font-size: 20px; font-family: Courier;}""") self.d = QPlainTextEdit(self) self.d.insertPlainText("Resultado de la ejecución.\n") self.d.move(660, 400) self.d.resize(640, 390) self.d.setReadOnly(True) self.d.setStyleSheet("""QPlainTextEdit {background-color: #333; color: #00FF00; font-size: 20px; font-family: Courier;}""") #Menu bar mainMenu = self.menuBar() fileMenu = mainMenu.addMenu('Archivo') ejecutar = mainMenu.addMenu('Ejecutar') helpMenu = mainMenu.addMenu('Help') abrir = QAction(QIcon('exit24.png'), 'Abrir TXT', self) abrir.triggered.connect(self.leerArchivo) fileMenu.addAction(abrir) abrir2 = QAction(QIcon('exit24.png'), 'Abrir XML', self) abrir2.triggered.connect(self.leerArchivo2) fileMenu.addAction(abrir2) guardar = QAction(QIcon('exit24.png'), 'Guardar TXT', self) guardar.triggered.connect(self.guardarArchivo) fileMenu.addAction(guardar) guardar2 = QAction(QIcon('exit24.png'), 'Guardar XML', self) guardar2.triggered.connect(self.guardarArchivo2) fileMenu.addAction(guardar2) cargar = QAction(QIcon('exit24.png'), 'Cargar Hileras', self) cargar.triggered.connect(self.cargarHileras) fileMenu.addAction(cargar) exitButton = QAction(QIcon('exit24.png'), 'Exit', self) exitButton.setShortcut('Ctrl+Q') exitButton.setStatusTip('Exit application') exitButton.triggered.connect(self.close) fileMenu.addAction(exitButton) paso = QAction(QIcon('exit24.png'), 'Paso a Paso', self) ejecutar.addAction(paso) correr = QAction(QIcon('exit24.png'), 'Correr', self) ejecutar.addAction(correr) button = QPushButton('α', self) button.setToolTip('Este es el botón de alpha') button.move(910, 30) button.resize(190, 50) button.clicked.connect(self.on_click) button2 = QPushButton('β', self) button2.setToolTip('Este es el botón de beta') button2.move(1110, 30) button2.resize(190, 50) button2.clicked.connect(self.on_click2) button3 = QPushButton('γ', self) button3.setToolTip('Este es el botón de gamma') button3.move(910, 80) button3.resize(190, 50) button3.clicked.connect(self.on_click3) button4 = QPushButton('δ', self) button4.setToolTip('Este es el botón de delta') button4.move(1110, 80) button4.resize(190, 50) button4.clicked.connect(self.on_click4) button5 = QPushButton('ε', self) button5.setToolTip('Este es el botón de epsilon') button5.move(910, 130) button5.resize(190, 50) button5.clicked.connect(self.on_click5) button6 = QPushButton('ζ', self) button6.setToolTip('Este es el botón de dzeta') button6.move(1110, 130) button6.resize(190, 50) button6.clicked.connect(self.on_click6) button7 = QPushButton('η', self) button7.setToolTip('Este es el botón de eta') button7.move(910, 180) button7.resize(190, 50) button7.clicked.connect(self.on_click7) button8 = QPushButton('θ', self) button8.setToolTip('Este es el botón de theta') button8.move(1110, 180) button8.resize(190, 50) button8.clicked.connect(self.on_click8) button9 = QPushButton('λ', self) button9.setToolTip('Este es el botón de lambda') button9.move(910, 230) button9.resize(190, 50) button9.clicked.connect(self.on_click9) button10 = QPushButton('μ', self) button10.setToolTip('Este es el botón de mi') button10.move(1110, 230) button10.resize(190, 50) button10.clicked.connect(self.on_click10) button11 = QPushButton('ξ', self) button11.setToolTip('Este es el botón de xi') button11.move(910, 280) button11.resize(190, 50) button11.clicked.connect(self.on_click11) button12 = QPushButton('π', self) button12.setToolTip('Este es el botón de pi') button12.move(1110, 280) button12.resize(190, 50) button12.clicked.connect(self.on_click12) button13 = QPushButton('φ', self) button13.setToolTip('Este es el botón de phi') button13.move(910, 330) button13.resize(190, 60) button13.clicked.connect(self.on_click13) button14 = QPushButton('Ω', self) button14.setToolTip('Este es el botón de omega') button14.move(1110, 330) button14.resize(190, 60) button14.clicked.connect(self.on_click14) stl = """QPushButton { background-color: #333; border-width: 2px; border-color: #00FF00; color: #00FF00; font-size: 30px; font-family: Courier; border-style: solid; }""" QApplication.instance().setStyleSheet(stl) self.show() @pyqtSlot() def on_click(self): print('Botón de alpha') self.b.insertPlainText('α') @pyqtSlot() def on_click2(self): print('Botón de beta') self.b.insertPlainText('β') @pyqtSlot() def on_click3(self): print('Botón de gamma') self.b.insertPlainText('γ') @pyqtSlot() def on_click4(self): print('Botón de delta') self.b.insertPlainText('δ') @pyqtSlot() def on_click5(self): print('Botón de epsilon') self.b.insertPlainText('ε') @pyqtSlot() def on_click6(self): print('Botón de dzeta') self.b.insertPlainText('ζ') @pyqtSlot() def on_click7(self): print('Botón de eta') self.b.insertPlainText('η') @pyqtSlot() def on_click8(self): print('Botón de theta') self.b.insertPlainText('θ') @pyqtSlot() def on_click9(self): print('Botón de lambda') self.b.insertPlainText('λ') @pyqtSlot() def on_click10(self): print('Botón de mi') self.b.insertPlainText('μ') @pyqtSlot() def on_click11(self): print('Botón de xi') self.b.insertPlainText('ξ') @pyqtSlot() def on_click12(self): print('Botón de pi') self.b.insertPlainText('π') @pyqtSlot() def on_click13(self): print('Botón de phi') self.b.insertPlainText('φ') @pyqtSlot() def on_click14(self): print('Botón de omega') self.b.insertPlainText('Ω') def guardarArchivo(self): print('Guardando TXT') texto = self.b.toPlainText() direccion = self.saveFileDialog() if (not (direccion is 'nulo')): direccion = direccion + '.txt' f = open(direccion, 'w') f.write(texto) f.close() else: print('El usuario canceló la operación') def guardarArchivo2(self): print('Guardando XML') texto = self.b.toPlainText() direccion = self.saveFileDialog() if (not (direccion is 'nulo')): root = ET.Element("root") doc = ET.SubElement(root, "doc") nodo1 = ET.SubElement(doc, "nodo1", name="nodo") nodo1.text = texto arbol = ET.ElementTree(root) direccion = direccion + '.xml' arbol.write(direccion) else: print('El usuario canceló la operación') def leerArchivo(self): print('Leyendo TXT') direccion = self.openFileNameDialogTXT() if (not (direccion is 'nulo')): f = open(direccion, 'r') mensaje = f.read() self.b.clear() self.b.insertPlainText(mensaje) f.close() else: print('El usuario canceló la operación') def leerArchivo2(self): print('Leyendo XML') direccion = self.openFileNameDialogXML() if (not (direccion is 'nulo')): mydoc = minidom.parse(direccion) items = mydoc.getElementsByTagName('nodo1') print('Item 1 attribute:') print(items[0].attributes['name'].value) print(items[0].firstChild.data) self.b.clear() mensaje = items[0].firstChild.data self.b.insertPlainText(mensaje) else: print('El usuario canceló la operación') def cargarHileras(self): print('Cargando Hileras') direccion = self.openFileNameDialogTXT() if (not (direccion is 'nulo')): f = open(direccion, 'r') mensaje = f.read() self.c.clear() self.c.insertPlainText(mensaje) f.close() else: print('El usuario canceló la operación') def openFileNameDialogTXT(self): textoAuxiliar = 'nulo' options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "Text Files (*.txt)", options=options) if fileName: #print(fileName) textoAuxiliar = fileName print(textoAuxiliar) return textoAuxiliar def openFileNameDialogXML(self): textoAuxiliar = 'nulo' options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "XML Files (*.xml)", options=options) if fileName: #print(fileName) textoAuxiliar = fileName print(textoAuxiliar) return textoAuxiliar def saveFileDialog(self): textoAuxiliar = 'nulo' options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getSaveFileName( self, "QFileDialog.getSaveFileName()", "", "All Files (*);;Text Files (*.txt)", options=options) if fileName: #print(fileName) textoAuxiliar = fileName print(textoAuxiliar) return textoAuxiliar
class MigrationWidget(QWidget): def __init__(self): super(MigrationWidget, self).__init__() self._migration = {} vbox = QVBoxLayout(self) lbl_title = QLabel(_translate("MigrationWidget", "Current code:")) self.current_list = QListWidget() lbl_suggestion = QLabel(_translate("MigrationWidget", "Suggested changes:")) self.suggestion = QPlainTextEdit() self.suggestion.setReadOnly(True) self.btn_apply = QPushButton(_translate("MigrationWidget", "Apply change!")) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(self.btn_apply) vbox.addWidget(lbl_title) vbox.addWidget(self.current_list) vbox.addWidget(lbl_suggestion) vbox.addWidget(self.suggestion) vbox.addLayout(hbox) self.current_list.itemClicked['QListWidgetItem*'].connect(self.load_suggestion) self.btn_apply.clicked['bool'].connect(self.apply_changes) def apply_changes(self): lineno = int(self.current_list.currentItem().data(Qt.UserRole)) lines = self._migration.migration_data[lineno][0].split('\n') remove = -1 code = '' for line in lines: if line.startswith('-'): remove += 1 elif line.startswith('+'): code += '%s\n' % line[1:] editorWidget = main_container.MainContainer().get_actual_editor() block_start = editorWidget.document().findBlockByLineNumber(lineno) block_end = editorWidget.document().findBlockByLineNumber( lineno + remove) cursor = editorWidget.textCursor() cursor.setPosition(block_start.position()) cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor) cursor.insertText(code[:-1]) def load_suggestion(self, item): lineno = int(item.data(Qt.UserRole)) lines = self._migration.migration_data[lineno][0].split('\n') code = '' for line in lines: if line.startswith('+'): code += '%s\n' % line[1:] self.suggestion.setPlainText(code) editorWidget = main_container.MainContainer().get_actual_editor() if editorWidget: editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, migration): self._migration = migration self.current_list.clear() base_lineno = -1 for lineno in sorted(migration.migration_data.keys()): linenostr = 'L%s\n' % str(lineno + 1) data = migration.migration_data[lineno] lines = data[0].split('\n') if base_lineno == data[1]: continue base_lineno = data[1] message = '' for line in lines: if line.startswith('-'): message += '%s\n' % line item = QListWidgetItem(linenostr + message) item.setToolTip(linenostr + message) item.setData(Qt.UserRole, lineno) self.current_list.addItem(item) def clear(self): """ Clear the widget """ self.current_list.clear() self.suggestion.clear()
class Summarizer(QWidget): # Declaring def __init__(self): super().__init__() self.layout = None self.label = None self.input_text = None self.summarize_button = None self.output_text = None self.init_ui() # initializing UI def init_ui(self): # Main window self.setGeometry(800, 800, 800, 800) self.setWindowTitle('Text Summarizer') self.layout = QVBoxLayout() # Input text box self.input_text = QPlainTextEdit() self.input_text.insertPlainText("Enter your text here...") self.input_text.resize(50, 50) self.layout.addWidget(self.input_text) # Push Button self.summarize_button = QPushButton("Summarize") self.layout.addWidget(self.summarize_button) # Text Output self.output_text = QPlainTextEdit() self.output_text.insertPlainText("Summarized text...") self.output_text.setReadOnly(True) self.output_text.resize(50, 50) self.layout.addWidget(self.output_text) self.setLayout(self.layout) self.summarize_button.clicked.connect(self.summarize) # Show UI def run(self): self.show() # Summarizer def summarize(self): txt = self.input_text.toPlainText() print(txt) parser = None # Testing summarizer and checking for errors try: parser = PlaintextParser.from_string(txt, Tokenizer("english")) print("summarizing") summarizer = LexRankSummarizer() print("summarizing") summary = summarizer(parser.document, 4) self.output_text.clear() for sentence in summary: print(sentence) self.output_text.insertPlainText(str(sentence)) except Exception as err: print("ERROR: " + str(err)) finally: print("finally")
class App(QWidget): USs = [] # { F# , name , description , Acceptance Criteria } USNames = [] # user stories names TCs = [] # { TC name , TC description } def __init__(self): super().__init__() self.title = 'NLP project.' self.left = 50 self.top = 50 self.width = 1500 self.height = 800 self.initUI() def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) app.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True) # Create Label label = QLabel('Select User Story by name:', self) label.move(50, 0) # Create Label label2 = QLabel('US Description + Acceptance Criteria:', self) label2.move(50, 125) # Create Label label3 = QLabel('Choose Algorithm:', self) label3.move(50, 600) # Create Label label4 = QLabel('Results:', self) label4.move(1000, 50) # Create textbox user story self.textbox = QPlainTextEdit(self) self.textbox.move(50, 175) self.textbox.resize(500, 300) """ # Create textbox results self.textbox3 = QLineEdit(self) self.textbox3.move(1000, 75) self.textbox3.resize(400,600) self.textbox3.setDisabled(True) """ self.tableWidget = QTableWidget() #self.tableWidget.resize(400,600) # Create textbox tokenize self.textbox4 = QLineEdit(self) self.textbox4.move(50, 700) self.textbox4.resize(280, 40) #self.textbox4.setDisabled(True) """ self.scrollArea = QScrollArea(self) self.scrollArea.setWidgetResizable(True) self.scrollArea.move(50,400) self.scrollArea.resize(280,40) self.scrollArea.setWidget(self.textbox4) """ button = QPushButton('Start', self) button.move(150, 750) button.clicked.connect(self.on_click_start) button2 = QPushButton('Tokenize', self) button2.move(50, 625) button2.clicked.connect(self.on_click_tokenize) button3 = QPushButton('Load excel', self) button3.move(50, 750) button3.clicked.connect(self.on_click_load) button4 = QPushButton('Choose US', self) button4.move(550, 29) button4.clicked.connect(self.on_click_choose_US) button5 = QPushButton('Choose AC', self) button5.move(550, 149) button5.clicked.connect(self.on_click_choose_AC) button6 = QPushButton('Clear', self) button6.move(250, 750) button6.clicked.connect(self.on_click_clear) # algorithm combobox self.comboBox = QComboBox(self) algorithms = ['cosine', 'other'] self.comboBox.addItems(algorithms) self.comboBox.move(150, 625) # US combobox self.comboBox2 = QComboBox(self) self.comboBox2.move(50, 25) self.comboBox2.resize(500, 20) #action_relect = lambda: self.on_click_reselect_us(self) self.comboBox2.currentIndexChanged.connect(self.on_click_reselect_us) # AC combobox self.comboBox3 = QComboBox(self) self.comboBox3.move(50, 150) self.comboBox3.resize(500, 20) self.show() @pyqtSlot() def on_click_reselect_us(self): self.textbox.clear() self.comboBox3.clear() @pyqtSlot() def on_click_clear(self): self.textbox.clear() self.textbox3.clear() self.textbox4.clear() self.comboBox.clear() self.comboBox2.clear() self.comboBox3.clear() @pyqtSlot() def on_click_start(self): us = self.textbox2.text() results = [] for tc in self.TCs: tmp = tc[0] + tc[1] results.append({ 'match_sentence': tmp, 'score': compare_sens(us, tmp) }) i = 0 self.tableWidget.setSortingEnabled(True) self.tableWidget.setRowCount(100) self.tableWidget.setColumnCount(2) results = sorted(results, key=itemgetter('score'), reverse=True) for res in results: #self.tableWidget.insertRow(str(res)+str1) #self.tableWidget.setItem(i,0, QTableWidgetItem(str(res[1]))) self.tableWidget.setItem(i, 0, QTableWidgetItem(str(res))) i += 1 #self.textbox3.insert(str(res)+str1 self.tableWidget.move(1000, 75) self.tableWidget.show() @pyqtSlot() def on_click_choose_US(self): # set User Story over textbox so we can edit if needed text = self.comboBox2.currentText() self.textbox.setPlainText(text) self.textbox.show() # fill AC combobox descriptions = [] ACs = [] tmp = [] us = self.comboBox2.currentText() for a, b, c, d in self.USs: if b == us: descriptions.append(c) ACs.append(d) tmp.append(c + d) self.comboBox3.addItems(tmp) @pyqtSlot() def on_click_choose_AC(self): # set AC over textbox so we can edit if needed text = self.comboBox3.currentText() self.textbox.paste() self.textbox.show() @pyqtSlot() def on_click_tokenize(self): text = self.textbox.text() tok = str(tokenize(text)) self.textbox4.setText(tok) @pyqtSlot() def on_click_load(self): # Assign spreadsheet filename to `file` file = self.openFileNameDialog() # Load in the workbook wb = load_workbook(file) # Get sheet names data_sheets_names = wb.sheetnames print(wb.sheetnames) # Get all the sheet names that hold User stories and Test Cases USs_sheets_names = [] TCs_Sheets_names = [] for sheet_name in data_sheets_names: if sheet_name.find("TCs") != -1: TCs_Sheets_names.append(sheet_name) if sheet_name.find(" F") != -1: USs_sheets_names.append(sheet_name) # get NLP data sheets for name in USs_sheets_names: sheet = wb[name] for i in range(2, sheet.max_row + 1): self.USs.append( ((sheet.cell(i, 1).value), (sheet.cell(i, 2).value), (sheet.cell(i, 3).value), (sheet.cell(i, 4).value))) self.USNames.append((sheet.cell(2, 2).value)) for name in TCs_Sheets_names: sheet = wb[name] for i in range(2, sheet.max_row + 1): self.TCs.append( (name, (sheet.cell(i, 1).value), (sheet.cell(i, 2).value))) #remove doubles self.USNames = list(set(self.USNames)) self.comboBox2.addItems(self.USNames) print(self.USNames) def openFileNameDialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "All Files (*);;Excel Files (*.xlsx)", options=options) if fileName: print(fileName) return fileName
class ComputeErrorsTab(QWidget): def __init__(self, inputTab): super().__init__() self.input = inputTab self.timeSelection = DoubleTimeSelection() self.btnCompute = QPushButton('Compute', icon=self.style().standardIcon(QStyle.SP_DialogApplyButton)) self.btnCompute.setFixedSize(105, 50) self.resultTextBox = QPlainTextEdit() self.btnCompute.clicked.connect(self.btnComputeEvent) mainLayout = QVBoxLayout() mainLayout.addItem(QSpacerItem(10, 10)) mainLayout.addWidget(self.timeSelection) mainLayout.addItem(QSpacerItem(10, 10)) hlayout = QHBoxLayout() hlayout.addWidget(self.btnCompute) hlayout.setAlignment(self.btnCompute, Qt.AlignTop) hlayout.setAlignment(Qt.AlignHCenter) vlayout = QVBoxLayout() vlayout.addWidget(self.resultTextBox) hlayout.addItem(QSpacerItem(10, 1)) hlayout.addLayout(vlayout) mainLayout.addLayout(hlayout) self.setLayout(mainLayout) self.template = '=== Comparison between Ref (frame {}) and Test (frame {}) ===\n'\ 'MSD (Mean signed deviation) \t{:<30}\n' \ 'MAD (Mean absolute deviation) \t{:<30}\n' \ 'RMSD (Root mean square deviation) \t{:<30}\n' def add_reference(self): self.timeSelection.initRef(self.input.ref_data.header.nb_frames) def add_test(self): self.timeSelection.initTest(self.input.test_data.header.nb_frames) def reset(self): self.timeSelection.clearText() self.resultTextBox.clear() def btnComputeEvent(self): ref_time = int(self.timeSelection.refIndex.text()) - 1 test_time = int(self.timeSelection.testIndex.text()) - 1 selected_variable = self.input.varBox.currentText().split('(')[0][:-1] try: with Serafin.Read(self.input.ref_data.filename, self.input.ref_data.language) as input_stream: input_stream.header = self.input.ref_data.header input_stream.time = self.input.ref_data.time ref_values = input_stream.read_var_in_frame(ref_time, selected_variable) with Serafin.Read(self.input.test_data.filename, self.input.test_data.language) as input_stream: input_stream.header = self.input.test_data.header input_stream.time = self.input.test_data.time test_values = input_stream.read_var_in_frame(test_time, selected_variable) except (Serafin.SerafinRequestError, Serafin.SerafinValidationError) as e: QMessageBox.critical(None, 'Serafin Error', e.message, QMessageBox.Ok, QMessageBox.Ok) return values = test_values - ref_values msd = self.input.ref_mesh.mean_signed_deviation(values) mad = self.input.ref_mesh.mean_absolute_deviation(values) rmsd = self.input.ref_mesh.root_mean_square_deviation(values) self.resultTextBox.appendPlainText(self.template.format(ref_time+1, test_time+1, msd, mad, rmsd))
class PluginDialog(AppletDialog): aboutToClose = pyqtSignal() messageToTeletext = pyqtSignal(str) switchLed = pyqtSignal(str, str) # __________________________________________________________________ def __init__(self, title, icon, logger): super().__init__(title, icon, logger) # always on top sometimes doesn't work self.setAttribute(Qt.WA_AlwaysStackOnTop) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint | Qt.WindowStaysOnTopHint) # __________________________________________________________________ def _buildUi(self): self._clues = {} self._selectionComboBox = None self.loadLanguage() self.loadClueAlbum('clue-album.ini') if self._clues: self._selectionComboBox = QComboBox() self._selectionComboBox.addItem(self.tr("Load clue..."), None) for k in self._clues: clue = self._clues[k] self._selectionComboBox.addItem(clue.title, k) self._options = {} if os.path.isfile('definitions.ini'): definitions = QSettings('definitions.ini', QSettings.IniFormat) for group in definitions.childGroups(): definitions.beginGroup(group) if group == "options": for key in definitions.childKeys(): self._options[key] = definitions.value(key) definitions.endGroup() main_layout = QVBoxLayout() main_layout.setSpacing(12) self._led = LedWidget(self.tr("Raspberry Teletext"), QSize(40, 20)) self._led.setRedAsBold(True) self._led.setRedAsRed(True) self._led.switchOn('gray') settings_button = QPushButton() settings_button.setIcon(QIcon("./settings.svg")) settings_button.setFlat(True) settings_button.setToolTip(self.tr("Effects and language")) settings_button.setIconSize(QSize(16, 16)) settings_button.setFixedSize(QSize(24, 24)) header_layout = QHBoxLayout() header_layout.addWidget(self._led) header_layout.addWidget(settings_button, Qt.AlignRight) main_layout.addLayout(header_layout) stop_button = QPushButton() stop_button.setIcon(QIcon("./cancel.svg")) stop_button.setFlat(True) stop_button.setToolTip(self.tr("Clear TV screen")) stop_button.setIconSize(QSize(16, 16)) stop_button.setFixedSize(QSize(24, 24)) if 'tv-screen-width' in self._options and 'tv-screen-height' in self._options: hint = QSize(int(self._options['tv-screen-width']), int(self._options['tv-screen-height'])) # self._tvScreen = TvScreenLabel(self.tr("<div align=center>Display on TV</div>"), hint) self._tvScreen = TvScreenLabel('', hint) policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) else: # self._tvScreen = TvScreenLabel(self.tr("<div align=center>Display on TV</div>")) self._tvScreen = TvScreenLabel('') policy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) policy.setHeightForWidth(True) self._tvScreen.setSizePolicy(policy) display_layout = QHBoxLayout() display_layout.addWidget(self._tvScreen) display_layout.addStretch() display_layout.addWidget(stop_button, Qt.AlignRight) main_layout.addLayout(display_layout) if self._selectionComboBox: main_layout.addWidget(self._selectionComboBox) self._editor = QPlainTextEdit() self._editor.setFrameShape(QFrame.NoFrame) self._editor.setCursorWidth(8) main_layout.addWidget(self._editor) clear_button = QPushButton(self.tr("Erase draft")) clear_button.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) send_button = QPushButton(self.tr("Display on TV")) send_button.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed) button_layout = QHBoxLayout() button_layout.addWidget(send_button) button_layout.addWidget(clear_button) main_layout.addLayout(button_layout) self.setLayout(main_layout) settings_button.pressed.connect(self.settings) stop_button.pressed.connect(self.stop) clear_button.pressed.connect(self.erase) send_button.pressed.connect(self.send) self.switchLed.connect(self._led.switchOn) if self._selectionComboBox: self._selectionComboBox.activated.connect(self.selectClue) self._editor.setFocusPolicy(Qt.StrongFocus) self._editor.setFocus(Qt.OtherFocusReason) # __________________________________________________________________ @pyqtSlot(str) def onTeletextDisplayMessage(self, message): if message == "-": message = "" message = message.replace('\n', '<br>') self._tvScreen.setText('<div style="text-align:center">' + message + '</div>') # __________________________________________________________________ @pyqtSlot(str) def onPropsMessage(self, message): if message.startswith("DISCONNECTED"): self._tvScreen.setText("") self._led.switchOn('yellow') else: if self._led.color() != 'green': self._led.switchOn('green') # __________________________________________________________________ def closeEvent(self, e): self.aboutToClose.emit() # __________________________________________________________________ @pyqtSlot() def erase(self): self._selectionComboBox.setCurrentIndex(0) self._editor.clear() # __________________________________________________________________ def loadClueAlbum(self, filename): # keys with ',' are read as list and will be joined back if os.path.isfile(filename): album = QSettings(filename, QSettings.IniFormat) album.setIniCodec("UTF-8"); for group in album.childGroups(): album.beginGroup(group) key = group if not 'fr' in album.childKeys(): self._logger.warning( "{} [{}] : {}".format(self.tr("Clue"), group, self.tr("ignored because 'fr' is missing"))) continue if not 'en' in album.childKeys(): self._logger.warning( "{} [{}] : {}".format(self.tr("Clue"), group, self.tr("ignored because 'en' is missing"))) continue try: title = album.value('en') if '|' in title: en = re.compile(r'\s*\|\s*').split(title) else: en = (title, '') text = album.value('fr') if '|' in text: fr = re.compile(r'\s*\|\s*').split(text) else: fr = (text, '') self._clues[key] = Clue(title, fr, en) except: self._logger.warning("{} {}".format(self.tr("Failed to load clue : "), key)) album.endGroup() # __________________________________________________________________ @pyqtSlot() def loadLanguage(self): settings = QSettings("settings.ini", QSettings.IniFormat); settings.setIniCodec("UTF-8"); settings.beginGroup("Cues") self._language = settings.value("language", "fr") settings.endGroup() if self._selectionComboBox: self.selectClue(self._selectionComboBox.currentIndex()) # __________________________________________________________________ @pyqtSlot('int') def selectClue(self, index): try: k = self._selectionComboBox.itemData(index) if k: self._editor.clear() clue = self._clues[k] if self._language == "fr": text1, text2 = clue.fr else: text1, text2 = clue.en if text2: self._editor.insertPlainText(text1 + '\n' + text2) else: self._editor.insertPlainText(text1) self._editor.setFocus(Qt.OtherFocusReason) except: self._logger.warning("{} {}".format(self.tr("Failed to select clue : index"), index)) # __________________________________________________________________ @pyqtSlot() def send(self): message = self._editor.toPlainText().strip() if len(message): self.messageToTeletext.emit("display:" + message) self._selectionComboBox.setCurrentIndex(0) self._editor.clear() # __________________________________________________________________ @pyqtSlot(str) def setLanguage(self, lang): self._logger.info(self.tr("Request received : language in ") + lang) if lang in ["en", "fr"]: self._language = lang settings = QSettings("settings.ini", QSettings.IniFormat); settings.setIniCodec("UTF-8"); settings.beginGroup("Cues") settings.setValue("language", self._language) settings.endGroup() settings.sync() if self._selectionComboBox: self.selectClue(self._selectionComboBox.currentIndex()) # __________________________________________________________________ @pyqtSlot() def settings(self): dlg = PluginSettingsDialog(self._logger) dlg.setModal(True) dlg.move(self.pos() + QPoint(20, 20)) dlg.languageChanged.connect(self.loadLanguage) dlg.messageToTeletext.connect(self.messageToTeletext) dlg.exec() # __________________________________________________________________ @pyqtSlot() def stop(self): self.messageToTeletext.emit("erase")
class BSSTab(QWidget): def __init__(self, inputTab): super().__init__() self.input = inputTab self.timeSelection = DoubleTimeSelection() self.initSelection = SimpleTimeSelection('Initial state index') # set up a custom plot viewer self.has_figure = False self.plotViewer = PlotViewer() self.plotViewer.exitAct.setEnabled(False) self.plotViewer.menuBar.setVisible(False) self.plotViewer.toolBar.addAction(self.plotViewer.xLabelAct) self.plotViewer.toolBar.addSeparator() self.plotViewer.toolBar.addAction(self.plotViewer.yLabelAct) self.plotViewer.toolBar.addSeparator() self.plotViewer.toolBar.addAction(self.plotViewer.titleAct) self.plotViewer.canvas.figure.canvas.mpl_connect('motion_notify_event', self.plotViewer.mouseMove) self.initSelection.refIndex.textChanged.connect(self.reinitFigure) self.timeSelection.refIndex.textChanged.connect(self.reinitFigure) self.btnEvolution = QPushButton('BSS evolution', icon=self.style().standardIcon(QStyle.SP_DialogApplyButton)) self.btnEvolution.setFixedSize(105, 50) self.btnCompute = QPushButton('Compute', icon=self.style().standardIcon(QStyle.SP_DialogApplyButton)) self.btnCompute.setFixedSize(105, 50) self.resultTextBox = QPlainTextEdit() self.btnCompute.clicked.connect(self.btnComputeEvent) self.btnEvolution.clicked.connect(self.btnEvolutionEvent) mainLayout = QVBoxLayout() mainLayout.addItem(QSpacerItem(10, 10)) mainLayout.addWidget(self.timeSelection) mainLayout.addWidget(self.initSelection) mainLayout.addItem(QSpacerItem(10, 10)) hlayout = QHBoxLayout() hlayout.addWidget(self.btnEvolution) hlayout.addWidget(self.btnCompute) hlayout.setAlignment(self.btnEvolution, Qt.AlignTop) hlayout.setAlignment(self.btnCompute, Qt.AlignTop) hlayout.setAlignment(Qt.AlignHCenter) vlayout = QVBoxLayout() vlayout.addWidget(self.resultTextBox) hlayout.addItem(QSpacerItem(10, 1)) hlayout.addLayout(vlayout) mainLayout.addLayout(hlayout) self.setLayout(mainLayout) self.template = '===\nComparison between Ref (frame {}) and Test (frame {})\n' \ 'with respect to Init (frame {})\n===\n' \ 'BSS\t{:<30}\n' def add_reference(self): self.timeSelection.initRef(self.input.ref_data.header.nb_frames) def add_test(self): self.timeSelection.initTest(self.input.test_data.header.nb_frames) self.initSelection.initRef(self.input.test_data.header.nb_frames) def reset(self): self.timeSelection.clearText() self.resultTextBox.clear() self.has_figure = False self.plotViewer.defaultPlot() self.plotViewer.current_title = 'Evolution of BSS' self.plotViewer.current_ylabel = 'BSS' self.plotViewer.current_xlabel = 'Time (second)' def reinitFigure(self): self.has_figure = False def btnEvolutionEvent(self): if not self.has_figure: all_bss = [] ref_time = int(self.timeSelection.refIndex.text()) - 1 init_time = int(self.initSelection.refIndex.text()) - 1 selected_variable = self.input.varBox.currentText().split('(')[0][:-1] try: with Serafin.Read(self.input.ref_data.filename, self.input.ref_data.language) as input_stream: input_stream.header = self.input.ref_data.header input_stream.time = self.input.ref_data.time ref_values = input_stream.read_var_in_frame(ref_time, selected_variable) with Serafin.Read(self.input.test_data.filename, self.input.test_data.language) as input_stream: input_stream.header = self.input.test_data.header input_stream.time = self.input.test_data.time init_values = input_stream.read_var_in_frame(init_time, selected_variable) ref_volume = self.input.ref_mesh.quadratic_volume(ref_values - init_values) for index in range(len(self.input.test_data.time)): test_values = input_stream.read_var_in_frame(index, selected_variable) test_volume = self.input.ref_mesh.quadratic_volume(test_values - ref_values) if test_volume == 0 and ref_volume == 0: bss = 1 else: with np.errstate(divide='ignore'): bss = 1 - test_volume / ref_volume all_bss.append(bss) except (Serafin.SerafinRequestError, Serafin.SerafinValidationError) as e: QMessageBox.critical(None, 'Serafin Error', e.message, QMessageBox.Ok, QMessageBox.Ok) return self.plotViewer.plot(self.input.test_data.time, all_bss) self.plotViewer.show() def btnComputeEvent(self): ref_time = int(self.timeSelection.refIndex.text()) - 1 test_time = int(self.timeSelection.testIndex.text()) - 1 init_time = int(self.initSelection.refIndex.text()) - 1 selected_variable = self.input.varBox.currentText().split('(')[0][:-1] try: with Serafin.Read(self.input.ref_data.filename, self.input.ref_data.language) as input_stream: input_stream.header = self.input.ref_data.header input_stream.time = self.input.ref_data.time ref_values = input_stream.read_var_in_frame(ref_time, selected_variable) with Serafin.Read(self.input.test_data.filename, self.input.test_data.language) as input_stream: input_stream.header = self.input.test_data.header input_stream.time = self.input.test_data.time test_values = input_stream.read_var_in_frame(test_time, selected_variable) init_values = input_stream.read_var_in_frame(init_time, selected_variable) except (Serafin.SerafinRequestError, Serafin.SerafinValidationError) as e: QMessageBox.critical(None, 'Serafin Error', e.message, QMessageBox.Ok, QMessageBox.Ok) return test_volume = self.input.ref_mesh.quadratic_volume(test_values - ref_values) ref_volume = self.input.ref_mesh.quadratic_volume(ref_values - init_values) if test_volume == 0 and ref_volume == 0: bss = 1 else: with np.errstate(divide='ignore'): bss = 1 - test_volume / ref_volume self.resultTextBox.appendPlainText(self.template.format(ref_time+1, test_time+1, init_time+1, bss))
class Form(QWidget): def __init__(self, title=''): super().__init__() self.title = title self.initUI() def initUI(self): # Layouts self.main_layout = QVBoxLayout() self.h_layout = QHBoxLayout() self.form = QFormLayout() # Widgets font = QFont() font.setBold(True) font.setPointSize(12) font_o = QFont() font_o.setBold(True) font_o.setPointSize(10) self.name = QLabel(self.title) self.name.setFont(font) self.output = QPlainTextEdit() self.output.setReadOnly(True) self.output.setFont(font_o) self.run = QPushButton('Run Algorithm') self.clear = QPushButton('Clear') self.run.setMinimumSize(100, 30) self.clear.setMinimumSize(100, 30) self.generate_fields() # Setup main layout self.main_layout.addWidget(self.name) self.main_layout.addLayout(self.form) self.main_layout.addWidget(self.output) self.main_layout.addLayout(self.h_layout) # Setup h layout self.h_layout.addStretch() self.h_layout.addWidget(self.clear) self.h_layout.addWidget(self.run) self.setLayout(self.main_layout) # Conecting button. self.run.clicked.connect(self.run_algorithm) self.clear.clicked.connect(self.clear_output) self.show() def generate_fields(self): raise NotImplementedError def run_algorithm(self): raise NotImplementedError def clear_output(self): self.output.clear() def print_results(self, values, t_time): self.output.appendPlainText('Results:') self.print_values(values) self.output.appendPlainText('Time: {}'.format(t_time)) self.output.appendPlainText('') def print_results_p(self, bests, t_time): self.output.appendPlainText('Results:') for i, best in bests.items(): self.output.appendPlainText('Thread: {}'.format(i)) self.print_values(best.get_values()) self.output.appendPlainText('Time: {}'.format(t_time)) self.output.appendPlainText('') def print_values(self, values): self.output.appendPlainText('R: {}'.format(values[0])) self.output.appendPlainText('L: {}'.format(values[1])) self.output.appendPlainText('J: {}'.format(values[2])) self.output.appendPlainText('Lam: {}'.format(values[3]))
class Ui_ProjectorEditForm(object): """ The :class:`~openlp.core.lib.ui.projector.editform.Ui_ProjectorEditForm` class defines the user interface for the ProjectorEditForm dialog. """ def setupUi(self, edit_projector_dialog): """ Create the interface layout. """ edit_projector_dialog.setObjectName('edit_projector_dialog') edit_projector_dialog.setWindowIcon( build_icon(u':/icon/openlp-logo-32x32.png')) edit_projector_dialog.setMinimumWidth(400) edit_projector_dialog.setModal(True) # Define the basic layout self.dialog_layout = QGridLayout(edit_projector_dialog) self.dialog_layout.setObjectName('dialog_layout') self.dialog_layout.setSpacing(8) self.dialog_layout.setContentsMargins(8, 8, 8, 8) # IP Address self.ip_label = QLabel(edit_projector_dialog) self.ip_label.setObjectName('projector_edit_ip_label') self.ip_text = QLineEdit(edit_projector_dialog) self.ip_text.setObjectName('projector_edit_ip_text') self.dialog_layout.addWidget(self.ip_label, 0, 0) self.dialog_layout.addWidget(self.ip_text, 0, 1) # Port number self.port_label = QLabel(edit_projector_dialog) self.port_label.setObjectName('projector_edit_ip_label') self.port_text = QLineEdit(edit_projector_dialog) self.port_text.setObjectName('projector_edit_port_text') self.dialog_layout.addWidget(self.port_label, 1, 0) self.dialog_layout.addWidget(self.port_text, 1, 1) # PIN self.pin_label = QLabel(edit_projector_dialog) self.pin_label.setObjectName('projector_edit_pin_label') self.pin_text = QLineEdit(edit_projector_dialog) self.pin_label.setObjectName('projector_edit_pin_text') self.dialog_layout.addWidget(self.pin_label, 2, 0) self.dialog_layout.addWidget(self.pin_text, 2, 1) # Name self.name_label = QLabel(edit_projector_dialog) self.name_label.setObjectName('projector_edit_name_label') self.name_text = QLineEdit(edit_projector_dialog) self.name_text.setObjectName('projector_edit_name_text') self.dialog_layout.addWidget(self.name_label, 3, 0) self.dialog_layout.addWidget(self.name_text, 3, 1) # Location self.location_label = QLabel(edit_projector_dialog) self.location_label.setObjectName('projector_edit_location_label') self.location_text = QLineEdit(edit_projector_dialog) self.location_text.setObjectName('projector_edit_location_text') self.dialog_layout.addWidget(self.location_label, 4, 0) self.dialog_layout.addWidget(self.location_text, 4, 1) # Notes self.notes_label = QLabel(edit_projector_dialog) self.notes_label.setObjectName('projector_edit_notes_label') self.notes_text = QPlainTextEdit(edit_projector_dialog) self.notes_text.setObjectName('projector_edit_notes_text') self.dialog_layout.addWidget(self.notes_label, 5, 0, alignment=QtCore.Qt.AlignTop) self.dialog_layout.addWidget(self.notes_text, 5, 1) # Time for the buttons self.button_box = QDialogButtonBox(QDialogButtonBox.Help | QDialogButtonBox.Save | QDialogButtonBox.Cancel) self.dialog_layout.addWidget(self.button_box, 8, 0, 1, 2) def retranslateUi(self, edit_projector_dialog): if self.new_projector: title = translate('OpenLP.ProjectorEditForm', 'Add New Projector') self.projector.port = PJLINK_PORT else: title = translate('OpenLP.ProjectorEditForm', 'Edit Projector') edit_projector_dialog.setWindowTitle(title) self.ip_label.setText( translate('OpenLP.ProjectorEditForm', 'IP Address')) self.ip_text.setText(self.projector.ip) self.ip_text.setFocus() self.port_label.setText( translate('OpenLP.ProjectorEditForm', 'Port Number')) self.port_text.setText(str(self.projector.port)) self.pin_label.setText(translate('OpenLP.ProjectorEditForm', 'PIN')) self.pin_text.setText(self.projector.pin) self.name_label.setText(translate('OpenLP.ProjectorEditForm', 'Name')) self.name_text.setText(self.projector.name) self.location_label.setText( translate('OpenLP.ProjectorEditForm', 'Location')) self.location_text.setText(self.projector.location) self.notes_label.setText(translate('OpenLP.ProjectorEditForm', 'Notes')) self.notes_text.clear() self.notes_text.insertPlainText(self.projector.notes)
class MainWindow(QWidget): def __init__(self): super().__init__() self.running = False self.setWindowTitle('PySwicher v{}'.format(VERSION)) # Logging config self.log_textbox = QPlainTextEditLogger(self) logging.getLogger().addHandler(self.log_textbox) self.log_textbox.setFormatter(logging.Formatter('[%(asctime)s][%(levelname)s]: %(message)s')) self.log_textbox.setLevel(self.get_numeric_loglevel(options['log_level'])) self.log_to_file = False # System tray configuration self.tray_menu = QMenu(self) self.systemTrayIcon = QSystemTrayIcon() self.systemTrayIcon.setVisible(False) self.systemTrayIcon.setIcon(QtGui.QIcon('C:\\Users\\Admin\\Pictures\\tray_stop.jpg')) self.systemTrayIcon.activated.connect(self.sys_tray) self.exit_action = self.tray_menu.addAction('Exit') self.exit_action.triggered.connect(self.exit_app) self.systemTrayIcon.setContextMenu(self.tray_menu) self.click_tray_timer = QtCore.QTimer(self) # Fix for systemtray click trigger self.click_tray_timer.setSingleShot(True) self.click_tray_timer.timeout.connect(self.click_timeout) self.main_window_ui() self.starter() def set_log_to_file(self, state): logger = logging.getLogger(__name__) file = logging.FileHandler(HOME + '\\switcher.log') if state == QtCore.Qt.Checked: self.log_to_file = True file.setFormatter( logging.Formatter('%(filename)s[LINE:%(lineno)d]# %(levelname)-8s [%(asctime)s] %(message)s')) file.setLevel(self.get_numeric_loglevel(options['log_level'])) logger.addHandler(file) else: if 'file' in logger.handlers: logger.removeHandler(file) self.log_to_file = False def starter(self): if not self.running: self.running = True self.start_btn.setText('Stop switcher') self.systemTrayIcon.setIcon(QtGui.QIcon('C:\\Users\\Admin\\Pictures\\tray_stop.jpg')) start_app() elif self.running: self.running = False self.start_btn.setText('Start switcher') self.systemTrayIcon.setIcon(QtGui.QIcon('C:\\Users\\Admin\\Pictures\\tray_start.jpg')) stop_app() return def main_window_ui(self): grid = QGridLayout(self) self.setLayout(grid) grid.setSpacing(5) # Here goes options layout self.topleft = QFrame(self) self.topleft.setFrameShape(QFrame.StyledPanel) self.topleft_grid = QGridLayout(self) self.topleft.setLayout(self.topleft_grid) self.switch_comb_label = QLabel('Switch combination:') self.switch_comb_text = QLineEdit() self.switch_comb_text.setText(options['switch_combination']) self.hotkey_label = QLabel('Hotkey:') self.hotkey_comb_text = QLineEdit() self.hotkey_comb_text.setText(options['hotkey']) self.topleft_grid.addWidget(self.switch_comb_label, 0, 0) self.topleft_grid.addWidget(self.switch_comb_text, 1, 0) self.topleft_grid.addWidget(self.hotkey_label, 2, 0) self.topleft_grid.addWidget(self.hotkey_comb_text, 3, 0) grid.addWidget(self.topleft, 0, 0) self.topright = QFrame(self) self.topright.setFrameShape(QFrame.StyledPanel) self.topright_grid = QGridLayout(self) self.topright.setLayout(self.topright_grid) self.info_label = QLabel('===INFO===') self.info_label.setAlignment(QtCore.Qt.AlignHCenter) self.info_author = QLabel('Author: Kurashov Sergey') self.info_author.setAlignment(QtCore.Qt.AlignHCenter) self.info_contacts = QLabel('Contacts: [email protected]') self.info_contacts.setAlignment(QtCore.Qt.AlignHCenter) self.info_sourcecode = QLabel('<a href="https://github.com/shimielder/win_switcher">Sourcecode on GitHub</a>') self.info_sourcecode.setAlignment(QtCore.Qt.AlignHCenter) self.info_sourcecode.setOpenExternalLinks(True) self.topright_grid.addWidget(self.info_label, 0, 0) self.topright_grid.addWidget(self.info_author, 1, 0) self.topright_grid.addWidget(self.info_contacts, 2, 0) self.topright_grid.addWidget(self.info_sourcecode, 3, 0) grid.addWidget(self.topright, 0, 1) self.middle = QFrame(self) self.middle.setFrameShape(QFrame.StyledPanel) self.middle_grid = QGridLayout(self) self.middle.setLayout(self.middle_grid) self.dictionsries_label = QLabel('Dictionaries to switch:') self.dict_one = QPlainTextEdit() self.dict_one.clear() self.dict_one.appendPlainText(options['layouts'][0]) self.dict_two = QPlainTextEdit() self.dict_two.clear() self.dict_two.appendPlainText(options['layouts'][1]) self.middle_grid.addWidget(self.dictionsries_label, 0, 0, 1, 4) self.middle_grid.addWidget(self.dict_one, 1, 0, 1, 4) self.middle_grid.addWidget(self.dict_two, 2, 0, 1, 4) grid.addWidget(self.middle, 1, 0, 1, 2) self.bottom = QFrame(self) self.bottom.setFrameShape(QFrame.StyledPanel) self.bottom_grid = QGridLayout(self) self.bottom.setLayout(self.bottom_grid) self.loglevel_label = QLabel('Logging level:') self.loglevel_dropmenu = QComboBox(self) self.loglevel_dropmenu.addItems(LOGGING_LEVELS) self.loglevel_dropmenu.setCurrentIndex(LOGGING_LEVELS.index((options['log_level'].upper()))) self.loglevel_dropmenu.activated[str].connect(self.set_logginglevel) # self.log_to_file_label = QLabel('Check to save logs to file') self.log_to_file_chk = QCheckBox('Check to save logs to file') self.log_to_file_chk.stateChanged.connect(self.set_log_to_file) self.logging_output_label = QLabel('Logging output:') self.logging_output_label.setAlignment(QtCore.Qt.AlignHCenter) self.bottom_grid.addWidget(self.loglevel_label, 0, 0) self.bottom_grid.addWidget(self.loglevel_dropmenu, 0, 1) self.bottom_grid.addWidget(self.log_to_file_chk, 0, 3, 1, 1) self.bottom_grid.addWidget(self.logging_output_label, 1, 0, 1, 4) self.bottom_grid.addWidget(self.log_textbox.widget, 2, 0, 2, 4) grid.addWidget(self.bottom, 2, 0, 1, 2) self.bottom_buttons = QFrame(self) # self.bottom_buttons.setFrameShape(QFrame.StyledPanel) self.bottom_buttons_grid = QGridLayout(self) self.bottom_buttons.setLayout(self.bottom_buttons_grid) self.start_btn = QPushButton('Start switcher') self.start_btn.clicked.connect(self.starter) self.apply_btn = QPushButton('Apply changes') self.apply_btn.clicked.connect(self.apply) self.exit_btn = QPushButton('Exit app') self.exit_btn.clicked.connect(self.exit_app) self.bottom_buttons_grid.addWidget(self.start_btn, 0, 0) self.bottom_buttons_grid.addWidget(self.apply_btn, 0, 1) self.bottom_buttons_grid.addWidget(self.exit_btn, 0, 2) grid.addWidget(self.bottom_buttons, 3, 0, 1, 2) self.resize(480, 320) self.show() def get_numeric_loglevel(self, loglevel): numeric_level = getattr(logging, loglevel.upper(), None) if not isinstance(numeric_level, int): numeric_level = 0 return numeric_level def set_logginglevel(self, loglevel): return self.log_textbox.setLevel(self.get_numeric_loglevel(loglevel)) @QtCore.pyqtSlot(QSystemTrayIcon.ActivationReason) def sys_tray(self, reason): """ По-умолчанию, trigger срабатывает всегда. Для обхода этого я повесил таймер на событие. Взято отсюда: https://riverbankcomputing.com/pipermail/pyqt/2010-November/028394.html """ if reason == QSystemTrayIcon.Trigger: self.click_tray_timer.start(QApplication.doubleClickInterval()) elif reason == QSystemTrayIcon.DoubleClick: self.click_tray_timer.stop() if self.isHidden(): self.showNormal() self.systemTrayIcon.setVisible(False) def click_timeout(self): self.starter() def apply(self): self.starter() options['layouts'] = [] options['layouts'].append(self.dict_one.toPlainText()) options['layouts'].append(self.dict_two.toPlainText()) options['log_level'] = LOGGING_LEVELS[self.loglevel_dropmenu.currentIndex()] self.set_logginglevel(options['log_level']) options['switch_combination'] = self.switch_comb_text.text() options['hotkey'] = self.hotkey_comb_text.text() logging.debug('Options from GUI: {}'.format(options)) save_to(options) self.starter() return options def exit_app(self): if self.running: self.starter() self.systemTrayIcon.setVisible(False) self.destroy() def closeEvent(self, event): self.exit_app() def changeEvent(self, event): if event.type() == QtCore.QEvent.WindowStateChange: if self.windowState() & QtCore.Qt.WindowMinimized: event.ignore() self.hide() self.systemTrayIcon.setVisible(True) self.systemTrayIcon.showMessage('', 'Running in the background.') super(MainWindow, self).changeEvent(event)
class MultipleLinearRegression(QMainWindow): #::---------------------- # Implementation of Multiple Linear regression using the bike share dataset # the methods in this class are # _init_ : initialize the class # initUi : creates the canvas and all the elements in the canvas # update : populates the elements of the canvas base on the parametes # chosen by the user #::---------------------- send_fig = pyqtSignal(str) def __init__(self): super(MultipleLinearRegression, self).__init__() self.Title ="Multiple Linear Regression" self.initUi() def initUi(self): #::----------------------------------------------------------------- # Create the canvas and all the element to create a dashboard with # all the necessary elements to present the results from the algorithm # The canvas is divided using a grid layout to facilitate the drawing # of the elements #::----------------------------------------------------------------- self.setWindowTitle(self.Title) self.setStyleSheet(font_size_window) self.main_widget = QWidget(self) self.layout = QGridLayout(self.main_widget) self.groupBox1 = QGroupBox('Independent Variables') self.groupBox1Layout = QGridLayout() self.groupBox1.setLayout(self.groupBox1Layout) # Create check boxes for each feature self.feature0 = QCheckBox(features_list[0], self) self.feature1 = QCheckBox(features_list[1], self) self.feature2 = QCheckBox(features_list[2], self) self.feature3 = QCheckBox(features_list[3], self) self.feature4 = QCheckBox(features_list[4], self) self.feature5 = QCheckBox(features_list[5], self) self.feature6 = QCheckBox(features_list[6], self) self.feature7 = QCheckBox(features_list[7], self) self.feature8 = QCheckBox(features_list[8], self) self.feature9 = QCheckBox(features_list[9], self) self.feature10 = QCheckBox(features_list[10], self) self.feature0.setChecked(True) self.feature1.setChecked(False) self.feature2.setChecked(True) self.feature3.setChecked(True) self.feature4.setChecked(True) self.feature5.setChecked(True) self.feature6.setChecked(True) self.feature7.setChecked(True) self.feature8.setChecked(True) self.feature9.setChecked(True) self.feature10.setChecked(True) self.btnExecute = QPushButton("Run Regression") self.btnExecute.clicked.connect(self.update) self.groupBox1Layout.addWidget(self.feature0, 0, 0) self.groupBox1Layout.addWidget(self.feature1, 0, 1) self.groupBox1Layout.addWidget(self.feature2, 0, 2) self.groupBox1Layout.addWidget(self.feature3, 0, 3) self.groupBox1Layout.addWidget(self.feature4, 1, 0) self.groupBox1Layout.addWidget(self.feature5, 1, 1) self.groupBox1Layout.addWidget(self.feature6, 1, 2) self.groupBox1Layout.addWidget(self.feature7, 1, 3) self.groupBox1Layout.addWidget(self.feature8, 2, 0) self.groupBox1Layout.addWidget(self.feature9, 2, 1) self.groupBox1Layout.addWidget(self.feature10, 2, 2) self.groupBox1Layout.addWidget(self.btnExecute, 3, 1) self.groupBox3 = QGroupBox('') self.groupBox3Layout = QGridLayout() self.groupBox3.setLayout(self.groupBox3Layout) self.groupBox4 = QGroupBox('Parameters of the Model') self.groupBox4Layout = QGridLayout() self.groupBox4.setLayout(self.groupBox4Layout) self.groupBox2 = QGroupBox('Results from the model') self.groupBox2Layout = QVBoxLayout() self.groupBox2.setLayout(self.groupBox2Layout) self.lblInt = QLabel('Intercept:') self.txtInt = QLineEdit() self.lblR2 = QLabel('R2:') self.txtR2 = QLineEdit() self.lblMSE = QLabel('Mean Squared Error:') self.txtMSE = QLineEdit() self.lblRMSE = QLabel('RMSE:') self.txtRMSE = QLineEdit() self.lblParam = QLabel("Coefficients:") self.lblParam.adjustSize() self.txtParam = QPlainTextEdit() self.groupBox2Layout.addWidget(self.lblInt) self.groupBox2Layout.addWidget(self.txtInt) self.groupBox2Layout.addWidget(self.lblR2) self.groupBox2Layout.addWidget(self.txtR2) self.groupBox2Layout.addWidget(self.lblMSE) self.groupBox2Layout.addWidget(self.txtMSE) self.groupBox2Layout.addWidget(self.lblRMSE) self.groupBox2Layout.addWidget(self.txtRMSE) self.groupBox4Layout.addWidget(self.lblParam) self.groupBox4Layout.addWidget(self.txtParam) self.layout.addWidget(self.groupBox1, 0, 0) self.layout.addWidget(self.groupBox2, 1, 0) self.layout.addWidget(self.groupBox3, 0, 1) self.layout.addWidget(self.groupBox4, 1, 1) #::-------------------------------------- # Graphic 1 : Residuals #::-------------------------------------- self.fig = Figure() self.ax1 = self.fig.add_subplot(111) self.axes = [self.ax1] self.canvas = FigureCanvas(self.fig) self.canvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.canvas.updateGeometry() self.groupBoxG3 = QGroupBox('Residuals Plot') self.groupBoxG3Layout = QVBoxLayout() self.groupBoxG3.setLayout(self.groupBoxG3Layout) self.groupBoxG3Layout.addWidget(self.canvas) self.layout.addWidget(self.groupBoxG3,0,1) self.setCentralWidget(self.main_widget) self.resize(1100, 700) self.show() def update(self): #::------------------------------------------------------------ # Populates the elements in the canvas using the values # chosen as parameters for the multiple linear regression #::------------------------------------------------------------ self.ax1.clear() self.txtParam.clear() self.Y = london_bikes['count'] self.X = pd.DataFrame() if self.feature0.isChecked(): self.X[features_list[0]] = london_bikes[features_list[0]] if self.feature1.isChecked(): self.X[features_list[1]] = london_bikes[features_list[1]] if self.feature2.isChecked(): self.X[features_list[2]] = london_bikes[features_list[2]] if self.feature3.isChecked(): self.X[features_list[3]] = london_bikes[features_list[3]] if self.feature4.isChecked(): self.X[features_list[4]] = london_bikes[features_list[4]] if self.feature5.isChecked(): self.X[features_list[5]] = london_bikes[features_list[5]] if self.feature6.isChecked(): self.X[features_list[6]] = london_bikes[features_list[6]] if self.feature7.isChecked(): self.X[features_list[7]] = london_bikes[features_list[7]] if self.feature8.isChecked(): self.X[features_list[8]] = london_bikes[features_list[8]] if self.feature9.isChecked(): self.X[features_list[9]] = london_bikes[features_list[9]] if self.feature10.isChecked(): self.X[features_list[10]] = london_bikes[features_list[10]] # splitting X and y into training and testing sets self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(self.X, self.Y, test_size=0.4, random_state=1) # create linear regression object self.reg = linear_model.LinearRegression() # train the model using the training sets self.results = self.reg.fit(self.X_train, self.y_train) self.y_pred = self.reg.predict(self.X_test) # intercept self.Int = self.reg.intercept_ # regression coefficients self.coef = self.reg.coef_ # zip with features self.parameters = zip(self.X.columns, self.coef) # variance score: 1 means perfect prediction self.variance = self.reg.score(self.X_test, self.y_test) # R2 and Mean Squared Error self.R2 = r2_score(self.y_test, self.y_pred) # Priniting R2 Score self.MSE = mean_squared_error(self.y_test, self.y_pred) # RMSE self.RMSE = np.sqrt(self.MSE) self.txtInt.setText(str(self.Int)) self.txtR2.setText(str(self.R2)) self.txtMSE.setText(str(self.MSE)) self.txtRMSE.setText(str(self.RMSE)) self.txtParam.appendPlainText(str(list(self.parameters))) ### Plot residuals self.ax1.scatter(self.reg.predict(self.X_train), self.reg.predict(self.X_train) - self.y_train, color="green", s=10, label='Train data') ## plotting residual errors in test data self.ax1.scatter(self.reg.predict(self.X_test), self.reg.predict(self.X_test) - self.y_test, color="blue", s=10, label='Test data') ## plotting line for zero residual error self.ax1.hlines(y=0, xmin=0, xmax=10, linewidth=2) ## plotting line for zero residual error self.ax1.hlines(y=0, xmin=0, xmax=10, linewidth=2) ## plotting legend self.ax1.legend(loc='upper right') self.fig.tight_layout() self.fig.canvas.draw_idle()
class PreparePanel(QWidget, TaskManager): signal_status = pyqtSignal(object, object) signal_password_response = pyqtSignal(str, bool) def __init__(self, context: ApplicationContext, manager: SoftwareManager, screen_size: QSize, i18n: I18n, manage_window: QWidget): super(PreparePanel, self).__init__(flags=Qt.CustomizeWindowHint | Qt.WindowTitleHint) self.i18n = i18n self.context = context self.manage_window = manage_window self.setWindowTitle('{} ({})'.format( __app_name__, self.i18n['prepare_panel.title.start'].lower())) self.setMinimumWidth(screen_size.width() * 0.5) self.setMinimumHeight(screen_size.height() * 0.35) self.setMaximumHeight(screen_size.height() * 0.95) self.setLayout(QVBoxLayout()) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.manager = manager self.tasks = {} self.output = {} self.ntasks = 0 self.ftasks = 0 self.self_close = False self.prepare_thread = Prepare(self.context, manager, self.i18n) self.prepare_thread.signal_register.connect(self.register_task) self.prepare_thread.signal_update.connect(self.update_progress) self.prepare_thread.signal_finished.connect(self.finish_task) self.prepare_thread.signal_started.connect(self.start) self.prepare_thread.signal_ask_password.connect(self.ask_root_password) self.prepare_thread.signal_output.connect(self.update_output) self.signal_password_response.connect( self.prepare_thread.set_password_reply) self.check_thread = CheckFinished() self.signal_status.connect(self.check_thread.update) self.check_thread.signal_finished.connect(self.finish) self.skip_thread = EnableSkip() self.skip_thread.signal_timeout.connect(self._enable_skip_button) self.progress_thread = AnimateProgress() self.progress_thread.signal_change.connect(self._change_progress) self.label_top = QLabel() self.label_top.setCursor(QCursor(Qt.WaitCursor)) self.label_top.setText("{}...".format( self.i18n['prepare_panel.title.start'].capitalize())) self.label_top.setAlignment(Qt.AlignHCenter) self.label_top.setStyleSheet( "QLabel { font-size: 14px; font-weight: bold; }") self.layout().addWidget(self.label_top) self.layout().addWidget(QLabel()) self.table = QTableWidget() self.table.setCursor(QCursor(Qt.WaitCursor)) self.table.setStyleSheet( "QTableWidget { background-color: transparent; }") self.table.setFocusPolicy(Qt.NoFocus) self.table.setShowGrid(False) self.table.verticalHeader().setVisible(False) self.table.horizontalHeader().setVisible(False) self.table.horizontalHeader().setSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) self.table.setColumnCount(4) self.table.setHorizontalHeaderLabels(['' for _ in range(4)]) self.layout().addWidget(self.table) self.textarea_output = QPlainTextEdit(self) self.textarea_output.resize(self.table.size()) self.textarea_output.setStyleSheet("background: black; color: white;") self.layout().addWidget(self.textarea_output) self.textarea_output.setVisible(False) self.textarea_output.setReadOnly(True) self.textarea_output.setMaximumHeight(100) self.current_output_task = None self.bottom_widget = QWidget() self.bottom_widget.setLayout(QHBoxLayout()) self.bottom_widget.layout().addStretch() bt_hide_output = QPushButton(self.i18n['prepare.bt_hide_details']) bt_hide_output.setStyleSheet( 'QPushButton { text-decoration: underline; border: 0px; background: none } ' ) bt_hide_output.clicked.connect(self.hide_output) bt_hide_output.setCursor(QCursor(Qt.PointingHandCursor)) self.bottom_widget.layout().addWidget(bt_hide_output) self.bottom_widget.layout().addStretch() self.layout().addWidget(self.bottom_widget) self.bottom_widget.setVisible(False) self.bt_bar = QToolBar() self.bt_close = QPushButton(self.i18n['close'].capitalize()) self.bt_close.setCursor(QCursor(Qt.PointingHandCursor)) self.bt_close.clicked.connect(self.close) self.bt_close.setVisible(False) self.ref_bt_close = self.bt_bar.addWidget(self.bt_close) self.bt_bar.addWidget(new_spacer()) self.progress_bar = QProgressBar() self.progress_bar.setStyleSheet(styles.PROGRESS_BAR) self.progress_bar.setMaximumHeight(10 if QApplication.instance().style( ).objectName().lower() == 'windows' else 4) self.progress_bar.setTextVisible(False) self.progress_bar.setVisible(False) self.progress_bar.setCursor(QCursor(Qt.WaitCursor)) self.ref_progress_bar = self.bt_bar.addWidget(self.progress_bar) self.bt_bar.addWidget(new_spacer()) self.bt_skip = QPushButton( self.i18n['prepare_panel.bt_skip.label'].capitalize()) self.bt_skip.clicked.connect(self.finish) self.bt_skip.setEnabled(False) self.bt_skip.setCursor(QCursor(Qt.WaitCursor)) self.bt_bar.addWidget(self.bt_skip) self.layout().addWidget(self.bt_bar) def hide_output(self): self.current_output_task = None self.textarea_output.setVisible(False) self.textarea_output.clear() self.bottom_widget.setVisible(False) self._resize_columns() self.setFocus(Qt.NoFocusReason) if not self.bt_bar.isVisible(): self.bt_bar.setVisible(True) def ask_root_password(self): root_pwd, ok = root.ask_root_password(self.context, self.i18n) self.signal_password_response.emit(root_pwd, ok) def _enable_skip_button(self): self.bt_skip.setEnabled(True) self.bt_skip.setCursor(QCursor(Qt.PointingHandCursor)) def _change_progress(self, value: int): self.progress_bar.setValue(value) def get_table_width(self) -> int: return reduce(operator.add, [ self.table.columnWidth(i) for i in range(self.table.columnCount()) ]) def _resize_columns(self): header_horizontal = self.table.horizontalHeader() for i in range(self.table.columnCount()): header_horizontal.setSectionResizeMode( i, QHeaderView.ResizeToContents) self.resize(self.get_table_width() * 1.05, self.sizeHint().height()) def show(self): super(PreparePanel, self).show() self.prepare_thread.start() centralize(self) def start(self): self.ref_bt_close.setVisible(True) self.check_thread.start() self.skip_thread.start() self.ref_progress_bar.setVisible(True) self.progress_thread.start() def closeEvent(self, QCloseEvent): if not self.self_close: QCoreApplication.exit() def register_task(self, id_: str, label: str, icon_path: str): self.ntasks += 1 self.table.setRowCount(self.ntasks) task_row = self.ntasks - 1 icon_widget = QWidget() icon_widget.setLayout(QHBoxLayout()) icon_widget.layout().setContentsMargins(10, 0, 10, 0) bt_icon = QToolButton() bt_icon.setCursor(QCursor(Qt.WaitCursor)) bt_icon.setEnabled(False) bt_icon.setToolTip(self.i18n['prepare.bt_icon.no_output']) bt_icon.setFixedSize(QSize(24, 24)) bt_icon.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) if icon_path: bt_icon.setIcon(QIcon(icon_path)) def _show_output(): lines = self.output[id_] if lines: self.current_output_task = id_ self.textarea_output.clear() self.textarea_output.setVisible(True) for l in lines: self.textarea_output.appendPlainText(l) self.bottom_widget.setVisible(True) self.setFocus(Qt.NoFocusReason) if self.bt_bar.isVisible(): self.bt_bar.setVisible(False) bt_icon.clicked.connect(_show_output) icon_widget.layout().addWidget(bt_icon) self.table.setCellWidget(task_row, 0, icon_widget) lb_status = QLabel(label) lb_status.setCursor(Qt.WaitCursor) lb_status.setMinimumWidth(50) lb_status.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) lb_status.setStyleSheet("QLabel { font-weight: bold; }") self.table.setCellWidget(task_row, 1, lb_status) lb_sub = QLabel() lb_status.setCursor(Qt.WaitCursor) lb_sub.setContentsMargins(10, 0, 10, 0) lb_sub.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) lb_sub.setMinimumWidth(50) self.table.setCellWidget(task_row, 2, lb_sub) lb_progress = QLabel('{0:.2f}'.format(0) + '%') lb_progress.setCursor(Qt.WaitCursor) lb_progress.setContentsMargins(10, 0, 10, 0) lb_progress.setStyleSheet("QLabel { font-weight: bold; }") lb_progress.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.table.setCellWidget(task_row, 3, lb_progress) self.tasks[id_] = { 'bt_icon': bt_icon, 'lb_status': lb_status, 'lb_prog': lb_progress, 'progress': 0, 'lb_sub': lb_sub, 'finished': False } self.signal_status.emit(self.ntasks, self.ftasks) def update_progress(self, task_id: str, progress: float, substatus: str): task = self.tasks[task_id] if progress != task['progress']: task['progress'] = progress task['lb_prog'].setText('{0:.2f}'.format(progress) + '%') if substatus: task['lb_sub'].setText('( {} )'.format(substatus)) else: task['lb_sub'].setText('') self._resize_columns() def update_output(self, task_id: str, output: str): full_output = self.output.get(task_id) if full_output is None: full_output = [] self.output[task_id] = full_output task = self.tasks[task_id] task['bt_icon'].setEnabled(True) task['bt_icon'].setCursor(QCursor(Qt.PointingHandCursor)) task['bt_icon'].setToolTip(self.i18n['prepare.bt_icon.output']) full_output.append(output) if self.current_output_task == task_id: self.textarea_output.appendPlainText(output) def finish_task(self, task_id: str): task = self.tasks[task_id] task['lb_sub'].setText('') for key in ('lb_prog', 'lb_status'): task[key].setStyleSheet( 'QLabel { color: %s; text-decoration: line-through; }' % GREEN) task['finished'] = True self._resize_columns() self.ftasks += 1 self.signal_status.emit(self.ntasks, self.ftasks) if self.ntasks == self.ftasks: self.label_top.setText(self.i18n['ready'].capitalize()) def finish(self): if self.isVisible(): self.manage_window.begin_refresh_packages() self.manage_window.show() self.self_close = True self.close()