def createFormGroupBox(self, numbobbins, bobmax, bobmin, bobbinmax): """Create a form to set the new values of the BoB binning parameters""" self.formGroupBox = QGroupBox("Edit BoB Binning Settings") layout = QFormLayout() val_double = QDoubleValidator() val_double.setBottom(1) #set smalled double allowed in the form val_int = QIntValidator() val_int.setBottom(0) #set smalled int allowed in the form val_int.setTop(rch.pb_global_const.maxbobbins ) #set largest int allowed in the form self.e1 = QLineEdit() self.e1.setValidator(val_int) self.e1.setMaxLength(6) self.e1.setText("%d" % numbobbins) self.e2 = QLineEdit() self.e2.setValidator(val_double) self.e2.setText("%.2e" % bobmax) self.e3 = QLineEdit() self.e3.setValidator(val_double) self.e3.setText("%.2e" % bobmin) self.e4 = QLineEdit() self.e4.setValidator(val_int) self.e4.setMaxLength(6) self.e4.setText("%d" % bobbinmax) layout.addRow(QLabel("Number of bins for Bob:"), self.e1) layout.addRow(QLabel("Maximum bin Mw (g/mol):"), self.e2) layout.addRow(QLabel("Minimum bin Mw (g/mol):"), self.e3) layout.addRow(QLabel("Maximum no. of polymers per bin:"), self.e4) self.formGroupBox.setLayout(layout)
def _createValidator(self): validator = QIntValidator(self.parent) if "min" in self.config: validator.setBottom(int(self.config["min"])) if "max" in self.config: validator.setTop(int(self.config["max"])) return validator
def get_int_validator(min=None, max=None): validator = QIntValidator() if min is not None: validator.setBottom(min) if max is not None: validator.setTop(max) return validator
def __init__(self, parent, grid, title="Print settings"): self.shape = grid.model.shape row_validator = QIntValidator() row_validator.setBottom(0) # Do not allow negative values row_validator.setTop(self.shape[0] - 1) column_validator = QIntValidator() column_validator.setBottom(0) # Do not allow negative values column_validator.setTop(self.shape[1] - 1) if grid.selection and len(grid.selected_idx) > 1: (bb_top, bb_left), (bb_bottom, bb_right) = \ grid.selection.get_grid_bbox(self.shape) else: bb_top, bb_bottom = grid.rowAt(0), grid.rowAt(grid.height()) bb_left, bb_right = grid.columnAt(0), grid.columnAt(grid.width()) initial_values = bb_top, bb_left, bb_bottom, bb_right validators = [row_validator, column_validator] * 2 super().__init__(parent, title, self.labels, initial_values, self.groupbox_title, validators)
def createEditableBox(text, size=100, label='', layout=None, validator=None, bottom=None, top=None): box = QLineEdit(text) box.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) box.setMinimumWidth(size) if layout is not None: box.label = QLabel(label) layout.addRow(box.label, box) if validator is not None: if validator == 'int': qvalidator = QIntValidator() elif validator == 'double': qvalidator = QDoubleValidator() if bottom is not None: qvalidator.setBottom(bottom) if top is not None: qvalidator.setTop(top) box.setValidator(qvalidator) return box
class Window(QMainWindow, Ui_window): renderRequested = QtCore.pyqtSignal(int, float) loadFileRequested = QtCore.pyqtSignal(str, str) findTextRequested = QtCore.pyqtSignal(str, int, bool) def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.setupUi(self) self.dockSearch.hide() self.dockWidget.hide() self.dockWidget.setMinimumWidth(310) self.findTextEdit.setFocusPolicy(QtCore.Qt.StrongFocus) self.treeView.setAlternatingRowColors(True) self.treeView.clicked.connect(self.onOutlineClick) # resizing pages requires some time to take effect self.resize_page_timer = QtCore.QTimer(self) self.resize_page_timer.setSingleShot(True) self.resize_page_timer.timeout.connect(self.onWindowResize) # Add shortcut actions self.gotoPageAction = QAction(QIcon(":/goto.png"), "GoTo Page", self) self.gotoPageAction.triggered.connect(self.gotoPage) self.copyTextAction = QAction(QIcon(":/copy.png"), "Copy Text", self) self.copyTextAction.setCheckable(True) self.copyTextAction.triggered.connect(self.toggleCopyText) self.findTextAction = QAction(QIcon(":/search.png"), "Find Text", self) self.findTextAction.setShortcut('Ctrl+F') self.findTextAction.triggered.connect(self.dockSearch.show) # connect menu actions signals self.openFileAction.triggered.connect(self.openFile) self.lockUnlockAction.triggered.connect(self.lockUnlock) self.printAction.triggered.connect(self.printFile) self.quitAction.triggered.connect(self.close) self.toPSAction.triggered.connect(self.exportToPS) self.pageToImageAction.triggered.connect(self.exportPageToImage) self.docInfoAction.triggered.connect(self.docInfo) self.zoominAction.triggered.connect(self.zoomIn) self.zoomoutAction.triggered.connect(self.zoomOut) self.undoJumpAction.triggered.connect(self.undoJump) self.prevPageAction.triggered.connect(self.goPrevPage) self.nextPageAction.triggered.connect(self.goNextPage) self.firstPageAction.triggered.connect(self.goFirstPage) self.lastPageAction.triggered.connect(self.goLastPage) # Create widgets for menubar / toolbar self.gotoPageEdit = QLineEdit(self) self.gotoPageEdit.setPlaceholderText("Jump to page...") self.gotoPageEdit.setMaximumWidth(120) self.gotoPageEdit.returnPressed.connect(self.gotoPage) self.gotoPageValidator = QIntValidator(1, 1, self.gotoPageEdit) self.gotoPageEdit.setValidator(self.gotoPageValidator) self.pageNoLabel = QLabel(self) self.pageNoLabel.setFrameShape(QFrame.StyledPanel) spacer = QWidget(self) spacer.setSizePolicy(1 | 2 | 4, 1 | 4) self.zoomLevelCombo = QComboBox(self) self.zoomLevelCombo.addItems([ "Fixed Width", "75%", "90%", "100%", "110%", "121%", "133%", "146%", "175%", "200%" ]) self.zoomLevelCombo.activated.connect(self.setZoom) self.zoom_levels = [0, 75, 90, 100, 110, 121, 133, 146, 175, 200] # Add toolbar actions self.toolBar.addAction(self.openFileAction) self.toolBar.addAction(self.printAction) self.toolBar.addSeparator() self.toolBar.addAction(self.docInfoAction) self.toolBar.addSeparator() self.toolBar.addAction(self.zoomoutAction) self.toolBar.addWidget(self.zoomLevelCombo) self.toolBar.addAction(self.zoominAction) self.toolBar.addSeparator() self.toolBar.addAction(self.firstPageAction) self.toolBar.addAction(self.prevPageAction) self.toolBar.addWidget(self.pageNoLabel) self.toolBar.addAction(self.nextPageAction) self.toolBar.addAction(self.lastPageAction) self.toolBar.addAction(self.undoJumpAction) self.toolBar.addWidget(self.gotoPageEdit) self.toolBar.addAction(self.gotoPageAction) self.toolBar.addSeparator() self.toolBar.addAction(self.copyTextAction) self.toolBar.addAction(self.findTextAction) #self.toolBar.addAction(self.saveUnlockedAction) self.toolBar.addWidget(spacer) self.toolBar.addSeparator() self.toolBar.addAction(self.quitAction) # Add widgets self.statusbar = QLabel(self) self.statusbar.setStyleSheet( "QLabel { font-size: 12px; border-radius: 2px; padding: 2px; background: palette(highlight); color: palette(highlighted-text); }" ) self.statusbar.setMaximumHeight(16) self.statusbar.hide() # Impoort settings desktop = QApplication.desktop() self.settings = QtCore.QSettings("gospel-pdf", "main", self) self.recent_files = self.settings.value("RecentFiles", []) self.history_filenames = self.settings.value("HistoryFileNameList", []) self.history_page_no = self.settings.value("HistoryPageNoList", []) self.offset_x = int(self.settings.value("OffsetX", 4)) self.offset_y = int(self.settings.value("OffsetY", 26)) self.available_area = [ desktop.availableGeometry().width(), desktop.availableGeometry().height() ] self.zoomLevelCombo.setCurrentIndex( int(self.settings.value("ZoomLevel", 2))) # Connect Signals self.scrollArea.verticalScrollBar().valueChanged.connect( self.onMouseScroll) self.scrollArea.verticalScrollBar().sliderReleased.connect( self.onSliderRelease) self.findTextEdit.returnPressed.connect(self.findNext) self.findNextButton.clicked.connect(self.findNext) self.findBackButton.clicked.connect(self.findBack) self.findCloseButton.clicked.connect(self.dockSearch.hide) self.dockSearch.visibilityChanged.connect(self.toggleFindMode) # Create separate thread and move renderer to it self.thread1 = QtCore.QThread(self) self.renderer1 = Renderer(0) self.renderer1.moveToThread( self.thread1) # this must be moved before connecting signals self.renderRequested.connect(self.renderer1.render) self.loadFileRequested.connect(self.renderer1.loadDocument) self.findTextRequested.connect(self.renderer1.findText) self.renderer1.rendered.connect(self.setRenderedImage) self.renderer1.textFound.connect(self.onTextFound) self.thread1.start() self.thread2 = QtCore.QThread(self) self.renderer2 = Renderer(1) self.renderer2.moveToThread(self.thread2) self.renderRequested.connect(self.renderer2.render) self.loadFileRequested.connect(self.renderer2.loadDocument) self.renderer2.rendered.connect(self.setRenderedImage) self.thread2.start() # Initialize Variables self.doc = None self.filename = '' self.passwd = '' self.pages = [] self.jumped_from = None self.max_preload = 1 self.recent_files_actions = [] self.addRecentFiles() # Show Window width = int(self.settings.value("WindowWidth", 1040)) height = int(self.settings.value("WindowHeight", 717)) self.resize(width, height) self.show() def addRecentFiles(self): self.recent_files_actions[:] = [] # pythonic way to clear list self.menuRecentFiles.clear() for each in self.recent_files: name = elideMiddle(os.path.basename(each), 60) action = self.menuRecentFiles.addAction(name, self.openRecentFile) self.recent_files_actions.append(action) self.menuRecentFiles.addSeparator() self.menuRecentFiles.addAction(QIcon(':/edit-clear.png'), 'Clear Recents', self.clearRecents) def openRecentFile(self): action = self.sender() index = self.recent_files_actions.index(action) self.loadPDFfile(self.recent_files[index]) def clearRecents(self): self.recent_files_actions[:] = [] self.menuRecentFiles.clear() self.recent_files[:] = [] def removeOldDoc(self): if not self.doc: return # Save current page number self.saveFileData() # Remove old document for i in range(len(self.pages)): self.verticalLayout.removeWidget(self.pages[-1]) for i in range(len(self.pages)): self.pages.pop().deleteLater() self.frame.deleteLater() self.jumped_from = None self.addRecentFiles() def loadPDFfile(self, filename): """ Loads pdf document in all threads """ filename = os.path.expanduser(filename) doc = Poppler.Document.load(filename) if not doc: return password = '' if doc.isLocked(): password = QInputDialog.getText(self, 'This PDF is locked', 'Enter Password :'******'': if self.doc == None: sys.exit(1) #exif if first document else: return locked = doc.unlock(password.encode(), password.encode()) if locked: return QMessageBox.critical(self, "Failed !", "Incorrect Password") self.passwd = password self.lockUnlockAction.setText("Save Unlocked") else: self.lockUnlockAction.setText("Encrypt PDF") self.removeOldDoc() doc.setRenderHint(Poppler.Document.TextAntialiasing | Poppler.Document.TextHinting | Poppler.Document.Antialiasing | Poppler.Document.ThinLineSolid) self.doc = doc self.filename = filename self.pages_count = self.doc.numPages() self.current_page = 1 self.rendered_pages = [] self.getOutlines(self.doc) # Load Document in other threads self.loadFileRequested.emit(self.filename, password) if collapseUser(self.filename) in self.history_filenames: self.current_page = int( self.history_page_no[self.history_filenames.index( collapseUser(self.filename))]) self.current_page = min(self.current_page, self.pages_count) self.scroll_render_lock = False # Add widgets self.frame = Frame(self.scrollAreaWidgetContents, self.scrollArea) self.verticalLayout = QVBoxLayout(self.frame) self.horizontalLayout_2.addWidget(self.frame) self.scrollArea.verticalScrollBar().setValue(0) self.frame.jumpToRequested.connect(self.jumpToPage) self.frame.copyTextRequested.connect(self.copyText) self.frame.showStatusRequested.connect(self.showStatus) # Render 4 pages, (Preload 3 pages) self.max_preload = min(4, self.pages_count) # Add pages for i in range(self.pages_count): page = PageWidget(i + 1, self.frame) self.verticalLayout.addWidget(page, 0, QtCore.Qt.AlignCenter) self.pages.append(page) self.resizePages() self.pageNoLabel.setText('<b>%i/%i</b>' % (self.current_page, self.pages_count)) self.gotoPageValidator.setTop(self.pages_count) self.setWindowTitle( os.path.basename(self.filename) + " - Gospel PDF " + __version__) if self.current_page != 1: QtCore.QTimer.singleShot(150 + self.pages_count // 3, self.jumpToCurrentPage) def setRenderedImage(self, page_no, image): """ takes a QImage and sets pixmap of the specified page when number of rendered pages exceeds a certain number, old page image is deleted to save memory """ debug("Set Rendered Image :", page_no) self.pages[page_no - 1].setPageData(page_no, QPixmap.fromImage(image), self.doc.page(page_no - 1)) # Request to render next page if self.current_page <= page_no < (self.current_page + self.max_preload - 2): if (page_no + 2 not in self.rendered_pages) and (page_no + 2 <= self.pages_count): self.rendered_pages.append(page_no + 2) self.renderRequested.emit(page_no + 2, self.pages[page_no + 1].dpi) # Replace old rendered pages with blank image if len(self.rendered_pages) > 10: cleared_page_no = self.rendered_pages.pop(0) debug("Clear Page :", cleared_page_no) self.pages[cleared_page_no - 1].clear() debug("Rendered Pages :", self.rendered_pages) def renderCurrentPage(self): """ Requests to render current page. if it is already rendered, then request to render next unrendered page """ requested = 0 for page_no in range(self.current_page, self.current_page + self.max_preload): if (page_no not in self.rendered_pages) and (page_no <= self.pages_count): self.rendered_pages.append(page_no) self.renderRequested.emit(page_no, self.pages[page_no - 1].dpi) requested += 1 debug("Render Requested :", page_no) if requested == 2: return def onMouseScroll(self, pos): """ It is called when vertical scrollbar value is changed. Get the current page number on scrolling, then requests to render""" index = self.verticalLayout.indexOf( self.frame.childAt(self.frame.width() / 2, pos)) if index == -1: return self.pageNoLabel.setText('<b>%i/%i</b>' % (index + 1, self.pages_count)) if self.scrollArea.verticalScrollBar().isSliderDown( ) or self.scroll_render_lock: return self.current_page = index + 1 self.renderCurrentPage() def onSliderRelease(self): self.onMouseScroll(self.scrollArea.verticalScrollBar().value()) def openFile(self): filename, sel_filter = QFileDialog.getOpenFileName( self, "Select Document to Open", "", "Portable Document Format (*.pdf);;All Files (*)") if filename != "": self.loadPDFfile(filename) def lockUnlock(self): if which("qpdf") == None: self.lockUnlockAction.setEnabled(False) QMessageBox.warning( self, "qpdf Required", "qpdf command not found.\nInstall qpdf program.") return if self.lockUnlockAction.text() == "Encrypt PDF": self.encryptPDF() return filename, ext = os.path.splitext(self.filename) new_name = filename + "-unlocked.pdf" proc = Popen([ "qpdf", "--decrypt", "--password="******"File Saved", "Successfully saved as\n" + basename) else: QMessageBox.warning(self, "Failed !", "Failed to save as unlocked") def encryptPDF(self): password, ok = QInputDialog.getText(self, "Lock PDF", "Enter Password :"******"": return filename, ext = os.path.splitext(self.filename) new_name = filename + "-locked.pdf" proc = Popen([ "qpdf", "--encrypt", password, password, '128', '--', self.filename, new_name ]) stdout, stderr = proc.communicate() if proc.returncode == 0: basename = os.path.basename(new_name) QMessageBox.information(self, "File Saved", "Successfully saved as\n" + basename) else: QMessageBox.warning(self, "Failed !", "Failed to save as Encrypted") def printFile(self): if which("quikprint") == None: QMessageBox.warning(self, "QuikPrint Required", "Install QuikPrint program.") return Popen(["quikprint", self.filename]) def exportToPS(self): width = self.doc.page(self.current_page - 1).pageSizeF().width() height = self.doc.page(self.current_page - 1).pageSizeF().height() filename, sel_filter = QFileDialog.getSaveFileName( self, "Select File to Save", os.path.splitext(self.filename)[0] + '.ps', "Adobe Postscript Format (*.ps)") if filename == '': return conv = self.doc.psConverter() conv.setPaperWidth(width) conv.setPaperHeight(height) conv.setOutputFileName(filename) conv.setPageList([i + 1 for i in range(self.pages_count)]) ok = conv.convert() if ok: QMessageBox.information(self, "Successful !", "File has been successfully exported") else: QMessageBox.warning(self, "Failed !", "Failed to export to Postscript") def exportPageToImage(self): dialog = ExportToImageDialog(self.current_page, self.pages_count, self) if dialog.exec_() == QDialog.Accepted: try: dpi = int(dialog.dpiEdit.text()) page_no = dialog.pageNoSpin.value() filename = os.path.splitext( self.filename)[0] + '-' + str(page_no) + '.jpg' page = self.doc.page(page_no - 1) if not page: return img = page.renderToImage(dpi, dpi) img.save(filename) QMessageBox.information(self, "Successful !", "Page has been successfully exported") except: QMessageBox.warning(self, "Failed !", "Failed to export to Image") def docInfo(self): info_keys = list(self.doc.infoKeys()) values = [self.doc.info(key) for key in info_keys] page_size = self.doc.page(self.current_page - 1).pageSizeF() page_size = "%s x %s pts" % (page_size.width(), page_size.height()) info_keys += ['Embedded FIles', 'Page Size'] values += [str(self.doc.hasEmbeddedFiles()), page_size] dialog = DocInfoDialog(self) dialog.setInfo(info_keys, values) dialog.exec_() def jumpToCurrentPage(self): """ this is used as a slot, to connect with a timer""" self.jumpToPage(self.current_page) def jumpToPage(self, page_num, top=0.0): """ scrolls to a particular page and position """ if page_num < 1: page_num = 1 elif page_num > self.pages_count: page_num = self.pages_count if not (0 < top < 1.0): top = 0 self.jumped_from = self.current_page self.current_page = page_num scrollbar_pos = self.pages[page_num - 1].pos().y() scrollbar_pos += top * self.pages[page_num - 1].height() self.scrollArea.verticalScrollBar().setValue(scrollbar_pos) def undoJump(self): if self.jumped_from == None: return self.jumpToPage(self.jumped_from) def goNextPage(self): if self.current_page == self.pages_count: return self.jumpToPage(self.current_page + 1) def goPrevPage(self): if self.current_page == 1: return self.jumpToPage(self.current_page - 1) def goFirstPage(self): self.jumpToPage(1) def goLastPage(self): self.jumpToPage(self.pages_count) def gotoPage(self): text = self.gotoPageEdit.text() if text == "": return self.jumpToPage(int(text)) self.gotoPageEdit.clear() self.gotoPageEdit.clearFocus() ###################### Zoom and Size Management ########################## def availableWidth(self): """ Returns available width for rendering a page """ dock_width = 0 if self.dockWidget.isHidden( ) else self.dockWidget.width() return self.width() - dock_width - 50 def resizePages(self): '''Resize all pages according to zoom level ''' page_dpi = self.zoom_levels[ self.zoomLevelCombo.currentIndex()] * SCREEN_DPI / 100 fixed_width = self.availableWidth() for i in range(self.pages_count): pg_width = self.doc.page(i).pageSizeF().width() # width in points pg_height = self.doc.page(i).pageSizeF().height() if self.zoomLevelCombo.currentIndex() == 0: # if fixed width dpi = 72.0 * fixed_width / pg_width else: dpi = page_dpi self.pages[i].dpi = dpi self.pages[i].setFixedSize(pg_width * dpi / 72.0, pg_height * dpi / 72.0) for page_no in self.rendered_pages: self.pages[page_no - 1].clear() self.rendered_pages = [] self.renderCurrentPage() def setZoom(self, index): """ Gets called when zoom level is changed""" self.scroll_render_lock = True # rendering on scroll is locked as set scroll position self.resizePages() QtCore.QTimer.singleShot(300, self.afterZoom) def zoomIn(self): index = self.zoomLevelCombo.currentIndex() if index == len(self.zoom_levels) - 1: return if index == 0: index = 3 self.zoomLevelCombo.setCurrentIndex(index + 1) self.setZoom(index + 1) def zoomOut(self): index = self.zoomLevelCombo.currentIndex() if index == 1: return if index == 0: index = 4 self.zoomLevelCombo.setCurrentIndex(index - 1) self.setZoom(index - 1) def afterZoom(self): scrolbar_pos = self.pages[self.current_page - 1].pos().y() self.scrollArea.verticalScrollBar().setValue(scrolbar_pos) self.scroll_render_lock = False ######### Search Text ######### def toggleFindMode(self, enable): if enable: self.findTextEdit.setText('') self.findTextEdit.setFocus() self.search_text = '' self.search_result_page = 0 elif self.search_result_page != 0: self.pages[self.search_result_page - 1].highlight_area = None self.pages[self.search_result_page - 1].updateImage() def findNext(self): """ search text in current page and next pages """ text = self.findTextEdit.text() if text == "": return # search from current page when text changed if self.search_text != text or self.search_result_page == 0: search_from_page = self.current_page else: search_from_page = self.search_result_page + 1 self.findTextRequested.emit(text, search_from_page, False) if self.search_result_page != 0: # clear previous highlights self.pages[self.search_result_page - 1].highlight_area = None self.pages[self.search_result_page - 1].updateImage() self.search_result_page = 0 self.search_text = text def findBack(self): """ search text in pages before current page """ text = self.findTextEdit.text() if text == "": return if self.search_text != text or self.search_result_page == 0: search_from_page = self.current_page else: search_from_page = self.search_result_page - 1 self.findTextRequested.emit(text, search_from_page, True) if self.search_result_page != 0: self.pages[self.search_result_page - 1].highlight_area = None self.pages[self.search_result_page - 1].updateImage() self.search_result_page = 0 self.search_text = text def onTextFound(self, page_no, areas): self.pages[page_no - 1].highlight_area = areas self.search_result_page = page_no if self.pages[page_no - 1].pixmap(): self.pages[page_no - 1].updateImage() first_result_pos = areas[0].y() / self.doc.page(page_no - 1).pageSize().height() self.jumpToPage(page_no, first_result_pos) ######### Cpoy Text to Clip Board ######### def toggleCopyText(self, checked): self.frame.enableCopyTextMode(checked) def copyText(self, page_no, top_left, bottom_right): zoom = self.pages[page_no - 1].height() / self.doc.page(page_no - 1).pageSize().height() # Copy text to clipboard text = self.doc.page(page_no - 1).text( QtCore.QRectF(top_left / zoom, bottom_right / zoom)) QApplication.clipboard().setText(text) self.copyTextAction.setChecked(False) self.toggleCopyText(False) ########## Other Functions ########## def getOutlines(self, doc): toc = doc.toc() if not toc: self.dockWidget.hide() return self.dockWidget.show() outline_model = QStandardItemModel(self) parent_item = outline_model.invisibleRootItem() node = toc.firstChild() loadOutline(doc, node, parent_item) self.treeView.setModel(outline_model) if parent_item.rowCount() < 4: self.treeView.expandToDepth(0) self.treeView.setHeaderHidden(True) self.treeView.header().setSectionResizeMode(0, 1) self.treeView.header().setSectionResizeMode(1, 3) self.treeView.header().setStretchLastSection(False) def onOutlineClick(self, m_index): page_num = self.treeView.model().data(m_index, QtCore.Qt.UserRole + 1) top = self.treeView.model().data(m_index, QtCore.Qt.UserRole + 2) if not page_num: return self.jumpToPage(page_num, top) def showStatus(self, url): if url == "": self.statusbar.hide() return self.statusbar.setText(url) self.statusbar.adjustSize() self.statusbar.move(0, self.height() - self.statusbar.height()) self.statusbar.show() def resizeEvent(self, ev): QMainWindow.resizeEvent(self, ev) if self.filename == '': return if self.zoomLevelCombo.currentIndex() == 0: self.resize_page_timer.start(200) def onWindowResize(self): for i in range(self.pages_count): self.pages[ i].annots_listed = False # Clears prev link annotation positions self.resizePages() wait(300) self.jumpToCurrentPage() if not self.isMaximized(): self.settings.setValue("WindowWidth", self.width()) self.settings.setValue("WindowHeight", self.height()) def saveFileData(self): if self.filename != '': filename = collapseUser(self.filename) if filename in self.history_filenames: index = self.history_filenames.index(filename) self.history_page_no[index] = self.current_page else: self.history_filenames.insert(0, filename) self.history_page_no.insert(0, self.current_page) if filename in self.recent_files: self.recent_files.remove(filename) self.recent_files.insert(0, filename) def closeEvent(self, ev): """ Save all settings on window close """ self.saveFileData() self.settings.setValue("OffsetX", self.geometry().x() - self.x()) self.settings.setValue("OffsetY", self.geometry().y() - self.y()) self.settings.setValue("ZoomLevel", self.zoomLevelCombo.currentIndex()) self.settings.setValue("HistoryFileNameList", self.history_filenames[:100]) self.settings.setValue("HistoryPageNoList", self.history_page_no[:100]) self.settings.setValue("RecentFiles", self.recent_files[:10]) return QMainWindow.closeEvent(self, ev) def onAppQuit(self): """ Close running threads """ loop1 = QtCore.QEventLoop() loop2 = QtCore.QEventLoop() self.thread1.finished.connect(loop1.quit) self.thread2.finished.connect(loop2.quit) self.thread1.quit() loop1.exec_() self.thread2.quit() loop2.exec_()
def set_valitor(self, widget, bottom=0, top=0): intvalitor = QIntValidator() intvalitor.setBottom(bottom) if top != 0: intvalitor.setTop(top) widget.setValidator(intvalitor)
class ScaniGUI(QMainWindow): def __init__(self, parent=None): self.dev = None self.model = None self.connected = False super(ScaniGUI, self).__init__(parent) self.widget = QWidget() self.setCentralWidget(self.widget) vb = QVBoxLayout() hb1 = QHBoxLayout() self.scanigr = QGroupBox("Rede") self.confgr = QGroupBox("Config") hb1.addWidget(self.scanigr) vb1 = QVBoxLayout() hb2 = QHBoxLayout() hb2.addWidget(QLabel("IP")) self.ip_ed = QLineEdit("191.30.80.131") hb2.addWidget(self.ip_ed) vb1.addLayout(hb2) self.connbut = QPushButton("Conectar") self.connbut.clicked.connect(self.connect) vb1.addWidget(self.connbut) self.scanigr.setLayout(vb1) hb1.addWidget(self.confgr) vb.addLayout(hb1) self.zerobut = QPushButton("Hard Zero") self.zerobut.clicked.connect(self.hard_zero) self.zerobut.setEnabled(False) vb.addWidget(self.zerobut) self.listsbut = QPushButton("LIST S") self.listsbut.clicked.connect(self.listS) self.listsbut.setEnabled(False) vb.addWidget(self.listsbut) self.okbut = QPushButton("Ok") vb.addWidget(self.okbut) #self.szerobut.QPushButton("Soft Zero") #self.szerobut.setEnabled(False) gr1 = QGridLayout() vb2 = QVBoxLayout() gr1.addWidget(QLabel("FPS"), 0, 0) gr1.addWidget(QLabel("PERIOD"), 1, 0) gr1.addWidget(QLabel("AVG"), 2, 0) self.fps_ed = QLineEdit("1") self.fps_val = QIntValidator(1, 2147483647) self.fps_ed.setValidator(self.fps_val) self.fps_ed.textChanged.connect(self.check_state) self.fps_ed.textChanged.emit(self.fps_ed.text()) self.period_ed = QLineEdit("500") self.period_val = QIntValidator(150, 62500) self.period_ed.setValidator(self.period_val) self.period_ed.textChanged.connect(self.check_state) self.period_ed.textChanged.emit(self.period_ed.text()) self.avg_ed = QLineEdit("1") self.avg_val = QIntValidator(1, 240) self.avg_ed.setValidator(self.avg_val) self.avg_ed.textChanged.connect(self.check_state) self.avg_ed.textChanged.emit(self.avg_ed.text()) self.freqlab = QLabel("") self.ttotlab = QLabel("") gr1.addWidget(self.fps_ed, 0, 1) gr1.addWidget(self.period_ed, 1, 1) gr1.addWidget(self.avg_ed, 2, 1) gr1.addWidget(QLabel("Freq (Hz)"), 3, 0) gr1.addWidget(self.freqlab, 3, 1) gr1.addWidget(QLabel("Tempo (s)"), 4, 0) gr1.addWidget(self.ttotlab, 4, 1) self.confgr.setEnabled(False) vb2.addLayout(gr1) self.confbut = QPushButton("Configurar") self.confbut.clicked.connect(self.config) vb2.addWidget(self.confbut) self.confgr.setLayout(vb2) self.widget.setLayout(vb) def ipaddr(self): return self.ip_ed.text().strip() def connect(self): if self.connected: self.connbut.setText("Conectar") self.confgr.setEnabled(False) self.zerobut.setEnabled(False) self.listsbut.setEnabled(False) self.dev.close() self.dev = None self.connected = False else: ip = self.ipaddr() if scani.check_server(ip, 23, 2): try: self.dev = scani.Scanivalve(ip) except: QMessageBox.warning(self, "Erro", "Não foi possível conectar com o Scanivalve") return try: self.model = self.dev.get_model() lists = self.dev.list_any_map("S") except: QMessageBox.warning(self, "Problemas com Scanivalve", "Problemas na configuração do Scanivalve") return fps = lists['FPS'] avg = lists['AVG'] period = lists['PERIOD'] self.fps_ed.setText(fps) self.period_ed.setText(period) self.avg_ed.setText(avg) self.freqlab.setText(str(1/self.dev.dt)) self.ttotlab.setText(str(self.dev.dt*int(fps))) if self.model=='3017': self.period_val.setBottom(500) self.avg_val.setTop(32767) else: self.period_val.setBottom(150) self.avg_val.setTop(240) self.connbut.setText("DESconectar") self.confgr.setEnabled(True) self.listsbut.setEnabled(True) self.zerobut.setEnabled(True) self.connected = True return else: QMessageBox.warning(self, "Sem conexão", "Não foi possível conectar com o scanivalve") return def check_state(self, *args, **kwargs): sender = self.sender() validator = sender.validator() state = validator.validate(sender.text(), 0)[0] if state == QValidator.Acceptable: color = '#c4df9b' # green #elif state == QtGui.QValidator.Intermediate: # color = '#fff79a' # yellow else: color = '#f6989d' # red sender.setStyleSheet('QLineEdit { background-color: %s }' % color) def config(self): avg = self.avg_ed.text() state = self.avg_val.validate(avg, 0)[0] if state != QValidator.Acceptable: QMessageBox.warning(self, "Valor ilegal", "AVG está fora dos valores permitidos") return period = self.period_ed.text() state = self.period_val.validate(period, 0)[0] if state != QValidator.Acceptable: QMessageBox.warning(self, "Valor ilegal", "PERIOD está fora dos valores permitidos") return fps = self.fps_ed.text() state = self.fps_val.validate(fps, 0)[0] if state != QValidator.Acceptable: QMessageBox.warning(self, "Valor ilegal", "FPS está fora dos valores permitidos") return self.dev.config(FPS=int(fps), AVG=int(avg), PERIOD=int(period)) self.freqlab.setText("{:05.3f}".format(1/self.dev.dt)) self.ttotlab.setText("{:05.3f}".format(self.dev.dt * int(fps))) return None def hard_zero(self): if self.dev is not None: self.dev.hard_zero() self.setEnabled(False) QtTest.QTest.qWait(15000) self.setEnabled(True) return None def listS(self): if self.dev is not None: lists = self.dev.list_any("S") s = '\n'.join([' '.join(l) for l in lists]) QMessageBox.information(self, "LIST S", s) return None def scanivalve(self): return self.dev
class SpectrogramTools(QWidget): def __init__(self, parent): super(SpectrogramTools, self).__init__(parent) self.spectrogram = self.parent().plugin.signal_widget.spectrogram layout = QFormLayout() self.n_fft_le = QLineEdit(str(self.spectrogram.n_fft)) self.n_fft_le_validator = QIntValidator(8, 1024) self.n_fft_le.setValidator(self.n_fft_le_validator) layout.addRow('NFFT', self.n_fft_le) self.n_fft_le.editingFinished.connect(self.set_n_fft) self.step_le = QLineEdit(str(self.spectrogram.step)) self.step_le_validator = QIntValidator(1, 128) self.step_le.setValidator(self.step_le_validator) layout.addRow('Step', self.step_le) self.step_le.editingFinished.connect(self.set_step) self.cmap_cb = QComboBox() layout.addRow('Colormap', self.cmap_cb) # curr_cmap = [x[0] for x in color.get_colormaps().items() \ # if x[1] == self.spectrogram.cmap][0] cmap_list = list(color.get_colormaps().keys()) cmap_list.sort() # curr_idx = cmap_list.index(curr_cmap) self.cmap_cb.addItems(cmap_list) # self.cmap_cb.setCurrentIndex(curr_idx) self.cmap_cb.currentIndexChanged.connect(self.set_cmap) self.interp_cb = QComboBox() layout.addRow('Interpolation', self.interp_cb) interp_list = [ 'nearest', 'bilinear', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'bicubic', 'catrom', 'mitchell', 'spline16', 'spline36', 'gaussian', 'bessel', 'sinc', 'lanczos', 'blackman' ] self.interp_cb.addItems(interp_list) self.interp_cb.currentIndexChanged.connect(self.set_interpolation) self.normalize_chb = QCheckBox() layout.addRow('Normalize', self.normalize_chb) self.normalize_chb.setCheckState(self.spectrogram.normalize) self.normalize_chb.stateChanged.connect(self.set_normalize) clim_low_layout = QHBoxLayout() self.clim_low_s = QSlider(Qt.Horizontal) self.clim_low_s.setMinimum(0) self.clim_low_s.setMaximum(100) self.clim_low_s.setValue(0) self.clim_low_s.setTickInterval(1) self.clim_low_s.valueChanged.connect(self.set_clim_low_s) self.clim_low_le = QLineEdit('0') self.clim_low_le_validator = QIntValidator(1, 100) self.clim_low_le.setValidator(self.clim_low_le_validator) self.clim_low_le.editingFinished.connect(self.set_clim) self.clim_low_le.setMaximumWidth(40) clim_low_layout.addWidget(self.clim_low_s) clim_low_layout.addWidget(self.clim_low_le) layout.addRow('Color limit low', clim_low_layout) clim_high_layout = QHBoxLayout() self.clim_high_s = QSlider(Qt.Horizontal) self.clim_high_s.setMinimum(0) self.clim_high_s.setMaximum(100) self.clim_high_s.setValue(100) self.clim_high_s.setTickInterval(1) self.clim_high_s.valueChanged.connect(self.set_clim_high_s) self.clim_high_le = QLineEdit('100') self.clim_high_le_validator = QIntValidator(1, 100) self.clim_high_le.setValidator(self.clim_high_le_validator) self.clim_high_le.editingFinished.connect(self.set_clim) self.clim_high_le.setMaximumWidth(40) clim_high_layout.addWidget(self.clim_high_s) clim_high_layout.addWidget(self.clim_high_le) layout.addRow('Color limit high', clim_high_layout) self.setLayout(layout) def set_n_fft(self): self.spectrogram.n_fft = int(self.n_fft_le.text()) self.step_le_validator.setTop(self.spectrogram.n_fft - 1) self.parent().plugin.signal_widget.update_signals() def set_step(self): self.spectrogram.step = int(self.step_le.text()) self.parent().plugin.signal_widget.update_signals() def set_cmap(self, idx): self.spectrogram.cmap = self.cmap_cb.itemText(idx) def set_interpolation(self, idx): self.spectrogram.interpolation = self.interp_cb.itemText(idx) def set_normalize(self, state): if state: self.spectrogram.normalize = True else: self.spectrogram.normalize = False def set_clim_low_s(self, val): low = int(val) high = int(self.clim_high_le.text()) # Adjust validators self.clim_high_le_validator.setBottom(low) # Adjust text self.clim_low_le.setText(str(low)) if self.spectrogram._data is None: return d_min = np.min(self.spectrogram._data) d_max = np.max(self.spectrogram._data) d_diff = d_max - d_min low = ((low / 100) * d_diff) + d_min high = ((high / 100) * d_diff) + d_min self.spectrogram.clim = (low, high) def set_clim_high_s(self, val): low = int(self.clim_low_le.text()) high = int(val) # Adjust validators self.clim_low_le_validator.setTop(high) # Adjust text self.clim_high_le.setText(str(high)) if self.spectrogram._data is None: return d_min = np.min(self.spectrogram._data) d_max = np.max(self.spectrogram._data) d_diff = d_max - d_min low = ((low / 100) * d_diff) + d_min high = ((high / 100) * d_diff) + d_min self.spectrogram.clim = (low, high) def set_clim(self): low = int(self.clim_low_le.text()) high = int(self.clim_high_le.text()) # Adjust validators self.clim_low_le_validator.setTop(high) self.clim_high_le_validator.setBottom(low) # Adjust the sliders self.clim_low_s.setValue(low) self.clim_high_s.setValue(high) if self.spectrogram.data is None: return d_min = np.min(self.spectrogram.data) d_max = np.max(self.spectrogram.data) d_diff = d_max - d_min low = ((low / 100) * d_diff) + d_min high = ((high / 100) * d_diff) + d_min self.spectrogram.clim = (low, high)
class MainViewController(QObject): DEFAULT_MOVIE_SPEED = 100 ANIMATION_PLAYING_FRAME_COLOR = Qt.red def __init__(self, view, model) -> None: super().__init__() self._view = view self._model = model self._frame_validator = QIntValidator(0, 0) self._current_file_path = None self.original_base_role_color = view.frame.palette().color( QPalette.Base) self._view.pushButtonBrowse.clicked.connect(self._browse_for_folder) self._view.actionBrowse.triggered.connect(self._browse_for_folder) self._view.loop.toggled.connect(self._play_movie) self._view.speed_slider.valueChanged.connect(self._update_speed_label) self._view.speed_slider.sliderReleased.connect(self._speed_changed) self._view.gif_list.currentItemChanged.connect( lambda current, _: current and self. _set_gif_display_movie_from_string(current.file_path)) self._view.gif_list.itemPressed.connect( lambda item: self._set_gif_display_movie_from_string(item.file_path )) self._model.files_changed.connect(self._populate_gif_list) self._model.first_file.connect(self._set_gif_display_movie_from_string) self._view.single_step.toggled.connect(self._single_step_toggled) def initialize_controller(self) -> None: self._view.frame_number.setValidator(self._frame_validator) self._update_speed_label(self.DEFAULT_MOVIE_SPEED) self._model.update_files_from_path( Path("/Users/charles/Downloads/assets")) @pyqtSlot(bool) # QPushButton::clicked(), QAction::triggered() def _browse_for_folder(self, _: bool) -> None: path = QFileDialog.getExistingDirectory(self._view, "Select Directory", ".") if path: self._view.reset() self._model.update_files_from_path(Path(path)) def _play_movie(self) -> None: self._view.update_widget_palette(self._view.frame, QPalette(self._view.frame.palette()), QPalette.Base, self.ANIMATION_PLAYING_FRAME_COLOR) self._view.play_movie() @pyqtSlot(list) def _populate_gif_list(self, files: list[Path]) -> None: if not files: self._current_file_path = None self._view.single_step.setEnabled(False) self._view.loop.setEnabled(False) return # populate for file in files: list_widget_item = QListWidgetItem(file.name) list_widget_item.file_path = file self._view.gif_list.addItem(list_widget_item) # update self._view.set_file_count(self._model.count) self._view.gif_list.setCurrentItem(self._view.gif_list.item(0)) self._view.set_speed(self.DEFAULT_MOVIE_SPEED) self._update_status_bar() self._view.single_step.setEnabled(True) self._view.loop.setEnabled(True) @pyqtSlot(Path) def _set_gif_display_movie_from_string(self, path: Path) -> None: if path == self._current_file_path: # trigger QRadioButton::toggled() signals # which will cause nav controls to be disabled and hidden self._view.normal_play.setChecked(True) self._play_movie() return current_movie = self._view.movie() if current_movie and current_movie.state() == QMovie.Running: self._view.normal_play.setChecked(True) speed = self._view.speed() movie: QMovie = QMovie(path.as_posix()) movie.setCacheMode(QMovie.CacheAll) movie.setSpeed(speed) # noinspection PyUnresolvedReferences movie.frameChanged.connect(self._stop_movie_if_looping_not_selected) # noinspection PyUnresolvedReferences movie.updated.connect(self._update_dimensions_label) self._current_gif_frame_count = movie.frameCount() - 1 self._current_file_path = path self._view.set_movie(movie) self._view.set_title(path.as_posix()) self._view.normal_play.setChecked(True) self._view.set_nav_controls_visible(False) self._play_movie() @pyqtSlot(bool) def _single_step_toggled(self, checked: bool) -> None: def _setup_starting_frame(*, current_frame, last_frame): if current_frame == last_frame: current_frame = 0 self._view.frame_slider.setValue(current_frame) self._view.frame_number.setText(str(current_frame)) movie.jumpToFrame(current_frame) if not checked: helpers.disconnect_lambda_slots( signal=self._view.frame_slider.valueChanged) helpers.disconnect_lambda_slots( signal=self._view.frame_number.returnPressed) self._view.set_speed_controls_visible(True) self._view.set_nav_controls_visible(False) return self._stop_movie() movie = self._view.movie() frame_count = movie.frameCount() - 1 self._view.frame_slider.setMinimum(0) self._view.frame_slider.setMaximum(frame_count) self._view.frame_slider.valueChanged.connect( lambda frame: movie.jumpToFrame(frame)) self._view.frame_slider.valueChanged.connect( lambda frame: self._view.frame_number.setText(str(frame))) self._frame_validator.setTop(frame_count) self._view.frame_number.returnPressed.connect( lambda: self._view.frame_slider.setValue( int(self._view.frame_number.text()))) _setup_starting_frame(current_frame=movie.currentFrameNumber(), last_frame=frame_count) self._view.set_speed_controls_visible(False) self._view.set_nav_controls_visible(True) @pyqtSlot() # QSlider::sliderReleased() def _speed_changed(self) -> None: speed = self._view.speed() if movie := self._view.movie(): movie.setSpeed(speed) self._play_movie()
class Simulator(QWidget): def __init__(self, *args, **kwargs): super(Simulator, self).__init__(*args, **kwargs) self.__simulation = SimulationData() self.__manage_window() self.__create_layouts() self.__create_buttons_and_inputs() self.__create_canvas() self.__manage_layouts() self.__connect_buttons() self.__set_timer() self.__change_initial_configuration() self.show() def __manage_window(self): self.setWindowTitle("2D Wave Equation Simulator") self.setFixedSize(1000, 860) def __create_layouts(self): self.__main_layout = QtWidgets.QVBoxLayout(self) self.__form_layout = QFormLayout(self) self.__start_stop_layout = QFormLayout(self) def __create_buttons_and_inputs(self): self.__start_button = QtWidgets.QPushButton("Start simulation", self) self.__stop_button = QtWidgets.QPushButton("Stop simulation", self) self.__start_button.setFixedWidth(485) self.__stop_button.setFixedWidth(485) self.__stop_button.setEnabled(False) self.__only_float = QRegExpValidator(QRegExp("-?[0-9]+\.?[0-9]+")) self.__only_float_time = QRegExpValidator(QRegExp("[0-9]+\.?[0-9]+")) self.__only_int = QIntValidator() self.__only_int.setBottom(0) self.__only_int.setTop(99) self.__label1 = QLabel("Number of points (X-axis):") self.__line1 = QLineEdit() self.__line1.setValidator(self.__only_int) self.__line1.setText("25") self.__label2 = QLabel("Number of points (Y-axis):") self.__line2 = QLineEdit() self.__line2.setValidator(self.__only_int) self.__line2.setText("25") self.__label3 = QLabel("Maximum simulation time [s]:") self.__line3 = QLineEdit() self.__line3.setValidator(self.__only_float_time) self.__line3.setText("1.0") self.__label4 = QPushButton("Alpha:") self.__label4.setFixedWidth(135) self.__line4 = QLineEdit() self.__line4.setValidator(self.__only_float) self.__line4.setText("0.0") self.__label5 = QPushButton("Beta:") self.__label5.setFixedWidth(135) self.__line5 = QLineEdit() self.__line5.setValidator(self.__only_float) self.__line5.setText("0.25") self.__label6 = QPushButton("Gamma:") self.__label6.setFixedWidth(135) self.__line6 = QLineEdit() self.__line6.setValidator(self.__only_float) self.__line6.setText("0.5") self.__label7 = QLabel("Fixed boundary conditions:") self.__line7 = QComboBox() self.__line7.addItems(["True", "False"]) self.__label8 = QLabel("Zero-displacement initial condition:") self.__line8 = QComboBox() self.__line8.addItems(["False", "True"]) self.__label9 = QLabel("Forcing term:") self.__line9 = QComboBox() self.__line9.addItems(["False", "True"]) def __create_canvas(self): self.__canvas = Canvas(self) self.__canvas.setFixedSize(980, 566) def __manage_layouts(self): self.__form_layout.addRow(self.__label1, self.__line1) self.__form_layout.addRow(self.__label2, self.__line2) self.__form_layout.addRow(self.__label3, self.__line3) self.__form_layout.addRow(self.__label4, self.__line4) self.__form_layout.addRow(self.__label5, self.__line5) self.__form_layout.addRow(self.__label6, self.__line6) self.__form_layout.addRow(self.__label7, self.__line7) self.__form_layout.addRow(self.__label8, self.__line8) self.__form_layout.addRow(self.__label9, self.__line9) self.__start_stop_layout.addRow(self.__start_button, self.__stop_button) self.__main_layout.addWidget(self.__canvas) self.__main_layout.addLayout(self.__form_layout) self.__main_layout.addLayout(self.__start_stop_layout) def __connect_buttons(self): self.__start_button.clicked.connect(lambda: self.__start_simulation()) self.__stop_button.clicked.connect(lambda: self.__stop_simulation()) self.__label4.clicked.connect(lambda: self.__show_alpha_description()) self.__label5.clicked.connect(lambda: self.__show_beta_description()) self.__label6.clicked.connect(lambda: self.__show_gamma_description()) self.__line1.textChanged.connect( lambda: self.__change_initial_configuration()) self.__line2.textChanged.connect( lambda: self.__change_initial_configuration()) self.__line3.textChanged.connect( lambda: self.__change_initial_configuration()) self.__line4.textChanged.connect( lambda: self.__change_initial_configuration()) self.__line5.textChanged.connect( lambda: self.__change_initial_configuration()) self.__line6.textChanged.connect( lambda: self.__change_initial_configuration()) self.__line7.currentTextChanged.connect( lambda: self.__change_initial_configuration()) self.__line8.currentTextChanged.connect( lambda: self.__change_initial_configuration()) self.__line9.currentTextChanged.connect( lambda: self.__change_initial_configuration()) def __show_alpha_description(self): title = "Description of Alpha parameter" description = "Alpha is the factor responsible for damping the membrane movement" self.__show_message(QMessageBox.Information, title, description) def __show_beta_description(self): title = "Description of Beta parameter" description = "Beta is the scalar parameter of the Newmark algorithm" self.__show_message(QMessageBox.Information, title, description) def __show_gamma_description(self): title = "Description of Gamma parameter" description = "Gamma is the scalar parameter of the Newmark algorithm" self.__show_message(QMessageBox.Information, title, description) def __show_message(self, message_type, title, description): self.__msg = QMessageBox() self.__msg.setIcon(message_type) self.__msg.setWindowTitle(title) self.__msg.setText(description) self.__msg.exec_() def __disable_gui(self): self.__stop_button.setEnabled(True) self.__start_button.setEnabled(False) self.__line1.setEnabled(False) self.__line2.setEnabled(False) self.__line3.setEnabled(False) self.__line4.setEnabled(False) self.__line5.setEnabled(False) self.__line6.setEnabled(False) self.__line7.setEnabled(False) self.__line8.setEnabled(False) self.__line9.setEnabled(False) self.__label4.setEnabled(False) self.__label5.setEnabled(False) self.__label6.setEnabled(False) def __enable_gui(self): self.__stop_button.setEnabled(False) self.__start_button.setEnabled(True) self.__line1.setEnabled(True) self.__line2.setEnabled(True) self.__line3.setEnabled(True) self.__line4.setEnabled(True) self.__line5.setEnabled(True) self.__line6.setEnabled(True) self.__line7.setEnabled(True) self.__line8.setEnabled(True) self.__line9.setEnabled(True) self.__label4.setEnabled(True) self.__label5.setEnabled(True) self.__label6.setEnabled(True) def __set_timer(self): self.__timer = QtCore.QTimer() self.__timer.setInterval(100) self.__timer.timeout.connect(self.__continue_simulation) def __change_initial_configuration(self): try: self.__n_x = int(self.__line1.text()) self.__n_y = int(self.__line2.text()) except: return if self.__n_x < 3 or self.__n_y < 3: return if self.__line8.currentText() == "False": self.__zero_diaphragm_displacement = False elif self.__line8.currentText() == "True": self.__zero_diaphragm_displacement = True self.__x_net = np.zeros(self.__n_x * self.__n_y, dtype=np.float64) self.__y_net = np.zeros(self.__n_x * self.__n_y, dtype=np.float64) for j in range(self.__n_y): for i in range(self.__n_x): self.__x_net[j * self.__n_x + i] = i * 1.0 / self.__n_x self.__y_net[j * self.__n_x + i] = j * 1.0 / self.__n_y first_step = self.__simulation.get_first_step( self.__n_x, self.__n_y, self.__zero_diaphragm_displacement) self.__max_value = first_step.max() + 0.0001 self.__min_value = -self.__max_value self.__canvas.axes.cla() self.__canvas.axes.set_xlabel("x [m]") self.__canvas.axes.set_ylabel("y [m]") self.__canvas.axes.set_zlabel("u [m]") if not self.__zero_diaphragm_displacement: self.__canvas.axes.set_zlim(self.__min_value, self.__max_value) else: self.__canvas.axes.set_zlim(-0.075, 0.075) self.__canvas.axes.set_title( "Diaphragm displacement diagram u(x, y, t) \n t = 0.0 s") self.__canvas.axes.scatter(self.__x_net, self.__y_net, first_step, linewidth=0, antialiased=False) self.__canvas.draw() def __start_simulation(self): self.__n_x = int(self.__line1.text()) self.__n_y = int(self.__line2.text()) if self.__n_x < 3 or self.__n_y < 3: title = "Warning" description = "Number of points for X-axis and Y-axis must be at least 3" self.__show_message(QMessageBox.Warning, title, description) return self.__t = float(self.__line3.text()) self.__alpha = float(self.__line4.text()) self.__beta = float(self.__line5.text()) self.__gamma = float(self.__line6.text()) if self.__line7.currentText() == "False": self.__fixed_boundary_conditions = False elif self.__line7.currentText() == "True": self.__fixed_boundary_conditions = True if self.__line8.currentText() == "False": self.__zero_diaphragm_displacement = False elif self.__line8.currentText() == "True": self.__zero_diaphragm_displacement = True if self.__line9.currentText() == "False": self.__forcing_term_check = False elif self.__line9.currentText() == "True": self.__forcing_term_check = True self.__delta_t = 0.01 self.__n_t = int(self.__t / self.__delta_t) self.__counter = 1 self.__simulation.change_initial_configuration( self.__n_x, self.__n_y, self.__t, self.__alpha, self.__beta, self.__gamma, self.__fixed_boundary_conditions, self.__zero_diaphragm_displacement, self.__forcing_term_check) self.__disable_gui() self.__simulation.start_simulation() self.__canvas.axes.cla() self.__canvas.axes.set_xlabel("x [m]") self.__canvas.axes.set_ylabel("y [m]") self.__canvas.axes.set_zlabel("u [m]") if not self.__zero_diaphragm_displacement: self.__canvas.axes.set_zlim(self.__min_value, self.__max_value) else: self.__canvas.axes.set_zlim(-0.075, 0.075) self.__canvas.axes.set_title( "Diaphragm displacement diagram u(x, y, t) \n t = 0.0 s") self.__canvas.axes.scatter(self.__x_net, self.__y_net, self.__simulation.get_actual_step(), linewidth=0, antialiased=False) self.__canvas.draw() self.__timer.start() def __continue_simulation(self): self.__canvas.axes.cla() self.__canvas.axes.set_xlabel("x [m]") self.__canvas.axes.set_ylabel("y [m]") self.__canvas.axes.set_zlabel("u [m]") if not self.__forcing_term_check: self.__canvas.axes.set_zlim(self.__min_value, self.__max_value) else: if self.__fixed_boundary_conditions or self.__simulation.get_actual_step( ).mean() < 0.05: self.__canvas.axes.set_zlim(-0.075, 0.075) self.__canvas.axes.set_title( "Diaphragm displacement diagram u(x, y, t) \n t = " + str(round(self.__counter * self.__delta_t, 2)) + " s") self.__canvas.axes.scatter(self.__x_net, self.__y_net, self.__simulation.get_actual_step(), linewidth=0, antialiased=False) self.__canvas.draw() if self.__counter < self.__n_t: self.__counter += 1 self.__simulation.calculate_next_step(self.__counter) else: self.__stop_simulation() def __stop_simulation(self): self.__timer.stop() self.__enable_gui()
def setUp(self): self.setWindowTitle("Settings") self.setSizeGripEnabled(False) self.layout = QGridLayout(self) self.layout.setSizeConstraint(QLayout.SetFixedSize) # --------------------------------------------------------------------- portValidator = QIntValidator(self) portValidator.setTop(65536) portValidator.setBottom(0) self.portStartEdit = QLineEdit(str(self.config['port_start']), self) self.portStartEdit.setValidator(portValidator) self.portEndEdit = QLineEdit(str(self.config['port_end']), self) self.portEndEdit.setValidator(portValidator) portsLayout = QHBoxLayout() portsLayout.addWidget(self.portStartEdit) portsLayout.addWidget(self.portEndEdit) self.layout.addWidget(QLabel("Listen port range:", self), 0, 0) self.layout.addLayout(portsLayout, 0, 1) # --------------------------------------------------------------------- speedValidator = QIntValidator(self) speedValidator.setBottom(0) maxDownloadSpeed = str(round(self.config['max_download_speed'] / 1024)) maxUploadSpeed = str(round(self.config['max_upload_speed'] / 1024)) self.maxDownSpeedEdit = QLineEdit(maxDownloadSpeed, self) self.maxDownSpeedEdit.setValidator(speedValidator) self.maxUpSpeedEdit = QLineEdit(maxUploadSpeed, self) self.maxUpSpeedEdit.setValidator(speedValidator) self.layout.addWidget(QLabel("Maximum download speed (KB/s):", self), 1, 0) self.layout.addWidget(self.maxDownSpeedEdit, 1, 1) self.layout.addWidget(QLabel("Maximum upload speed (KB/s):", self), 2, 0) self.layout.addWidget(self.maxUpSpeedEdit, 2, 1) # --------------------------------------------------------------------- torrentCountValidator = QIntValidator(self) torrentCountValidator.setTop(50) torrentCountValidator.setBottom(2) self.torrentCountEdit = QLineEdit(str(self.config['max_torrents']), self) self.torrentCountEdit.setValidator(torrentCountValidator) self.layout.addWidget(QLabel("Maximal torrent count:", self), 3, 0) self.layout.addWidget(self.torrentCountEdit, 3, 1) # --------------------------------------------------------------------- activeTorrentsValidator = QIntValidator(self) activeTorrentsValidator.setBottom(0) self.maxActiveDownloadsEdit = QLineEdit( str(self.config['max_active_downloads']), self) self.maxActiveDownloadsEdit.setValidator(activeTorrentsValidator) self.maxActiveSeedsEdit = QLineEdit( str(self.config['max_active_seeds']), self) self.maxActiveSeedsEdit.setValidator(activeTorrentsValidator) self.layout.addWidget(QLabel("Maximum active downloads:", self), 4, 0) self.layout.addWidget(self.maxActiveDownloadsEdit, 4, 1) self.layout.addWidget(QLabel("Maximum active seeds:", self), 5, 0) self.layout.addWidget(self.maxActiveSeedsEdit, 5, 1) # --------------------------------------------------------------------- self.resumeDataCheckbox = QCheckBox(self) self.resumeDataCheckbox.setChecked(self.config['resume_data'] == 1) self.layout.addWidget(QLabel("Enable resume data:", self), 6, 0) self.layout.addWidget(self.resumeDataCheckbox, 6, 1) # --------------------------------------------------------------------- buttonsRow = QHBoxLayout() OKButton = QPushButton("Apply", self) OKButton.setFocus() OKButton.clicked.connect(self.accept) cancelButton = QPushButton("Cancel", self) cancelButton.clicked.connect(self.reject) buttonsRow.addWidget(OKButton) buttonsRow.addWidget(cancelButton) self.layout.addLayout(buttonsRow, 7, 1)