예제 #1
0
    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)
예제 #2
0
 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
예제 #3
0
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
예제 #4
0
    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)
예제 #5
0
파일: io.py 프로젝트: darioflute/obsmaker
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
예제 #6
0
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)
예제 #8
0
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
예제 #9
0
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)
예제 #10
0
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()
예제 #11
0
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()
예제 #12
0
    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)