Esempio n. 1
1
class CustomWidget(QMainWindow):

    def __init__(self):
        """
        Constructor
        """
        QMainWindow.__init__(self)
        self.name = "Custom widget"
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        # TODO: This is ugly, improve it
        self.icon_path = JConfig().icons_path

        self._createLayout()

    def _createGui(self):
        """
        Subclasses must override this
        depending on the elements they want to add
        self._createOutputTree(),
        self._createOutputTable(),
        self._createOutputWindow() and add them to
        the corresponding layouts.
        """
        raise NotImplementedError

    def _createToolBar(self, name):
        """
        Subclasses need to define the
        specific Actions
        """
        self.toolbar = self.addToolBar(name)
        self.toolbar.setMovable(False)

    def _createLayout(self):
        """
        This creates the basic layout:
        Buttons & Outputs
        """

        # Layouts (This is a common disposition)
        main_layout = QVBoxLayout()
        self.button_layout = QHBoxLayout()
        output_layout = QVBoxLayout()

        # You will need to create your buttons
        # and add them to your layout like this:
        # self.button_layout.addWidget(button_1)

        # Output Layout Inner (QSplitter)
        # Add as many widgets as you please
        # They will be ordered vertically and
        # be resizable by the user
        # self.splitter.addWidget(self.table_label)
        # self.splitter.addWidget(...)
        self.splitter = QSplitter(QtCore.Qt.Vertical)

        # Nested layouts
        main_layout.addLayout(self.button_layout)
        output_layout.addWidget(self.splitter)
        main_layout.addLayout(output_layout)
        self.central_widget.setLayout(main_layout)

    def _createOutputWindow(self):
        """
        Some binary analysis commands will output to this.
        """

        self.output_label = QLabel('Output')

        self.output_window = QTextEdit()
        self.output_window.setFontPointSize(10)
        self.output_window.setReadOnly(True)
        # Save it for later use
        self.output_window.original_textcolor = self.output_window.textColor()

    def _createOutputTable(self):
        """
        A vanilla QTableWidget. Callbacks modify
        its properties, like number of columns, etc.
        """
        self.table_label = QLabel('Table Output')

        self.table = QTableWidget()
        self.table.setColumnCount(3)
        self.table.setColumnWidth(0, 100)
        self.table.setColumnWidth(1, 300)
        self.table.setColumnWidth(2, 300)

        self.table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)

        # Connect signals to slots
        self.table.customContextMenuRequested.connect(self._tablePopup)
        self.table.horizontalHeader().sectionDoubleClicked.connect(
            self._tableHeaderDoubleClicked)
        self.table.cellDoubleClicked.connect(self._tableCellDoubleClicked)

    def _createOutputTree(self):
        """
        A QtreeWidget. Initially used to display those pesky
        dword comparison to immediate values.
        """
        self.tree_label = QLabel('Tree Output')

        self.tree = QTreeWidget()
        self.tree.setColumnCount(3)
        self.tree.setColumnWidth(0, 150)
        self.tree.setColumnWidth(1, 150)
        self.tree.setColumnWidth(2, 50)

        # Connect signals to slots
        self.tree.itemDoubleClicked.connect(self._treeElementDoubleClicked)

    #################################################################
    # GUI Callbacks
    #################################################################
    def _console_output(self, s = "", err = False):
        """
        Convenience wrapper
        """
        if err:
            # Error message
            err_color = QColor('red')
            self.output_window.setTextColor(err_color)
            self.output_window.append(s)
            # restore original color
            self.output_window.setTextColor(
                self.output_window.original_textcolor)

        else:
            self.output_window.append(s)

    def _tableCellDoubleClicked(self, row, col):
        """
        Most of the info displayed in QTableWidgets represent addresses.
        Default action: try to jump to it.
        """
        it = self.table.item(row, col).text()

        try:
            addr = int(it, 16)
            jump_to_address(addr)

        except ValueError:
            self._console_output("[!] That does not look like an address...", err = True)
            return

    def _tablePopup(self, pos):
        """
        Popup menu activated clicking the secondary
        button on the table
        """
        menu = QMenu()

        # Add menu entries
        delRow = menu.addAction(QIcon(self.icon_path + "close.png"), "Delete Row")
        selItem = menu.addAction(
            QIcon(self.icon_path + "bookmark.png"), "Mark entry")
        menu.addSeparator()
        origFunc = menu.addAction(
            QIcon(self.icon_path + "lightning.png"), "Select origin function")
        destFunc = menu.addAction(
            QIcon(self.icon_path + "flag.png"), "Select destination function")

        # Get entry clicked
        action = menu.exec_(self.mapToGlobal(pos))

        # Dispatch :)
        if action == delRow:
            self.table.removeRow(self.table.currentRow())

        elif action == selItem:
            self.table.currentItem().setBackground(QColor('red'))

        elif action == origFunc:
            try:
                addr = self.table.currentItem().text()
                InfoUI.function_orig_ea = int(addr, 16)
            except Exception as e:
                self._console_output("[!] That does not look like an address...", err = True)

        elif action == destFunc:
            try:
                addr = self.table.currentItem().text()
                InfoUI.function_dest_ea = int(addr, 16)
            except Exception as e:
                self._console_output("[!] That does not look like an address...", err = True)

    def _tableHeaderDoubleClicked(self, index):
        """
        Used to sort the contents
        """
        self.table.sortItems(index, order = QtCore.Qt.AscendingOrder)

    def _treeElementDoubleClicked(self, item, column):
        """
        QTreeWidgetElement callback. Basically it jumps to
        the selected address in IDA disassembly window.
        """
        try:
            # Only interested in addresses
            addr_int = int(item.text(column), 16)
            jump_to_address(addr_int)
            # Paint some color
            item.setBackground(column, QColor('green'))
        except Exception as e:
            self._console_output("[!] That does not look like an address...", err = True)
Esempio n. 2
0
class window(QWidget):
    def __init__(self):
        super().__init__()
        self.grid = QGridLayout()
        self.text = QTextEdit()
        self.btn = QPushButton()
        self.btn.setText('Send')
        self.btn.clicked.connect(self.sendMessage)
        self.message = QLineEdit()

        self.grid.addWidget(self.text,1,1,2,2)
        self.grid.addWidget(self.message,3,1,1,1)
        self.grid.addWidget(self.btn,3,2,1,1)

        self.setLayout(self.grid)

        self.updateThread = updateThread()
        self.updateThread.signal.connect(self.updateMessages, Qt.QueuedConnection)
        self.updateThread.start()

    def sendMessage(self, signal):
        client.sendMessage(self.message.text())

    def updateMessages(self, signal):
        self.text.append(signal)
Esempio n. 3
0
class Edit(QWidget):

    def __init__(self, filename):
        super().__init__()

        self.filename = filename

        #Save and Cancel buttons, placed at the bottom of the window
        saveButton = QPushButton("Save")
        cancelButton = QPushButton("Cancel")
        saveButton.clicked.connect(self.save)
        cancelButton.clicked.connect(self.cancel)

        #Text edit field above the buttons
        #Containing all ingredients in the file, to be edited/removed/added to by the user
        self.ingredientEdit = QTextEdit()
        self.loadIngredients()

        #Set grid layout
        grid = QGridLayout()
        grid.setSpacing(10)

        #Add buttons, text field
        grid.addWidget(self.ingredientEdit, 1, 0, 5, 2)
        grid.addWidget(saveButton, 6, 0)
        grid.addWidget(cancelButton, 6, 1)

        self.setLayout(grid)
        self.setGeometry(800, 600, 350, 300)
        if filename == "ingredients.txt":
            self.setWindowTitle("My Ingredients")
        elif filename == "shoppinglist.txt":
            self.setWindowTitle("Shopping List")
        else:
            self.setWindowTitle(filename)

    # import ingredients from whichever file and put them in the text field
    # So that they can be edited by the user
    def loadIngredients(self):
        ingredients = whatsfordinner.importIngredients(self.filename)

        for i in ingredients:
            if (i != " ") and (i != "") and (i != None):
                self.ingredientEdit.append(i)

        self.ingredientEdit.repaint()

    # write ingredients to file
    def save(self):
        text = self.ingredientEdit.toPlainText()
        ingredients = text.split('\n')
        whatsfordinner.deleteIngredients(self.filename)
        whatsfordinner.writeIngredients(self.filename, ingredients)
        self.close()

    # close without writing
    def cancel(self):
        self.close()
Esempio n. 4
0
class ArchieveDialog(QtWidgets.QDialog):

    def __init__(self,parent, db):
        super(ArchieveDialog, self).__init__(parent)
        self.conversation = QTextEdit(self)
        self.combo = QComboBox(self)
        self.db = db
        self.initUI()

    def initUI(self):
        self.resize(300,300)
        for key, value in self.db.items():
            self.combo.addItem(key)
        self.conversation.move(0,20)
        self.combo.move(0, 0)
        self.combo.activated[str].connect(self.onActivated)

    def onActivated(self, text):
        self.conversation.clear()
        self.conversation.append(self.db[text])
Esempio n. 5
0
class ConsoleWidget(QWidget):

    def __init__(self, parent=None):
        super(ConsoleWidget, self).__init__(parent)

        self.textEdit = QTextEdit()
        self.textEdit.setFont(QFont('Consolas'))
        self.clearButton = QPushButton()
        self.clearButton.setText('Clear')

        self.vboxLayout = QVBoxLayout()
        self.vboxLayout.addWidget(self.textEdit)
        self.vboxLayout.addWidget(self.clearButton)
        self.setLayout(self.vboxLayout)

        self.clearButton.clicked.connect(self.clearConsoleTexts)

    def clearConsoleTexts(self):
        self.textEdit.clear()

    @pyqtSlot(str)
    def consoleOutput(self, msg):
        self.textEdit.append(msg)
Esempio n. 6
0
class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.instr = QLabel("Choose an extension and the link to download from", self)
        self.instr.move(20, 15)

        self.ext_label = QLabel("Extension: ", self)
        self.ext_label.move(20, 50)


        self.ext_input = QLineEdit(self)
        self.ext_input.move(115, 45)
        self.ext_input.returnPressed.connect(self.download)

        self.dom_label = QLabel("Link: ", self)
        self.dom_label.move(20, 90)

        self.dom_input = QLineEdit(self)
        self.dom_input.move(115, 85)
        self.dom_input.returnPressed.connect(self.download)

        self.dwl_but = QPushButton("Download", self)
        self.dwl_but.move(280,45)
        self.dwl_but.resize(100, 75)
        self.dwl_but.clicked.connect(self.download)

        self.dwl_bar = QProgressBar(self)
        self.dwl_bar.move(20, 125)
        self.dwl_bar.resize(360, 25)

        self.results = QTextEdit(self)
        self.results.move(20, 150)
        self.results.resize(360, 100)
        self.results.setReadOnly(True)



        self.setGeometry(300, 300, 400, 300)
        self.setFixedSize(400, 300)
        self.setWindowTitle("File Crawler")
        self.show()

    def download(self):
        self.results.setText("")
        file = str(QFileDialog.getExistingDirectory(self, "Onde salvar?"))
        if (file != ""):
            domain = self.dom_input.text()
            extension = self.ext_input.text()
            try:
                web_text = urlopen(domain, timeout=1.5).read().decode('utf-8', 'ignore')
            except ValueError:
                try:
                    domain = "http://"+domain
                    web_text = urlopen(domain, timeout=1.5).read().decode('utf-8', 'ignore')
                except Exception as e:
                    self.results.append(str(e))
                    web_text = None
            except Exception as e:
                self.results.append(str(e))
                web_text = None

            if web_text != None:
                double_b_file_pattern = re.compile("=\"([^(\'|\")]*\."+extension+")")
                simple_b_file_pattern = re.compile("=\'([^(\'|\")]*\."+extension+")")
                matches = double_b_file_pattern.findall(web_text)
                matches.extend(simple_b_file_pattern.findall(web_text))
            else:
                matches = []
            if len(matches) > 0:
                self.dwl_bar.setValue(0)
                self.results.append("Saving to " + file)
                self.results.append("%d files were found." % len(matches))
                for index, item in enumerate(matches, 1):
                    self.dwl_bar.setValue(int(100 * index / len(matches)))
                    try:
                        download(urljoin(domain, item), file + "/" + split(item)[-1])
                    except Exception as e:
                        # Document links may be broken, in this case, nothing to do.
                        self.results.append("Could not download {}, {}".format(split(item)[-1], e))
                self.results.append("Finished downloading.")
            else:
                self.results.append("Could not find any file.")
Esempio n. 7
0
class Example(QMainWindow):
    
    def __init__(self):
        super().__init__()
        self.copiedtext=""
        self.initUI()
        
        
    def initUI(self):               
        
        self.textEdit = QTextEdit()
        self.setCentralWidget(self.textEdit)
        self.textEdit.setText(" ")

        exitAction = QAction(QIcon('exit.png'), 'Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)
        
        newAction=QAction(QIcon('new.png'),'New',self)
        newAction.setShortcut('Ctrl+N')
        newAction.setStatusTip('New Application')
        newAction.triggered.connect(self.__init__)
        
        openAction=QAction(QIcon('open.png'),'Open',self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open Application')
        openAction.triggered.connect(self.openo)
        
        saveAction=QAction(QIcon('save.png'),'Save',self)
        saveAction.setShortcut('Ctrl+S')
        saveAction.setStatusTip('Save Application')
        saveAction.triggered.connect(self.save)
        
        undoAction=QAction(QIcon('undo.png'),'Undo',self)
        undoAction.setShortcut('Ctrl+Z')
        undoAction.setStatusTip('Undo')
        undoAction.triggered.connect(self.textEdit.undo)
        
        redoAction=QAction(QIcon('redo.png'),'Redo',self)
        redoAction.setShortcut('Ctrl+Y')
        redoAction.setStatusTip('Undo')
        redoAction.triggered.connect(self.textEdit.redo)
        
        copyAction=QAction(QIcon('copy.png'),'Copy',self)
        copyAction.setShortcut('Ctrl+C')
        copyAction.setStatusTip('Copy')
        copyAction.triggered.connect(self.copy)
        
        pasteAction=QAction(QIcon('paste.png'),'Paste',self)
        pasteAction.setShortcut('Ctrl+V')
        pasteAction.setStatusTip('Paste')
        pasteAction.triggered.connect(self.paste)
        
        cutAction=QAction(QIcon('cut.png'),'Cut',self)
        cutAction.setShortcut('Ctrl+X')
        cutAction.setStatusTip('Cut')
        cutAction.triggered.connect(self.cut)
        
        aboutAction=QAction('About',self)
        aboutAction.setStatusTip('About')
        aboutAction.triggered.connect(self.about)
        
        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(newAction)
        fileMenu.addAction(openAction)
        fileMenu.addAction(saveAction)
        fileMenu.addAction(exitAction)
        fileMenu2=menubar.addMenu('&Edit')
        fileMenu2.addAction(undoAction)
        fileMenu2.addAction(redoAction)
        fileMenu2.addAction(cutAction)
        fileMenu2.addAction(copyAction)
        fileMenu2.addAction(pasteAction)
        fileMenu3=menubar.addMenu('&Help')
        fileMenu3.addAction(aboutAction)
        

        tb1 = self.addToolBar('File')
        tb1.addAction(newAction)
        tb1.addAction(openAction)
        tb1.addAction(saveAction)
        
        tb2 = self.addToolBar('Edit')
        tb2.addAction(undoAction)
        tb2.addAction(redoAction)
        tb2.addAction(cutAction)
        tb2.addAction(copyAction)
        tb2.addAction(pasteAction)
        
        tb3 = self.addToolBar('Exit')
        tb3.addAction(exitAction)
        
        self.setGeometry(0,0,600,600)
        self.setWindowTitle('Text Editor')    
        self.setWindowIcon(QIcon('text.png')) 
        self.show()
    
    
        
    def closeEvent(self, event):
        
        reply = QMessageBox.question(self, 'Message',
            "Are you sure to quit without Saving?", QMessageBox.Yes | 
            QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.statusBar().showMessage('Quiting...')
            event.accept()
            
        else:
            event.ignore()
            self.save()
            event.accept()
            
    def openo(self):
        self.statusBar().showMessage('Open Text Files ')
        fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')
        self.statusBar().showMessage('Open File')
        if fname[0]:
            f = open(fname[0], 'r')

            with f:
                data = f.read()
                self.textEdit.setText(data)

    def save(self):
        self.statusBar().showMessage('Add extension to file name')
        fname =QFileDialog.getSaveFileName(self, 'Save File')
        data=self.textEdit.toPlainText()
        
        file=open(fname[0],'w')
        file.write(data)
        file.close()
    
    def copy(self):
        cursor=self.textEdit.textCursor()
        textSelected = cursor.selectedText()
        self.copiedtext=textSelected
    
    def paste(self):
        self.textEdit.append(self.copiedtext)
    
    def cut(self):
        cursor=self.textEdit.textCursor()
        textSelected=cursor.selectedText()
        self.copiedtext=textSelected
        self.textEdit.cut()
    
    def about(self):
        url ="https://en.wikipedia.org/wiki/Text_editor"
        self.statusBar().showMessage('Loading url...')
        webbrowser.open(url)
Esempio n. 8
0
class QWLoggerError(QGroupBox):
    """
    """
    def __init__(self, parent=None):

        QGroupBox.__init__(self, 'Error messages', parent)

        #cp.qwloggererror = self

        self.edi_err = QTextEdit()
        self.hbox = QHBoxLayout()
        self.hbox.addWidget(self.edi_err)
        self.setLayout(self.hbox)
        self.set_style()
        #self.set_tool_tips()

    def set_tool_tips(self):
        self.edi_err.setToolTip('Window for ERROR messages')

    def set_style(self):
        self.edi_err.setReadOnly(True)
        self.edi_err.setStyleSheet(style.styleYellowish)
        self.edi_err.setMinimumHeight(50)
        self.edi_err.setTextColor(Qt.red)

        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)

        self.setStyleSheet(style.qgrbox_title)
        self.layout().setContentsMargins(2, 0, 2, 2)

    def sizeHint(self):
        return QSize(300, 300)

    def append_qwlogger_err(self, msg='...'):
        self.edi_err.append(msg)
        self.scroll_down()

    def add_separator_err(self, sep='\n\n\n\n\n%s' % (50 * '_')):
        self.append_qwlogger_err(msg=sep)

    def scroll_down(self):
        #logger.debug('scroll_down')
        self.edi_err.moveCursor(QTextCursor.End)
        self.edi_err.repaint()
        #self.edi_err.update()

    def setReadOnly(self, state):
        self.edi_err.setReadOnly(state)

    def setStyleSheet(self, s):
        QGroupBox.setStyleSheet(self, s)
        #self.edi_err.setStyleSheet(s)

    def setTextColor(self, c):
        self.edi_err.setTextColor(c)

    def append(self, msg):
        self.edi_err.append(msg)

    #def closeEvent(self, e):
    #    logger.debug('QWLoggerError.closeEvent')
    #    QGroupBox.closeEvent(self, e)
    #    cp.qwloggererror = None

    if __name__ == "__main__":
        #if True:

        def key_usage(self):
            return 'Keys:'\
                   '\n  ESC - exit'\
                   '\n  M - add message in error logger window'\
                   '\n  S - add separator in error logger window'\
                   '\n'

        def keyPressEvent(self, e):
            if e.key() == Qt.Key_Escape:
                self.close()

            elif e.key() == Qt.Key_S:
                self.add_separator_err()

            elif e.key() == Qt.Key_M:
                self.append_qwlogger_err(msg='new message')

            else:
                logger.info(self.key_usage())
Esempio n. 9
0
class MyWidget(QWidget):
    NUM_THREADS = 5

    # sig_start = pyqtSignal()  # needed only due to PyCharm debugger bug (!)
    sig_abort_workers = pyqtSignal()

    def __init__(self):
        super().__init__()

        self.setWindowTitle("Thread Example")
        form_layout = QVBoxLayout()
        self.setLayout(form_layout)
        self.resize(400, 800)

        self.button_start_threads = QPushButton()
        self.button_start_threads.clicked.connect(self.start_threads)
        self.button_start_threads.setText("Start {} threads".format(
            self.NUM_THREADS))
        form_layout.addWidget(self.button_start_threads)

        self.button_stop_threads = QPushButton()
        self.button_stop_threads.clicked.connect(self.abort_workers)
        self.button_stop_threads.setText("Stop threads")
        self.button_stop_threads.setDisabled(True)
        form_layout.addWidget(self.button_stop_threads)

        self.log = QTextEdit()
        form_layout.addWidget(self.log)

        self.progress = QTextEdit()
        form_layout.addWidget(self.progress)

        QThread.currentThread().setObjectName(
            'main')  # threads can be named, useful for log output
        self.__workers_done = None
        self.__threads = None

    def start_threads(self):
        self.log.append('starting {} threads'.format(self.NUM_THREADS))
        self.button_start_threads.setDisabled(True)
        self.button_stop_threads.setEnabled(True)

        self.__workers_done = 0
        self.__threads = []
        for idx in range(self.NUM_THREADS):
            worker = Worker(idx)
            thread = QThread()
            thread.setObjectName('thread_' + str(idx))
            self.__threads.append(
                (thread,
                 worker))  # need to store worker too otherwise will be gc'd
            worker.moveToThread(thread)

            # get progress messages from worker:
            worker.sig_step.connect(self.on_worker_step)
            worker.sig_done.connect(self.on_worker_done)
            worker.sig_msg.connect(self.log.append)

            # control worker:
            self.sig_abort_workers.connect(worker.abort)

            # get read to start worker:
            # self.sig_start.connect(worker.work)  # needed due to PyCharm debugger bug (!); comment out next line
            thread.started.connect(worker.work)
            thread.start(
            )  # this will emit 'started' and start thread's event loop

        # self.sig_start.emit()  # needed due to PyCharm debugger bug (!)

    @pyqtSlot(int, str)
    def on_worker_step(self, worker_id: int, data: str):
        self.log.append('Worker #{}: {}'.format(worker_id, data))
        self.progress.append('{}: {}'.format(worker_id, data))

    @pyqtSlot(int)
    def on_worker_done(self, worker_id):
        self.log.append('worker #{} done'.format(worker_id))
        self.progress.append('-- Worker {} DONE'.format(worker_id))
        self.__workers_done += 1
        if self.__workers_done == self.NUM_THREADS:
            self.log.append('No more workers active')
            self.button_start_threads.setEnabled(True)
            self.button_stop_threads.setDisabled(True)
            # self.__threads = None

    @pyqtSlot()
    def abort_workers(self):
        self.sig_abort_workers.emit()
        self.log.append('Asking each worker to abort')
        for thread, worker in self.__threads:  # note nice unpacking by Python, avoids indexing
            thread.quit(
            )  # this will quit **as soon as thread event loop unblocks**
            thread.wait()  # <- so you need to wait for it to *actually* quit

        # even though threads have exited, there may still be messages on the main thread's
        # queue (messages that threads emitted before the abort):
        self.log.append('All threads exited')
Esempio n. 10
0
class TerminalWidget(QWidget):
    """
    The terminal widget handles sending commands to the serial port.
    It also handles receiving and displaying data from the serial port.

    The purpose behind the class is to abstract all interaction with the
    serial port away from the rest of the application so that commands
    can be constructed by other parts of the application then sent to
    the serial port through this class/widget, without having to deal
    with serial port communication in any way.

    The widget essentially provides a basic terminal interface, but also
    provides the ability for other modules to send commands to the serial
    port via the "send_command" method.
    """

    connectionError = pyqtSignal()

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        # Create the terminal widgets
        self.command_txt = QLineEdit()
        self.log = QTextEdit()
        self.log.setReadOnly(True)

        # Create the command buttons
        self.send_command_btn = QPushButton(QIcon(':/images/bullet_go.png'),
                                            '')
        self.clear_log_btn = QPushButton(QIcon(':/images/page_white.png'), '')

        # Create the form layout
        button_box = QHBoxLayout()
        button_box.addWidget(self.command_txt)
        button_box.addWidget(self.send_command_btn)
        button_box.addWidget(self.clear_log_btn)

        container = QVBoxLayout()
        container.addLayout(button_box)
        container.addWidget(self.log)

        self.setLayout(container)

        # Create a timer to read from the serial port
        self.read_timer = QTimer(self)

        # Connect the widgets
        self.command_txt.returnPressed.connect(self.send_line_command)
        self.send_command_btn.clicked.connect(self.send_line_command)
        self.clear_log_btn.clicked.connect(self.log.clear)
        self.log.textChanged.connect(self.scroll_log)
        self.read_timer.timeout.connect(self.read_serial_data)

    def connect_com_port(self):

        # Start the timer that reads the COM port
        self.read_timer.start(100)

        # Enable the GUI widgets
        self.command_txt.setEnabled(True)
        self.send_command_btn.setEnabled(True)
        self.clear_log_btn.setEnabled(True)
        self.log.setEnabled(True)

    def disconnect_com_port(self):

        # Stop the timer that reads the COM port
        self.read_timer.stop()

        # Close the COM port
        self.serial_conn.close()

        # Disable the GUI widgets
        self.command_txt.setDisabled(True)
        self.send_command_btn.setDisabled(True)
        self.clear_log_btn.setDisabled(True)
        self.log.setDisabled(True)

    def send_command(self, command):
        """
        Send a command to the serial port.

        The command is expected to be an AT command string. Leading and
        trailing white space is stripped from the command string.
        """
        command = str(command).strip()

        try:

            # Add a command marker in the terminal & send the command
            self.log.append('> ')
            self.serial_conn.write((command + '\r\n').encode('utf-8'))

        except serial.SerialException:
            QMessageBox.critical(
                self, self.tr('Serial Port Error'),
                self.tr(
                    'There was a communication error with the serial port.'),
                QMessageBox.Ok)

    def set_font(self, font):
        """
        Set the font of the terminal.

        Expects a QFont object as the parameter.
        """
        self.log.setFont(font)
        self.command_txt.setFont(font)

    def send_line_command(self):
        """
        Send a command from the "command_txt" line edit widget.
        """

        # Get the command text (cast to string and strip whitespace)
        command = str(self.command_txt.text()).strip()

        # Empty the text box and set focus
        self.command_txt.setText('')
        self.command_txt.setFocus()

        # Send the entered text as a command
        if command:
            self.send_command(command)

    def read_serial_data(self):
        """
        Read any buffered data from the serial port.

        This is invoked at regular intervals by the "read_timer"
        timer that is created in the class initializer.
        """
        try:
            buffer_size = self.serial_conn.inWaiting()
            if buffer_size:
                current_text = str(self.log.toPlainText())
                new_text = self.serial_conn.read(buffer_size).decode('utf-8')
                new_text = new_text.replace('\r', '')
                self.log.setText(current_text + new_text)

        except serial.SerialException:
            self.connectionError.emit()
            QMessageBox.critical(
                self, self.tr('Serial Port Error'),
                self.tr(
                    'There was a communication error with the serial port.'),
                QMessageBox.Ok)

    def scroll_log(self):
        """
        Moves the terminal log text cursor to the bottom of the text box.

        This is invoked every time the text changes in the terminal log
        so that the most current text is always shown.
        """
        cursor = self.log.textCursor()
        cursor.movePosition(QTextCursor.End)
        self.log.setTextCursor(cursor)
Esempio n. 11
0
class ResultTextWidget(QWidget):
    def __init__(self, parent=None, flags=Qt.WindowFlags()):
        super().__init__(parent=parent, flags=flags)
        self.mainLayout = QVBoxLayout()
        self.text = QTextEdit("Result:\n Not computed yet")
        
        self.mainLayout.addWidget(self.text)
        self.setLayout(self.mainLayout)
        
        StateManagement().computeTensionsSink.subscribe(self._showResult)
        
        
    
    def _showResult(self, res):
        self.text.setText(f"Result:\n")
        if res.error:
            self.text.append(f"Error: {res.error.__repr__()}")
            return
        self.text.append("  Joint angles (from proximal to distal):")
        for i, s in enumerate(res.states):
            self.text.append(f"    {i+1}-th joint: {math.degrees(s.bottomJointAngle)} deg")
        self.text.append(f"")
        self.text.append(f"  TF:\n{res.getTF(side='tr')}\n")
        self.text.append(f"  Tendon lengths:")
        for i, ts in enumerate(res.computeTendonLengths()):
            self.text.append(f"    {i+1}-th segment:")
            for j, t in enumerate(ts):
                self.text.append(f"     {j+1}-th tendon: {t}")
Esempio n. 12
0
    app = QApplication(sys.argv)

    portNames = map(lambda portInfo: portInfo.portName(),
                    QSerialPortInfo.availablePorts())

    portName, ok = QInputDialog.getItem(None,
                                        'Serial port',
                                        'Select the serial port',
                                        portNames,
                                        editable=False)

    if not ok:
        sys.exit(1)

    board = QBoard(portName)
    board.open()

    textEdit = QTextEdit()

    appendMessage = lambda message: textEdit.append('<i>{}</i>'.format(message)
                                                    )

    appendValue = lambda value: textEdit.append('<b>{}</b>'.format(value))

    board.receivedMessage.connect(appendMessage)
    board.receivedValue.connect(appendValue)

    textEdit.show()

    sys.exit(app.exec_())
Esempio n. 13
0
class Talking_win(QMainWindow):
    update_signal = pyqtSignal(str)
    recv_file_signal = pyqtSignal(list)
    confirm_path_signal = pyqtSignal()  # 点击另存为按钮则确认文件的保存路径

    #askfor_signal = pyqtSignal()  # 工作线程用于请求文件路径
    def __init__(self, one_client, account):
        super().__init__()
        self.initUI(account)
        self.account = account
        self.update_signal.connect(self.update_text)
        self.recv_file_signal.connect(self.remind_recv_file)
        self.confirm_path_signal.connect(self.confirm_path)
        #self.askfor_signal.connect(self.askfor_filepath)
        self.one_client = one_client

        self.one_client.recv_for_longtime(self.update_signal,
                                          self.recv_file_signal)

    def initUI(self, account):
        self.now_color = QColor(0, 0, 0)
        self.setGeometry(300, 300, 450, 300)
        self.setWindowTitle('Welcome!' + account)
        self.Create_centre_widget()
        self.Create_layout(account)
        self.show()

    def Create_centre_widget(self):
        self.cen_wid = QWidget()
        self.setCentralWidget(self.cen_wid)

    def Create_layout(self, account):
        self.cen_wid.mainlayout = QVBoxLayout()
        qhboxlayout = QHBoxLayout()
        rich_text_layout = QHBoxLayout()  # 用于创建富文本

        #创建一些控件,并将控件放到水平布局中
        self.profile_photo = Mylabel(self, account)
        temp_map = QPixmap(
            os.path.dirname(os.path.abspath(sys.argv[0])) + "\\" +
            "profile.jpg")
        self.profile_photo.setPixmap(temp_map.scaled(QSize(30, 25)))
        self.profile_photo.setFixedSize(30, 25)
        self.nameline = QLineEdit(self)
        self.nameline.setPlaceholderText("请输入对方用户名")

        self.color_btn = QPushButton("", self)
        self.color_btn.setIcon(
            QIcon(
                os.path.dirname(os.path.abspath(sys.argv[0])) + '\\' +
                "flower.jpg"))
        self.color_btn.clicked.connect(self.Change_color)
        qhboxlayout.addWidget(self.profile_photo)
        qhboxlayout.addWidget(self.nameline)

        rich_text_layout.addWidget(self.color_btn)
        #创建发送信息框和显示框
        self.send_meage_text = QTextEdit()
        self.send_meage_text.setAcceptRichText(True)
        self.send_display_text = QTextEdit()
        self.send_display_text.setAcceptRichText(True)

        #创建发送信息按钮
        self.send_btn = QPushButton("发送", self)
        self.send_btn.clicked.connect(self.Send_message)

        #将水平布局,显示框,发送框和发送按钮整合到垂直布局
        self.cen_wid.mainlayout.addLayout(qhboxlayout)
        self.cen_wid.mainlayout.addWidget(self.send_display_text)
        # 添加包含一个富文本的控件和字体粗细控件的部件
        self.cen_wid.mainlayout.addLayout(rich_text_layout)
        self.cen_wid.mainlayout.addWidget(self.send_meage_text)
        self.cen_wid.mainlayout.addWidget(self.send_btn)
        self.cen_wid.setLayout(self.cen_wid.mainlayout)

    def update_text(self, msg):
        self.send_display_text.append(msg)

    def remind_recv_file(self, source_filename):
        if "file_win" not in dir(self):
            self.file_win = Ui_SubWindow(source_filename,
                                         self.confirm_path_signal)
            self.file_win.show()
        else:
            self.file_win.addfile(source_filename, self.confirm_path_signal)

    def confirm_path(self):
        """
        将要接收(保存)的文件传递给client对象的temp_file
        """
        if self.one_client.temp_filename.empty():
            for btn in self.file_win.available.keys():
                if self.file_win.available[btn][1] and (
                        not self.file_win.available[btn][2]):
                    self.one_client.temp_filename.put(
                        self.file_win.available[btn][0])
                    self.one_client.target_file.put(
                        self.file_win.btn_dict[btn][0])
                    self.file_win.available[btn][2] = True
                    break

    # def askfor_filepath(self):
    # if "available" in dir(self.file_win):
    # for btn in self.file_win.available.keys():
    # if self.file_win.available[btn][1] and (not self.file_win.available[btn][2]):
    # self.one_client.temp_filename = self.file_win.available[btn][0]
    # self.one_client.target_file = self.file_win.btn_dict[btn][0]
    # self.file_win.available[2] = True
    # break

    def Send_message(self):
        #发送信息,并在显示框显示
        target_name = self.nameline.text()  #获取想要进行聊天的用户名
        msg = target_name + (10 - len(
            target_name.encode())) * ' ' + self.send_meage_text.toPlainText()
        self.one_client.send(msg, self.account)  #接受server返回的信息
        self.send_display_text.setTextColor(self.now_color)
        msg = "to " + msg[:10] + "\n" + msg[10:]
        self.send_display_text.append(msg)
        self.send_meage_text.clear()

    def Change_color(self):
        self.now_color = QColorDialog.getColor()
        self.send_meage_text.setTextColor(self.now_color)
Esempio n. 14
0
class GUI(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        # 执行时间标签
        self.time=QLabel('',self)
        self.time.move(100,80)
        self.time.resize(200, 20)
        # NMAE标签
        self.sid = QLabel('NAME', self)
        self.sid.move(25, 50)
        self.sid.resize(50, 20)
        # ID搜索框
        self.searchBar = QLineEdit(self)
        self.searchBar.move(100, 30)
        self.searchBar.resize(450,50)
        # 搜索按钮
        self.searchButton = QPushButton("Search",self)
        self.searchButton.move(600, 30)
        self.searchButton.resize(80,50)
        # 清空按钮
        self.clearButton = QPushButton("Clear", self)
        self.clearButton.move(700, 30)
        self.clearButton.resize(80, 50)

        # entity_id
        self.entity_id = QLabel('ENTITY_ID', self)
        self.entity_id.move(15, 140)
        self.entity_id.resize(50, 20)
        self.entity_idEdit=QTextEdit(self)
        self.entity_idEdit.move(100, 120)
        self.entity_idEdit.resize(680,60)

        # type
        self.type = QLabel('TYPE', self)
        self.type.move(15, 200)
        self.type.resize(50, 20)
        self.typeEdit = QTextEdit(self)
        self.typeEdit.move(100, 180)
        self.typeEdit.resize(680, 60)

        #len
        self.len = QLabel('LEN', self)
        self.len.move(15, 260)
        self.len.resize(80, 20)
        self.lenEdit = QTextEdit(self)
        self.lenEdit.move(100, 240)
        self.lenEdit.resize(680, 60)

        # lable
        self.lable = QLabel('LABLE', self)
        self.lable.move(15, 320)
        self.lable.resize(80, 20)
        self.lableEdit = QTextEdit(self)
        self.lableEdit.move(100, 300)
        self.lableEdit.resize(680, 160)

        #description
        self.description = QLabel('DESCRIPTION', self)
        self.description.move(15, 380)
        self.description.resize(80, 20)
        self.descriptionEdit = QTextEdit(self)
        self.descriptionEdit.move(100, 360)
        self.descriptionEdit.resize(680, 60)

        # alise
        self.aliases = QLabel('ALISE', self)
        self.aliases.move(15, 440)
        self.aliases.resize(80, 20)
        self.aliasesEdit = QTextEdit(self)
        self.aliasesEdit.move(100, 400)
        self.aliasesEdit.resize(680, 60)

        # site
        self.site = QLabel('SITE', self)
        self.site.move(15, 500)
        self.site.resize(80, 20)
        self.siteEdit = QTextEdit(self)
        self.siteEdit.move(100, 460)
        self.siteEdit.resize(680, 60)

        # title
        self.title = QLabel('TITLE', self)
        self.title.move(15, 560)
        self.title.resize(80, 20)
        self.titleEdit = QTextEdit(self)
        self.titleEdit.move(100, 520)
        self.titleEdit.resize(680, 60)

        self.resize( 800, 650)
        self.center()
        self.setWindowTitle('WikiData---Qs1 ID-Search')
        self.setWindowIcon(QIcon('icon.jpg'))
        self.show()
        self.searchButton.clicked.connect(self.fun)
        self.clearButton.clicked.connect(self.clear)


    def fun(self):
        start = time.clock()
        queryname=self.searchBar.text()


        sql1 = "SELECT entity_id FROM web_main WHERE lable = '%s'" % (queryname)
        cur.execute(sql1)
        entity_id = str(cur.fetchall()).replace('\'','').replace(',','').replace('(','').replace(')','')
        con.commit()
       # print("entity_id")
        self.entity_idEdit.append(entity_id)

        sql2 = "SELECT type FROM web_main WHERE lable = '%s'" % (queryname)
        cur.execute(sql2)
        type = str(cur.fetchall()).replace('\'', '').replace(',', '').replace('(', '').replace(')', '')
        #print("1111111")
        con.commit()
        self.typeEdit.append(type)

        sql3 = "SELECT description FROM web_main WHERE lable = '%s'" % (queryname)
        cur.execute(sql3)
        description = str(cur.fetchall()).replace('\'', '').replace(',', '').replace('(', '').replace(')', '')
        con.commit()
        self.descriptionEdit.append(description)

        sql4 = "SELECT aliase FROM web_main WHERE lable = '%s'" % (queryname)
        cur.execute(sql4)
        aliases = str(cur.fetchall()).replace('\'', '').replace(',', '').replace('(', '').replace(')', '')
        con.commit()
        self.aliasesEdit.append(aliases)

        sql5 = "SELECT len FROM web_main WHERE lable = '%s'" % (queryname)
        cur.execute(sql5)
        len = str(cur.fetchall()).replace('\'', '').replace(',', '').replace('(', '').replace(')', '')
        con.commit()
        self.lenEdit.append(len)

        sql6 = "SELECT lable FROM web_main WHERE lable = '%s'" % (queryname)
        cur.execute(sql6)
        lable= str(cur.fetchall()).replace('\'', '').replace(',', '').replace('(', '').replace(')', '')
        con.commit()
        self.lableEdit.append(lable)

        sql7 = "SELECT site FROM web_main WHERE lable = '%s'" % (queryname)
        cur.execute(sql7)
        site = str(cur.fetchall()).replace('\'', '').replace(',', '').replace('(', '').replace(')', '')
        con.commit()
        self.siteEdit.append(site)

        sql8 = "SELECT title FROM web_main WHERE lable = '%s'" % (queryname)
        cur.execute(sql8)
        title = str(cur.fetchall()).replace('\'', '').replace(',', '').replace('(', '').replace(')', '')
        con.commit()
        self.titleEdit.append(title)


        end = time.clock()
        ex_time = 'Execution Time:' + str(end - start)
        # print(ex_time)
        self.time.setText(ex_time)


    def clear(self):
        self.searchBar.setText('')
        self.entity_idEdit.setText('')
        self.typeEdit.setText('')
        self.descriptionEdit.setText('')
        self.aliasesEdit.setText('')
        self.lenEdit.setText('')
        self.lableEdit.setText('')
        self.siteEdit.setText('')
        self.titleEdit.setText('')
        self.rhashEdit.setText('')
        self.rlableEdit.setText('')
        self.snakorderEdit.setText('')
        self.time.setText('')

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def closeEvent(self, event):
        reply = QMessageBox.question(self, 'Message',
                                     "Are you sure to exit?", QMessageBox.Yes |
                                     QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
Esempio n. 15
0
class TemplateBuildWidgets(QWidget):
    # 构造方法
    def __init__(self):
        super().__init__()
        self.template_name_edit = None
        self.fq_condition_edit = None
        self.fq_target_edit = None
        self.template_sentence_edit = None
        self.input_btn = None
        self.analysis_result = None
        self.build_template_btn = None
        self.template_build_result_edit = None
        self.init_ui()

    # GUI创建
    def init_ui(self):
        self.create_template_build_widgets()
        # 窗口信息设置
        self.setGeometry(200, 200, 1000, 800)
        self.setWindowTitle("模板创建")
        self.setWindowIcon(QIcon("images/cat.jpg"))
        self.show()

    # 创建模板查看与创建控件
    def create_template_build_widgets(self):
        # 输入模板名
        tip_name_text = QLabel("请在以下文本框中输入模板名")
        tip_name_hbox = QHBoxLayout()
        tip_name_hbox.addWidget(tip_name_text)
        template_name_text = QLabel("模板名")
        self.template_name_edit = QLineEdit()
        template_name_hbox = QHBoxLayout()
        template_name_hbox.addWidget(template_name_text)
        template_name_hbox.addWidget(self.template_name_edit)

        # 输入问句条件词
        tip_fq_condition_text = QLabel("输入问句条件词(英文名称在前且唯一,后面可跟多个中文解释)如:\n"
                                       "school 学校 高校")
        tip_fq_condition_hbox = QHBoxLayout()
        tip_fq_condition_hbox.addWidget(tip_fq_condition_text)
        fq_condition_text = QLabel("问句条件词")
        self.fq_condition_edit = QTextEdit()
        fq_condition_hbox = QHBoxLayout()
        fq_condition_hbox.addWidget(fq_condition_text)
        fq_condition_hbox.addWidget(self.fq_condition_edit)

        # 输入问句目标词
        tip_fq_target_text = QLabel("输入问句目标词(英文名称在前且唯一,后面可跟多个中文解释)如:\n"
                                    "numbers 招生人数 招生计划 招多少人 招生计划是多少 招生人数是多少")
        tip_fq_target_hbox = QHBoxLayout()
        tip_fq_target_hbox.addWidget(tip_fq_target_text)
        fq_target_text = QLabel("问句目标词")
        self.fq_target_edit = QTextEdit()
        fq_target_hbox = QHBoxLayout()
        fq_target_hbox.addWidget(fq_target_text)
        fq_target_hbox.addWidget(self.fq_target_edit)

        # 输入问句模板及对应的答句模板
        tip_template_sentence_text = QLabel("每行输入完整的模板句示例及对应的答案句模板,如:\n"
                                            "(school)(year)(major)(district)(classy)(numbers)\n"
                                            "(school)(year)(major)(district)(classy)招收(numbers)人")
        tip_template_sentence_hbox = QHBoxLayout()
        tip_template_sentence_hbox.addWidget(tip_template_sentence_text)
        template_sentence_text = QLabel("模板字段")
        self.template_sentence_edit = QTextEdit()
        template_sentence_hbox = QHBoxLayout()
        template_sentence_hbox.addWidget(template_sentence_text)
        template_sentence_hbox.addWidget(self.template_sentence_edit)

        self.input_btn = QPushButton("输入以上信息")
        self.input_btn.clicked.connect(self.analysis_input)
        input_btn_hbox = QHBoxLayout()
        input_btn_hbox.addWidget(self.input_btn)

        # 分析字段并返回给用户
        analysis_result_text = QLabel("字段分析结果")
        self.analysis_result = QTextEdit()
        analysis_result_hbox = QHBoxLayout()
        analysis_result_hbox.addWidget(analysis_result_text)
        analysis_result_hbox.addWidget(self.analysis_result)

        # 字段确认,进入模板构造阶段
        self.build_template_btn = QPushButton("模板构造")
        self.build_template_btn.clicked.connect(self.build_template)
        build_template_btn_hbox = QHBoxLayout()
        build_template_btn_hbox.addWidget(self.build_template_btn)

        # 构造模板显示
        template_build_result_text = QLabel("构造模板")
        self.template_build_result_edit = QTextEdit()
        template_build_result_hbox = QHBoxLayout()
        template_build_result_hbox.addWidget(template_build_result_text)
        template_build_result_hbox.addWidget(self.template_build_result_edit)

        main_vbox = QVBoxLayout()
        main_vbox.addLayout(tip_name_hbox)
        main_vbox.addLayout(template_name_hbox)
        main_vbox.addLayout(tip_fq_condition_hbox)
        main_vbox.addLayout(fq_condition_hbox)
        main_vbox.addLayout(tip_fq_target_hbox)
        main_vbox.addLayout(fq_target_hbox)
        main_vbox.addLayout(tip_template_sentence_hbox)
        main_vbox.addLayout(template_sentence_hbox)
        main_vbox.addLayout(input_btn_hbox)
        main_vbox.addLayout(analysis_result_hbox)
        main_vbox.addLayout(build_template_btn_hbox)
        main_vbox.addLayout(template_build_result_hbox)
        self.setLayout(main_vbox)

    # 确认用户输入字段,返回分析结果
    def analysis_input(self):
        name = self.template_name_edit.text()
        fq_condition = self.fq_condition_edit.toPlainText().strip()
        fq_target = self.fq_target_edit.toPlainText().strip()
        template_sentence = self.template_sentence_edit.toPlainText().strip().replace("(", "(").replace(")", ")")
        self.analysis_result.clear()
        if name == "":
            self.analysis_result.append("模板名为空!")
        else:
            self.analysis_result.append("模板名:" + name)
        if fq_condition == "":
            self.analysis_result.append("问句条件词为空!")
        else:
            self.analysis_result.append("问句条件词:")
            fq_condition_list = fq_condition.split("\n")
            for fqc in fq_condition_list:
                self.analysis_result.append(fqc)
        if fq_target == "":
            self.analysis_result.append("问句目标词为空!")
        else:
            self.analysis_result.append("问句目标词:")
            fq_target_list = fq_target.split("\n")
            for fqt in fq_target_list:
                self.analysis_result.append(fqt)
        if template_sentence == "":
            self.analysis_result.append("答句模板为空!")
        else:
            self.analysis_result.append("答句模板:")
            template_sentence_list = template_sentence.split("\n")
            for sentence in template_sentence_list:
                self.analysis_result.append(sentence)
        self.analysis_result.append("请确认以上字段对应关系和模板句,确认无误后点击模板构造按钮")

    # 构造模板
    def build_template(self):
        name = self.template_name_edit.text()
        fq_condition = self.fq_condition_edit.toPlainText().strip()
        fq_target = self.fq_target_edit.toPlainText().strip()
        template_sentence = self.template_sentence_edit.toPlainText().strip().replace("(", "(").replace(")", ")")

        self.template_build_result_edit.clear()
        if name == "":
            self.template_build_result_edit.append("模板名为空!")
        elif fq_condition == "":
            self.template_build_result_edit.append("问句条件词为空!")
        elif fq_target == "":
            self.template_build_result_edit.append("问句目标词为空!")
        elif template_sentence == "":
            self.template_build_result_edit.append("答句模板为空!")
        if name == "" or fq_condition == "" or fq_target == "" or template_sentence == "":
            self.template_build_result_edit.append("请填充以上为空的模块后再构造模板!")

        if name != "" and fq_condition != "" and fq_target != "" and template_sentence != "":
            fq_condition_list = fq_condition.split("\n")
            fq_target_list = fq_target.split("\n")
            template_sentence_list = template_sentence.split("\n")
            ts_question = [template_sentence_list[i_question]
                           for i_question in range(0, len(template_sentence_list), 2)]
            ts_answer = [template_sentence_list[i_answer]
                         for i_answer in range(1, len(template_sentence_list), 2)]
            template_root_path = "../TemplateLoad/Template"
            build_template_by_infos(template_root_path + "/" + name, fq_condition_list, fq_target_list, ts_question,
                                    ts_answer)
            self.template_build_result_edit.clear()
            self.template_build_result_edit.append("构造的模板句式如下:")
            fq_condition, fq_target, ts_answers, ts_questions \
                = load_template_by_file(template_root_path + "/" + name)
            self.template_build_result_edit.append("模板答案句如下:")
            for i_answer in range(len(ts_answers)):
                self.template_build_result_edit.append(str(i_answer) + "--" + ts_answers[i_answer])
            self.template_build_result_edit.append("模板问题句如下:")
            for sentence in ts_questions:
                self.template_build_result_edit.append(sentence)
Esempio n. 16
0
class TemplateCheckWidgets(QWidget):
    # 构造方法
    def __init__(self):
        super().__init__()
        self.query_current_template_btn = None
        self.template_combo = None
        self.template_fields_edit = None
        self.template_sentence_edit = None
        self.build_template_btn = None
        self.template_build_wid = None
        self.init_ui()

    # GUI创建
    def init_ui(self):
        self.create_template_check_widgets()
        # 窗口信息设置
        self.setGeometry(200, 200, 1000, 800)
        self.setWindowTitle("模板查看")
        self.setWindowIcon(QIcon("images/cat.jpg"))
        self.show()

    # 创建模板查看与创建控件
    def create_template_check_widgets(self):
        # 当前模板查看(查询按钮+模板显示下拉框、横向布局)
        self.query_current_template_btn = QPushButton("查看当前模板")
        self.query_current_template_btn.clicked.connect(self.template_query)

        current_template_text = QLabel("当前模板")
        self.template_combo = QComboBox()
        self.template_combo.activated[str].connect(self.template_combo_activated)

        select_hbox = QHBoxLayout()
        select_hbox.addWidget(self.query_current_template_btn)
        select_hbox.addWidget(current_template_text)
        select_hbox.addWidget(self.template_combo)

        # 模板字段部分
        template_fields_text = QLabel("模板字段")
        self.template_fields_edit = QTextEdit()

        template_fields_hbox = QHBoxLayout()
        template_fields_hbox.addWidget(template_fields_text)
        template_fields_hbox.addWidget(self.template_fields_edit)

        # 模板句式部分
        template_sentence_text = QLabel("模板句式")
        self.template_sentence_edit = QTextEdit()

        template_sentence_hbox = QHBoxLayout()
        template_sentence_hbox.addWidget(template_sentence_text)
        template_sentence_hbox.addWidget(self.template_sentence_edit)

        # 创建模板
        self.build_template_btn = QPushButton("创建模板")
        self.build_template_btn.clicked.connect(self.turn_page_template_build)
        template_build_hbox = QHBoxLayout()
        template_build_hbox.addWidget(self.build_template_btn)

        main_vbox = QVBoxLayout()
        main_vbox.addLayout(select_hbox)
        main_vbox.addLayout(template_fields_hbox)
        main_vbox.addLayout(template_sentence_hbox)
        main_vbox.addLayout(template_build_hbox)
        self.setLayout(main_vbox)

    # 查看当前模板
    def template_query(self):
        template_path = "../TemplateLoad/Template"
        file_list = read_all_file_list(template_path)
        template_file = [file.split("\\")[-1] for file in file_list]
        self.template_combo.clear()
        self.template_combo.addItems(template_file)

    # 当点击某个模板时
    def template_combo_activated(self, text):
        template_path = "../TemplateLoad/Template"
        fq_condition, fq_target, ts_answers, ts_questions = load_template_by_file(template_path + "/" + text)
        self.template_fields_edit.clear()
        self.template_fields_edit.append("问句条件词:")
        self.template_fields_edit.append(str(fq_condition))
        self.template_fields_edit.append("问句目标词:")
        for word in fq_target:
            self.template_fields_edit.append(word)

        self.template_sentence_edit.clear()
        self.template_sentence_edit.append("答句模板:")
        for sentence in ts_answers:
            self.template_sentence_edit.append(sentence)
        self.template_sentence_edit.append("问句模板:")
        for sentence in ts_questions:
            self.template_sentence_edit.append(sentence)

    # 跳转到模板创造页面
    def turn_page_template_build(self):
        self.template_build_wid = TemplateBuildWidgets()
        self.template_build_wid.show()
Esempio n. 17
0
class MySQLWidgets(QWidget):
    # 构造方法
    def __init__(self):
        super().__init__()
        self.table_combo = None
        self.school_combo = None
        self.district_combo = None
        self.year_combo = None
        self.major_combo = None
        self.batch_combo = None
        self.classy_combo = None
        self.SQL_edit = None
        self.result_edit = None
        self.query_btn = None
        self.query_table_name = None
        self.query_school_name = None
        self.query_district_name = None
        self.query_year_name = None
        self.query_major_name = None
        self.query_classy_name = None
        self.init_ui()

    # GUI创建
    def init_ui(self):
        self.create_mysql_widgets()
        # 窗口信息设置
        self.setGeometry(200, 200, 500, 800)
        self.setWindowTitle("MySQL数据表查询")
        self.setWindowIcon(QIcon("images/cat.jpg"))
        self.show()

    # 创建MySQL查询控件
    def create_mysql_widgets(self):
        table = QLabel("表类型")
        school = QLabel("学校")
        province = QLabel("地区")
        year = QLabel("年份")
        major = QLabel("专业")
        batch = QLabel("批次")
        classy = QLabel("科别")

        self.table_combo = QComboBox()
        table_names = ["计划招生", "专业分数", "地区分数"]
        self.table_combo.addItems(table_names)
        self.table_combo.activated[str].connect(self.table_combo_activated)

        self.school_combo = QComboBox()
        self.school_combo.activated[str].connect(self.school_combo_activated)

        self.district_combo = QComboBox()
        self.district_combo.activated[str].connect(self.district_combo_activated)

        self.year_combo = QComboBox()
        self.year_combo.activated[str].connect(self.year_combo_activated)
        self.major_combo = QComboBox()
        self.major_combo.activated[str].connect(self.major_combo_activated)
        self.batch_combo = QComboBox()
        self.classy_combo = QComboBox()
        self.classy_combo.activated[str].connect(self.classy_combo_activated)

        select_hbox = QHBoxLayout()
        select_hbox.addWidget(table)
        select_hbox.addWidget(self.table_combo)
        select_hbox.addWidget(school)
        select_hbox.addWidget(self.school_combo)
        select_hbox.addWidget(province)
        select_hbox.addWidget(self.district_combo)
        select_hbox.addWidget(year)
        select_hbox.addWidget(self.year_combo)
        select_hbox.addWidget(major)
        select_hbox.addWidget(self.major_combo)
        select_hbox.addWidget(batch)
        select_hbox.addWidget(self.batch_combo)
        select_hbox.addWidget(classy)
        select_hbox.addWidget(self.classy_combo)

        sql = QLabel("SQL语句")
        self.SQL_edit = QLineEdit()
        sql_hbox = QHBoxLayout()
        sql_hbox.addWidget(sql)
        sql_hbox.addWidget(self.SQL_edit)

        result = QLabel("查询结果")
        self.result_edit = QTextEdit()
        result_hbox = QHBoxLayout()
        result_hbox.addWidget(result)
        result_hbox.addWidget(self.result_edit)

        self.query_btn = QPushButton("查询")

        btn_hbox = QHBoxLayout()
        btn_hbox.addWidget(self.query_btn)
        self.query_btn.clicked.connect(self.mysql_query)

        main_vbox = QVBoxLayout()
        main_vbox.addLayout(select_hbox)
        main_vbox.addLayout(sql_hbox)
        main_vbox.addLayout(result_hbox)
        main_vbox.addLayout(btn_hbox)
        self.setLayout(main_vbox)

    # 设置SQL语句编辑框内的SQL语句
    def set_SQLedit_content(self):
        self.SQL_edit.clear()
        mysql_string = "select * from "
        if self.query_table_name is not None:
            mysql_string += self.query_table_name
        if self.query_school_name is not None:
            mysql_string += " where school='" + self.query_school_name + "'"
        if self.query_district_name is not None:
            mysql_string += " and district ='" + self.query_district_name + "'"
        if self.query_year_name is not None:
            mysql_string += " and year='" + self.query_year_name + "'"
        if self.query_major_name is not None:
            mysql_string += " and major='" + self.query_major_name + "'"
        if self.query_classy_name is not None:
            mysql_string += " and classy='" + self.query_classy_name + "'"
        mysql_string += ";"
        self.SQL_edit.setText(mysql_string)

    # mysql查询
    def mysql_query(self):
        mysql_string = self.SQL_edit.text()
        if mysql_string != "":
            pass
        else:
            mysql_string = self.build_mysql_string()
            self.SQL_edit.setText(mysql_string)
        myresult = mysql_query_sentence(mysql_string)
        if len(myresult) == 0:
            self.result_edit.setText("查询结果为空!")
            return
        self.result_edit.clear()
        for item in myresult:
            self.result_edit.append(str(item))
        return myresult

    # 构造SQL语句
    def build_mysql_string(self):
        mysql_string = "select * from " + self.query_table_name + " where school='" + self.query_school_name \
                       + "' and district='" + self.query_district_name + "' and year='" + self.query_year_name \
                       + "';"
        return mysql_string

    # table_combo发生改变
    def table_combo_activated(self, text):
        table_names = ["计划招生", "专业分数", "地区分数"]
        mysql_table_name = ["admission_plan", "admission_score_major", "admission_score_pro"]
        self.query_table_name = mysql_table_name[table_names.index(text)]
        # 查询当前选择下(表名)学校数据项
        mysql_string = "select school from " + self.query_table_name + " group by school;"
        myresult = mysql_query_sentence(mysql_string)
        temp = []
        for item in myresult:
            temp.append(item["school"])
        school_names = temp
        # 重新设置school_combo
        self.school_combo.clear()
        school_names = sorted(school_names, key=lambda x: lazy_pinyin(x.lower())[0][0])
        self.school_combo.addItems(school_names)
        self.set_SQLedit_content()

    # school_combo发生改变
    def school_combo_activated(self, text):
        self.query_school_name = text
        # 查询当前选择下(表名、学校)地区数据项
        mysql_string = "select district from " + self.query_table_name + " where school='" + self.query_school_name \
                       + "' group by district;"
        myresult = mysql_query_sentence(mysql_string)
        temp = []
        for item in myresult:
            temp.append(item["district"])
        district_names = temp
        # 重新设置major_combo
        self.district_combo.clear()
        district_names = sorted(district_names, key=lambda x: lazy_pinyin(x.lower())[0][0])
        self.district_combo.addItems(district_names)
        self.set_SQLedit_content()

    # district_combo发生改变
    def district_combo_activated(self, text):
        self.query_district_name = text
        # 查询当前选择下(表名、学校、地区)年份数据项
        mysql_string = "select year from " + self.query_table_name + " where school='" + self.query_school_name \
                       + "' and district='" + self.query_district_name + "' group by year;"
        myresult = mysql_query_sentence(mysql_string)
        temp = []
        for item in myresult:
            temp.append(str(item["year"]))
        year_names = temp
        # 重新设置year_combo
        self.year_combo.clear()
        year_names.sort()
        self.year_combo.addItems(year_names)
        self.set_SQLedit_content()

    # year_combo发生改变
    def year_combo_activated(self, text):
        self.query_year_name = text
        self.set_SQLedit_content()

        # 查询并设置major专业
        if self.query_table_name == "admission_score_pro":
            self.major_combo.clear()
            self.major_combo.addItem("无此项数据")
        else:
            mysql_string = "select major from " + self.query_table_name + " where school='" + self.query_school_name \
                           + "' and district='" + self.query_district_name + "' and year='" + self.query_year_name \
                           + "' group by major;"
            myresult = mysql_query_sentence(mysql_string)
            temp = []
            for item in myresult:
                temp.append(item["major"])
            major_names = temp
            # 重新设置major_combo
            self.major_combo.clear()
            major_names = sorted(major_names, key=lambda x: lazy_pinyin(x.lower())[0][0])
            self.major_combo.addItems(major_names)

        # 查询并设置batch批次
        if self.query_table_name == "admission_score_pro":
            mysql_string = "select batch from " + self.query_table_name + " where school='" + self.query_school_name \
                           + "' and district='" + self.query_district_name + "' and year='" + self.query_year_name \
                           + "' group by batch;"
            myresult = mysql_query_sentence(mysql_string)
            temp = []
            for item in myresult:
                temp.append(item["batch"])
            batch_names = temp
            # 重新设置classy_combo
            self.batch_combo.clear()
            batch_names = sorted(batch_names, key=lambda x: lazy_pinyin(x.lower())[0][0])
            self.batch_combo.addItems(batch_names)
        else:
            self.batch_combo.clear()
            self.batch_combo.addItem("无此项数据")

        # 查询并设置classy科别
        mysql_string = "select classy from " + self.query_table_name + " where school='" + self.query_school_name \
                       + "' and district='" + self.query_district_name + "' and year='" + self.query_year_name \
                       + "' group by classy;"
        myresult = mysql_query_sentence(mysql_string)
        temp = []
        for item in myresult:
            temp.append(item["classy"])
        classy_names = temp
        # 重新设置classy_combo
        self.classy_combo.clear()
        classy_names = sorted(classy_names, key=lambda x: lazy_pinyin(x.lower())[0][0])
        self.classy_combo.addItems(classy_names)

    # major_combo发生改变
    def major_combo_activated(self, text):
        if text != "":
            self.query_major_name = text
            self.set_SQLedit_content()

    # classy_combo发生改变
    def classy_combo_activated(self, text):
        if text != "":
            self.query_classy_name = text
            self.set_SQLedit_content()
Esempio n. 18
0
class QAWidgets(QWidget):
    # 构造方法
    def __init__(self):
        super().__init__()
        self.clear_btn = None
        self.qa_btn = None
        self.question_edit = None
        self.answer_edit = None
        self.init_ui()

    # GUI创建
    def init_ui(self):
        self.create_qa_widgets()

    # 创建问答控件
    def create_qa_widgets(self):
        question = QLabel('Question')
        answer = QLabel('Answer')

        # 按钮
        self.clear_btn = QPushButton('清空')
        self.clear_btn.clicked.connect(self.clear_button)
        self.qa_btn = QPushButton('回答提问')
        self.qa_btn.clicked.connect(self.question_answer)

        # 编辑文本框
        self.question_edit = QLineEdit(self)
        self.answer_edit = QTextEdit(self)
        self.question_edit.returnPressed.connect(self.question_answer)

        # 布局方式
        question_hbox = QHBoxLayout()
        question_hbox.addWidget(question)
        question_hbox.addWidget(self.question_edit)

        answer_hbox = QHBoxLayout()
        answer_hbox.addWidget(answer)
        answer_hbox.addWidget(self.answer_edit)

        button_box = QHBoxLayout()
        button_box.addStretch(1)
        button_box.addWidget(self.clear_btn)
        button_box.addWidget(self.qa_btn)

        vbox = QVBoxLayout()
        vbox.addLayout(question_hbox)
        vbox.addLayout(answer_hbox)
        vbox.addLayout(button_box)

        self.setLayout(vbox)

    # 回答提出的问题
    def question_answer(self):
        self.answer_edit.clear()
        sentence = self.question_edit.text()
        sentence_type = self.question_type_predict(sentence)
        if sentence_type not in question_can_answer:
            self.answer_edit.append("抱歉,当前系统无法回答关于%s的问题,尝试问问其它问题!" % sentence_type)
        else:
            # hanlp方法
            mid_result, result_edit = answer_question_by_template(sentence)
            self.answer_edit.append("问句类型:" + sentence_type)
            self.answer_edit.append("分词列表:" + str(mid_result["segment_list"]))
            self.answer_edit.append("问题抽象结果:" + str(mid_result["ab_question"]))
            self.answer_edit.append("关键词列表:" + str(mid_result["keyword"]))
            self.answer_edit.append("正则化处理:" + str(mid_result["keyword_normalize"]))
            self.answer_edit.append("匹配问句模板:" + str(mid_result["match_template_question"]))
            self.answer_edit.append("匹配答句模板:" + str(mid_result["match_template_answer"]))
            if "mysql_string" in mid_result:
                self.answer_edit.append("查询语句:" + str(mid_result["mysql_string"]))
            if "search_result" in mid_result:
                self.answer_edit.append("查询结果:" + str(mid_result["search_result"]))
            self.answer_edit.append("回答如下:")
            for item in result_edit:
                self.answer_edit.append(item)

    # 判断问题类型,优先级:关键词>模板>模型
    def question_type_predict(self, sentence):
        # 使用关键词判断
        sentence_type = QAPage.question_type_predict_keyword.question_predict_by_keyword(sentence)
        if sentence_type:
            return sentence_type
        else:
            # 使用模板判断
            sentence_type = QAPage.question_type_predict_template.question_predict_by_template(sentence)
            if sentence_type:
                return sentence_type
            else:
                # 使用模型判断
                sentence_type = QAPage.question_type_predict_model.question_predict_by_fastText(sentence)
                return sentence_type

    # 清空按钮状态
    def clear_button(self):
        self.question_edit.clear()
        self.answer_edit.clear()
Esempio n. 19
0
class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'Hello world'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.goods = []

        self.readGoods()
        self.initUI()
        self.resetFields()
        self.addToOrderBtn.setDisabled(True)
        self.backBtn.setVisible(False)
        self.successLabel.setVisible(False)

    def readGoods(self):
        with open("src/input.txt", "r") as f:
            n = int(f.readline())
            for i in range(n):
                title = f.readline().strip()
                description = f.readline().strip()
                cost = int(f.readline())
                self.goods.append({
                    "title": title,
                    "description": description,
                    "cost": cost
                })

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.createGridLayout()
        self.setLayout(self.gridLayout)

        self.show()

    def createGridLayout(self):
        self.gridLayout = QGridLayout()
        self.gridLayout.setSpacing(10)

        self.createTable()

        self.descriptionTextLabel = QLabel("Описание товара")
        self.descriptionText = QLineEdit()

        self.orderInfoLabel = QLabel("Информация о заказе")
        self.orderInfo = QTextEdit()

        self.totalCostLabel = QLabel("Стоимость заказа")
        self.totalCost = QLineEdit()

        self.successLabel = QLabel("Заказ успешно оформлен")

        self.addToOrderBtn = QPushButton("Добавить")
        self.newOrderBtn = QPushButton("Новый заказ")
        self.saveOrderBtn = QPushButton("Сохранить заказ")
        self.backBtn = QPushButton("Назад")
        self.addToOrderBtn.clicked.connect(self.onAddToOrderBtnClick)
        self.newOrderBtn.clicked.connect(self.resetFields)
        self.saveOrderBtn.clicked.connect(self.onSaveOrderBtnClick)
        self.backBtn.clicked.connect(self.onBackBtnClick)

        self.gridLayout.addWidget(self.orderInfoLabel, 1, 0)
        self.gridLayout.addWidget(self.orderInfo, 2, 0, 1, 1)
        self.gridLayout.addWidget(self.tableWidget, 2, 1, 1, 2)
        self.gridLayout.addWidget(self.descriptionTextLabel, 3, 1, 1, 2)
        self.gridLayout.addWidget(self.descriptionText, 4, 1, 1, 2)
        self.gridLayout.addWidget(self.totalCostLabel, 3, 0)
        self.gridLayout.addWidget(self.totalCost, 4, 0, 1, 1)
        self.gridLayout.addWidget(self.addToOrderBtn, 5, 0)
        self.gridLayout.addWidget(self.newOrderBtn, 5, 1)
        self.gridLayout.addWidget(self.saveOrderBtn, 5, 2)
        self.gridLayout.addWidget(self.backBtn, 6, 0)
        self.gridLayout.addWidget(self.successLabel, 6, 1)

    def onAddToOrderBtnClick(self):
        self.orderInfo.append(
            self.goods[self.tableWidget.currentRow()]["title"] + " " +
            str(self.goods[self.tableWidget.currentRow()]["cost"]))
        self.totalCost.setText(
            str(
                int(self.totalCost.text()) +
                self.goods[self.tableWidget.currentRow()]["cost"]))

    def onSaveOrderBtnClick(self):
        with open("src/output.txt", "w") as f:
            f.writelines(self.orderInfo.toPlainText())

        self.backBtn.setVisible(True)
        self.successLabel.setVisible(True)

    def onBackBtnClick(self):
        self.resetFields()
        self.backBtn.setVisible(False)
        self.successLabel.setVisible(False)

    def createTable(self):
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(len(self.goods))
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableWidget.setHorizontalHeaderLabels(["Товар", "Цена"])

        for i in range(len(self.goods)):
            self.tableWidget.setItem(i, 0,
                                     QTableWidgetItem(self.goods[i]["title"]))
            self.tableWidget.setItem(
                i, 1, QTableWidgetItem(str(self.goods[i]["cost"])))
            self.tableWidget.item(i, 0).setBackground(
                QColor(220, 220, 220) if i % 2 == 0 else QColor(255, 255, 255))
            self.tableWidget.item(i, 1).setBackground(
                QColor(220, 220, 220) if i % 2 == 0 else QColor(255, 255, 255))

        self.tableWidget.clicked.connect(self.on_click)

    def resetFields(self):
        self.orderInfo.setText("")
        self.totalCost.setText("0")

    @pyqtSlot()
    def on_click(self):
        self.addToOrderBtn.setDisabled(False)
        for currentQTableWidgetItem in self.tableWidget.selectedItems():
            self.descriptionText.setText(
                self.goods[currentQTableWidgetItem.row()]["description"])
Esempio n. 20
0
class CentralWidget(QWidget):
    startCalcSig = pyqtSignal(list, str, list, str)

    def __init__(self, parent):
        super().__init__(parent)
        self.initui()
        self.calcThread = SegQualityMetricsThread(None, None, None, None)


    def initui(self):

        mainVBox = QVBoxLayout()

        self.gtLabelImageSelect = FileSelect(title='Ground Truth Label Image',
                                        dialogDefaultPath=None,
                                        dialogFileTypeFilter='Label Image(*.tif)',
                                        dialogTitle='Choose Ground Truth Label Image'
                                        )
        self.testFolder = DirSelect(title='Folder containing test images',
                               dialogTitle='Choose folder containing test images',
                               dialogDefaultPath=None)


        mainVBox.addWidget(self.gtLabelImageSelect)
        mainVBox.addWidget(self.testFolder)

        tableActionButtons = QHBoxLayout()
        mainVBox.addLayout(tableActionButtons)

        refreshButton = QPushButton('Load Tiff Files in TestFolder')
        refreshButton.clicked.connect(self.loadTiffs)

        self.tiffFiles = []

        tableActionButtons.addWidget(refreshButton)

        self.tiffTable = QTableWidget()
        self.loadTable()
        mainVBox.addWidget(self.tiffTable)

        self.opDirSelect = DirSelect(title='Output Folder',
                               parent=self,
                               dialogTitle='Choose folder OutputFolder',
                               dialogDefaultPath=None)
        mainVBox.addWidget(self.opDirSelect)

        runGroupBox = QGroupBox(self)
        runBox = QHBoxLayout()

        runControlBox = QVBoxLayout()
        startButton = QPushButton('Run')
        startButton.clicked.connect(self.runSegQualMetrics)

        self.interruptButton = QPushButton('Interrupt')

        runControlBox.addWidget(startButton)
        runControlBox.addWidget(self.interruptButton)

        self.outputDisplay = QTextEdit()
        self.outputDisplay.setReadOnly(True)

        runBox.addWidget(self.outputDisplay)
        runBox.addLayout(runControlBox)
        runGroupBox.setLayout(runBox)

        mainVBox.addWidget(runGroupBox)

        self.setLayout(mainVBox)

    def initSegQualPy(self):

        oneDirUp = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
        self.segQualPy = os.path.join(oneDirUp, 'dist', 'segQualMetricsMultiTest',
                                      'segQualMetricsMultiTest.exe')

    def getcheckedTiffList(self):

        checkedTiffFiles = []
        checkedTiffFileLabels = []
        for rowInd in range(self.tiffTable.rowCount()):
            item = self.tiffTable.cellWidget(rowInd, 0)
            label = self.tiffTable.cellWidget(rowInd, 1).text()
            if item.isChecked():
                checkedTiffFiles.append(self.tiffFiles[rowInd])
                checkedTiffFileLabels.append(label)
        return checkedTiffFiles, checkedTiffFileLabels

    def runSegQualMetrics(self):

        checkedTiffFiles, checkedTiffFileLabels = self.getcheckedTiffList()
        gtLabelImage = self.gtLabelImageSelect.getText()
        outputDir = self.opDirSelect.getText()
        currentData = 'ground Truth Image File:\n{}\n\ntest images:\n{}.\n' \
                       .format(gtLabelImage, '\n'.join(checkedTiffFiles))
        checkMessage = currentData + 'Are you sure you want to proceed?'
        reply = QMessageBox.question(self, 'Check Parameters', checkMessage,
                                     QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel)

        if reply == QMessageBox.Yes:

            self.calcThread.__init__(checkedTiffFiles,
                                   gtLabelImage,
                                   checkedTiffFileLabels,
                                   outputDir)
            try:
                self.calcThread.start()
                self.outputDisplay.append('Calculating metrics for:\n{}\nPlease Wait. The program may take '
                                          'a few minutes to finish......'.format(currentData))
            except Exception as e:
                self.outputDisplay.append('The Program has encoutered an error. Here is the error message:\n'
                                          '{}'.format(str(e)))
                self.calcThread.terminated
            self.interruptButton.clicked.connect(self.termicateCalc)
            self.calcThread.finished.connect(self.handleSQMFinished)

    def termicateCalc(self):
        self.calcThread.terminated = True
        self.calcThread.terminate()
        self.calcThread.wait()


    def handleSQMFinished(self):

        if self.calcThread.terminated:
            self.outputDisplay.append('Calculation Terminated. No Output generated.')
        else:
            self.outputDisplay.append('Finished Succesfully. '
                                          'Metrics written into {}'.format(self.opDirSelect.getText()))

    def loadTiffs(self):

        testFolder = self.testFolder.getText()

        if not os.path.isdir(testFolder):
            raiseInfo('Invalid Test Folder: {}'.format(testFolder), self)
        else:
            self.tiffFiles = getAllFilesInTree(testFolder, '.tif')

        self.loadTable()


    def loadTable(self):

        self.tiffTable.setRowCount(len(self.tiffFiles))
        self.tiffTable.setColumnCount(2)
        self.tiffTable.setHorizontalHeaderLabels(['Tiff File', 'Label'])

        for ind, tifffile in enumerate(self.tiffFiles):

            shortenedTiffFilePath = getShortenedPath(tifffile)
            checkBox = QCheckBox(shortenedTiffFilePath, self)
            checkBox.setChecked(1)
            self.tiffTable.setCellWidget(ind, 0, checkBox)

            label = QLineEdit(self)
            label.setText('File{}'.format(ind + 1))
            self.tiffTable.setCellWidget(ind, 1, label)

        self.tiffTable.resizeColumnsToContents()
Esempio n. 21
0
class RF_Qt(QMainWindow):
    """
    Class to create the main GUI window. It extends QMainWindow.
    The GUI allows the user to load up to four font files, provide a new font name, adjust some options,
    view a preview of font changes, and finally generate new TrueType font files.
    """

    def __init__(self):
        """
        Create the main window.
        :return:
        """
        super(RF_Qt, self).__init__()

        # Define variables
        self.fnt_styles = ["Regular", "Italic", "Bold", "Bold Italic"]
        self.fnt_sty_combo_list = []
        self.fnt_file_name_list = []
        self.font_files = None
        self.font_info = FontInfo()
        # Create a QProcess object, and connect it to appropriate slots
        self.cli_process = QProcess(self)
        self.cli_process.setProcessChannelMode(QProcess.MergedChannels)
        self.cli_process.readyRead.connect(self.read_proc_output)
        self.cli_process.started.connect(self.manage_proc)
        self.cli_process.finished.connect(self.manage_proc)
        self.cli_process.error.connect(self.manage_proc)

        # Style for all groupbox labels
        gb_style = "QGroupBox { font-weight: bold; }"
        # Top level layout manager for the window.
        win_layout = QVBoxLayout()
        gb_fnt_files = QGroupBox("Font Files")
        gb_fnt_files.setStyleSheet(gb_style)
        grid_f_f = QGridLayout()
        grid_pos = 0

        # Font Files and styles #

        # Create a grid of font names with their respective font style combo boxes
        for i in range(len(self.fnt_styles)):
            self.fnt_file_name_list.append(QLabel("Load font file..."))
            cmb = QComboBox()
            cmb.addItem("")
            cmb.addItems(self.fnt_styles)
            cmb.setEnabled(False)
            cmb.setToolTip(
                "<qt/>If not automatically detected when the font is added, allows you to select what font "
                "sub-family the font file belongs to"
            )
            self.fnt_sty_combo_list.append(cmb)
            row, col = helper.calc_grid_pos(grid_pos, 2)
            grid_f_f.addWidget(self.fnt_file_name_list[i], row, col)
            grid_pos += 1
            row, col = helper.calc_grid_pos(grid_pos, 2)
            grid_f_f.addWidget(self.fnt_sty_combo_list[i], row, col)
            grid_pos += 1
        grid_f_f.setColumnStretch(0, 1)
        gb_fnt_files.setLayout(grid_f_f)
        win_layout.addWidget(gb_fnt_files)

        # New Font Name #
        gb_fnt_name = QGroupBox("Font Family Name")
        gb_fnt_name.setStyleSheet(gb_style)
        hb_fnt_name = QHBoxLayout()
        self.new_fnt_name = QLineEdit()
        self.new_fnt_name.setToolTip("Enter a name for the modified font.")
        self.new_fnt_name.textEdited[str].connect(self.set_family_name)
        hb_fnt_name.addWidget(self.new_fnt_name)
        gb_fnt_name.setLayout(hb_fnt_name)
        win_layout.addWidget(gb_fnt_name)

        # Options #
        hb_options = QHBoxLayout()

        ## Kerning, Panose, Alt. Name ##
        gb_basic_opt = QGroupBox("Basic Options")
        gb_basic_opt.setStyleSheet(gb_style)
        hb_basic_opt = QHBoxLayout()
        self.basic_opt_list = []
        basic_tooltips = (
            "<qt/>Some readers and software require 'legacy', or 'old style' kerning to be "
            "present for kerning to work.",
            "<qt/>Kobo readers can get confused by PANOSE settings. This option sets all "
            "PANOSE information to 0, or 'any'",
            "<qt/>Some fonts have issues with renaming. If the generated font does not have "
            "the same internal font name as you entered, try enabling this option.",
        )

        for opt, tip in zip(("Legacy Kerning", "Clear PANOSE", "Alt. Name"), basic_tooltips):
            self.basic_opt_list.append(QCheckBox(opt))
            self.basic_opt_list[-1].setToolTip(tip)
            hb_basic_opt.addWidget(self.basic_opt_list[-1])

        gb_basic_opt.setLayout(hb_basic_opt)
        hb_options.addWidget(gb_basic_opt)

        ## Hinting ##
        gb_hint_opt = QGroupBox("Hinting Option")
        gb_hint_opt.setStyleSheet(gb_style)
        hb_hint_opt = QHBoxLayout()
        self.hint_opt_list = []
        hint_tooltips = (
            "<qt/>Keep font hinting as it exists in the orginal font files.<br />"
            "In most cases, this will look fine on most ebook reading devices.",
            '<qt/>Some fonts are manually, or "hand" hinted for specific display types (such as LCD). '
            "These fonts may not look good on other display types such as e-ink, therefore they can be "
            "removed.",
            "<qt/>If you don't like the original hinting, but you want your font to be hinted, "
            "this option will auto hint your font.",
        )
        for opt, tip in zip(("Keep Existing", "Remove Existing", "AutoHint"), hint_tooltips):
            self.hint_opt_list.append(QRadioButton(opt))
            self.hint_opt_list[-1].setToolTip(tip)
            self.hint_opt_list[-1].toggled.connect(self.set_hint)
            hb_hint_opt.addWidget(self.hint_opt_list[-1])

        self.hint_opt_list[0].setChecked(Qt.Checked)
        gb_hint_opt.setLayout(hb_hint_opt)
        hb_options.addWidget(gb_hint_opt)

        win_layout.addLayout(hb_options)

        ## Darken ##
        gb_dark_opt = QGroupBox("Darken Options")
        gb_dark_opt.setStyleSheet(gb_style)
        hb_dark_opt = QHBoxLayout()
        self.darken_opt = QCheckBox("Darken Font")
        self.darken_opt.setToolTip("<qt/>Darken, or add weight to a font to make it easier to read on e-ink screens.")
        self.darken_opt.toggled.connect(self.set_darken_opt)
        hb_dark_opt.addWidget(self.darken_opt)
        self.mod_bearing_opt = QCheckBox("Modify Bearings")
        self.mod_bearing_opt.setToolTip(
            "<qt/>By default, adding weight to a font increases glyph width. Enable this "
            "option to set the glyph width to be roughly equal to the original.<br/><br/>"
            "WARNING: This reduces the spacing between glyphs, and should not be used if "
            "you have added too much weight."
        )
        self.mod_bearing_opt.toggled.connect(self.set_mod_bearing)
        self.mod_bearing_opt.setEnabled(False)
        hb_dark_opt.addWidget(self.mod_bearing_opt)

        self.lbl = QLabel("Darken Amount:")
        self.lbl.setEnabled(False)
        hb_dark_opt.addWidget(self.lbl)
        self.darken_amount_opt = QSlider(Qt.Horizontal)
        self.darken_amount_opt.setMinimum(1)
        self.darken_amount_opt.setMaximum(50)
        self.darken_amount_opt.setValue(12)
        self.darken_amount_opt.setEnabled(False)
        self.darken_amount_opt.setToolTip(
            "<qt/>Set the amount to darken a font by. 50 is considered turning a "
            "regular weight font into a bold weight font. It is not recommended to "
            "darken a font that much however."
        )
        self.darken_amount_opt.valueChanged[int].connect(self.set_darken_amount)
        hb_dark_opt.addWidget(self.darken_amount_opt)
        self.darken_amount_lab = QLabel()
        self.darken_amount_lab.setText(str(self.darken_amount_opt.value()))
        self.darken_amount_lab.setEnabled(False)
        hb_dark_opt.addWidget(self.darken_amount_lab)
        gb_dark_opt.setLayout(hb_dark_opt)

        win_layout.addWidget(gb_dark_opt)

        # Buttons #
        hb_buttons = QHBoxLayout()
        # hb_buttons.addStretch()
        self.gen_ttf_btn = QPushButton("Generate TTF")
        self.gen_ttf_btn.setEnabled(False)
        self.gen_ttf_btn.setToolTip(
            "<qt/>Generate a new TrueType font based on the options chosen in this program. "
            "<br /><br />"
            "The new fonts are saved in a directory of your choosing."
        )
        self.gen_ttf_btn.clicked.connect(self.gen_ttf)
        hb_buttons.addWidget(self.gen_ttf_btn)
        self.load_font_btn = QPushButton("Load Fonts")
        self.load_font_btn.setToolTip("<qt/>Load font files to modify.")
        self.load_font_btn.clicked.connect(self.load_fonts)
        hb_buttons.addWidget(self.load_font_btn)
        self.prog_bar = QProgressBar()
        self.prog_bar.setRange(0, 100)
        hb_buttons.addWidget(self.prog_bar)
        win_layout.addLayout(hb_buttons)

        # Output Log #
        gb_log_win = QGroupBox("Log Window")
        gb_log_win.setStyleSheet(gb_style)
        vb_log = QVBoxLayout()
        out_font = QFont("Courier")
        out_font.setStyleHint(QFont.Monospace)
        self.log_win = QTextEdit()
        self.log_win.setAcceptRichText(False)
        self.log_win.setFont(out_font)
        vb_log.addWidget(self.log_win)
        gb_log_win.setLayout(vb_log)
        win_layout.addWidget(gb_log_win)

        # Show Window #
        self.setCentralWidget(QWidget(self))
        self.centralWidget().setLayout(win_layout)
        self.setWindowTitle("Readify Font")

        self.show()

        # Check if fontforge is actually in users PATH. If it isn't, prompt user to provice a location
        self.ff_path = helper.which("fontforge")
        if not self.ff_path:
            self.set_ff_path()

    def set_ff_path(self):
        """
        Let user choose location of fontforge
        :return:
        """
        QMessageBox.warning(
            self,
            "Fontforge Missing!",
            "FontForge is not in your PATH! If it is installed, " "please locate it now.",
            QMessageBox.Ok,
            QMessageBox.Ok,
        )
        path = QFileDialog.getOpenFileName(self, "Locate FontForge...")
        if path[0]:
            self.ff_path = os.path.normpath(path[0])

    def set_basic_opt(self):
        """
        Handler to set basic options
        :return:
        """
        opt = self.sender()
        if opt.isChecked():
            if "kerning" in opt.text().lower():
                self.font_info.leg_kern = True
            if "panose" in opt.text().lower():
                self.font_info.strip_panose = True
            if "alt" in opt.text().lower():
                self.font_info.name_hack = True
        else:
            if "kerning" in opt.text().lower():
                self.font_info.leg_kern = False
            if "panose" in opt.text().lower():
                self.font_info.strip_panose = False
            if "alt" in opt.text().lower():
                self.font_info.name_hack = False

    def set_family_name(self, name):
        """
        Handler to set name option. Also checks if buttons need enabling
        :param name:
        :return:
        """
        if name:
            if helper.valid_filename(name):
                self.font_info.font_name = name
                if self.font_files:
                    self.gen_ttf_btn.setEnabled(True)
            else:
                self.gen_ttf_btn.setEnabled(False)
        else:
            self.gen_ttf_btn.setEnabled(False)

    def set_darken_amount(self, amount):
        """
        Set Darken amount slider
        :param amount:
        :return:
        """
        self.darken_amount_lab.setText(str(amount))
        self.font_info.add_weight = amount

    def set_hint(self):
        """
        Set hint options
        :return:
        """
        hint = self.sender()
        if hint.isChecked():
            if "keep" in hint.text().lower():
                self.font_info.change_hint = "keep"
            elif "remove" in hint.text().lower():
                self.font_info.change_hint = "remove"
            elif "auto" in hint.text().lower():
                self.font_info.change_hint = "auto"

    def set_darken_opt(self):
        """
        Set darken options
        :return:
        """
        if self.sender().isChecked():
            self.mod_bearing_opt.setEnabled(True)
            self.lbl.setEnabled(True)
            self.darken_amount_lab.setEnabled(True)
            self.darken_amount_opt.setEnabled(True)
            self.set_darken_amount(self.darken_amount_opt.value())
        else:
            self.mod_bearing_opt.setEnabled(False)
            self.lbl.setEnabled(False)
            self.darken_amount_lab.setEnabled(False)
            self.darken_amount_opt.setEnabled(False)
            self.set_darken_amount(0)

    def set_mod_bearing(self):
        """
        Set mod bearing options
        :return:
        """
        if self.mod_bearing_opt.isChecked():
            self.font_info.mod_bearings = True
        else:
            self.font_info.mod_bearings = False

    def load_fonts(self):
        """
        Load fonts from a directory, and sets appropriate options
        :return:
        """
        f_f = QFileDialog.getOpenFileNames(self, "Load Fonts", "", "Font Files (*.ttf *.otf)")
        if f_f[0]:
            for f_label, f_style in zip(self.fnt_file_name_list, self.fnt_sty_combo_list):
                f_label.setText("Load font file...")
                f_style.setCurrentIndex(SEL_NONE)
                f_style.setEnabled(False)

            self.font_files = f_f[0]
            f_f_names = []
            for file in self.font_files:
                file = os.path.normpath(file)
                base, fn = os.path.split(file)
                f_f_names.append(fn)

            for f_file, f_label, f_style in zip(f_f_names, self.fnt_file_name_list, self.fnt_sty_combo_list):
                f_label.setText(f_file)
                f_style.setEnabled(True)
                if "regular" in f_file.lower():
                    f_style.setCurrentIndex(SEL_REGULAR)
                elif "bold" in f_file.lower() and "italic" in f_file.lower():
                    f_style.setCurrentIndex(SEL_BOLDITALIC)
                elif "bold" in f_file.lower():
                    f_style.setCurrentIndex(SEL_BOLD)
                elif "italic" in f_file.lower():
                    f_style.setCurrentIndex(SEL_ITALIC)

            if self.new_fnt_name.text():
                self.gen_ttf_btn.setEnabled(True)

    def read_proc_output(self):
        """
        Read any stdout data available from the process and displays it in the output log window.
        :return:
        """
        if sys.version_info.major == 2:
            output = unicode(self.cli_process.readAllStandardOutput(), encoding=sys.getdefaultencoding())
        else:
            output = str(self.cli_process.readAllStandardOutput(), encoding=sys.getdefaultencoding())
        self.log_win.append(output)

    def manage_proc(self):
        """
        Manage the progress bar
        :return:
        """
        proc = self.sender()
        if proc.state() == QProcess.Running:
            self.prog_bar.setRange(0, 0)
        if proc.state() == QProcess.NotRunning:
            self.prog_bar.setRange(0, 100)
            self.prog_bar.setValue(100)

    def gen_ttf(self):
        """
        Generate modified TrueType font files, by calling the CLI script with the appropriate arguments.
        :param prev:
        :return:
        """
        self.log_win.clear()
        if not self.ff_path:
            self.set_ff_path()
        if self.ff_path:
            if not self.font_info.out_dir:
                save_dir = os.path.normpath(
                    QFileDialog.getExistingDirectory(self, "Select save directory...", options=QFileDialog.ShowDirsOnly)
                )
                if save_dir == "." or save_dir == "":
                    return
                else:
                    self.font_info.out_dir = save_dir
            else:
                save_dir = os.path.normpath(
                    QFileDialog.getExistingDirectory(
                        self, "Select Save directory...", self.font_info.out_dir, options=QFileDialog.ShowDirsOnly
                    )
                )
                if save_dir == "." or save_dir == "":
                    return
                else:
                    self.font_info.out_dir = save_dir

            for file, style in zip(self.font_files, self.fnt_sty_combo_list):
                if style.currentIndex() == SEL_REGULAR:
                    self.font_info.font_file_reg = file
                elif style.currentIndex() == SEL_BOLDITALIC:
                    self.font_info.font_file_bi = file
                elif style.currentIndex() == SEL_BOLD:
                    self.font_info.font_file_bd = file
                elif style.currentIndex() == SEL_ITALIC:
                    self.font_info.font_file_it = file

            cli_opt_list = self.font_info.gen_cli_command()
            self.cli_process.start(self.ff_path, cli_opt_list)

    def closeEvent(self, event):
        """
        Cleaning up...
        :param event:
        :return:
        """
        self.cli_process.close()
        event.accept()
Esempio n. 22
0
class QWFileBrowser(QWidget):
    """GUI for File Browser"""
    def __init__(self,
                 parent=None,
                 list_of_files=['Empty list'],
                 selected_file=None,
                 is_editable=True):

        QWidget.__init__(self, parent)

        self.setGeometry(200, 400, 900, 500)
        self.setWindowTitle('GUI File Browser')
        #try : self.setWindowIcon(cp.icon_browser)
        #except : pass

        self.box_txt = QTextEdit()

        self.tit_status = QLabel('Status:')
        self.tit_file = QLabel('File:')
        self.but_brow = QPushButton('Browse')
        self.but_close = QPushButton('Close')
        self.but_save = QPushButton('Save As')

        self.is_editable = is_editable

        self.box_file = QComboBox(self)
        self.setListOfFiles(list_of_files)

        self.hboxM = QHBoxLayout()
        self.hboxM.addWidget(self.box_txt)

        self.hboxF = QHBoxLayout()
        self.hboxF.addWidget(self.tit_file)
        self.hboxF.addWidget(self.box_file)
        self.hboxF.addWidget(self.but_brow)

        self.hboxB = QHBoxLayout()
        self.hboxB.addWidget(self.tit_status)
        self.hboxB.addStretch(4)
        self.hboxB.addWidget(self.but_save)
        self.hboxB.addWidget(self.but_close)

        self.vbox = QVBoxLayout()
        #self.vbox.addWidget(self.tit_title)
        self.vbox.addLayout(self.hboxF)
        self.vbox.addLayout(self.hboxM)
        self.vbox.addLayout(self.hboxB)
        self.setLayout(self.vbox)

        #self.connect(self.but_brow,  QtCore.SIGNAL('clicked()'), self.onBrow)
        #self.connect(self.but_save,  QtCore.SIGNAL('clicked()'), self.onSave)
        #self.connect(self.but_close, QtCore.SIGNAL('clicked()'), self.onClose)
        #self.connect(self.box_file, QtCore.SIGNAL('currentIndexChanged(int)'), self.onBox)

        self.but_brow.clicked.connect(self.onBrow)
        self.but_save.clicked.connect(self.onSave)
        self.but_close.clicked.connect(self.onClose)
        self.box_file.currentIndexChanged['int'].connect(self.onBox)

        self.startFileBrowser(selected_file)

        self.showToolTips()
        self.setStyle()

        #self.guifilebrowser = self

    def showToolTips(self):
        #self           .setToolTip('This GUI is intended for run control and monitoring.')
        self.but_close.setToolTip('Close this window.')

    def setStyle(self):
        style.set_styles()

        self.setStyleSheet(style.styleBkgd)
        self.tit_status.setStyleSheet(style.styleTitle)
        self.tit_file.setStyleSheet(style.styleTitle)
        self.tit_file.setFixedWidth(25)
        self.tit_file.setAlignment(Qt.AlignRight)
        self.box_file.setStyleSheet(style.styleButton)
        self.but_brow.setStyleSheet(style.styleButton)
        self.but_brow.setFixedWidth(60)
        self.but_save.setStyleSheet(style.styleButton)
        self.but_close.setStyleSheet(style.styleButton)
        self.box_txt.setReadOnly(not self.is_editable)
        self.box_txt.setStyleSheet(style.styleWhiteFixed)
        self.setContentsMargins(-9, -9, -9, -9)
        #self.setContentsMargins(QMargins(-9,-9,-9,-9))

    def setListOfFiles(self, list):
        self.list_of_files = [
            'Click on this box and select file from pop-up-list'
        ]
        self.list_of_files += list
        self.box_file.clear()
        self.box_file.addItems(self.list_of_files)
        #self.box_file.setCurrentIndex( 0 )

    def setParent(self, parent):
        self.parent = parent

    #def resizeEvent(self, e):
    #logger.debug('resizeEvent')
    #pass

    #def moveEvent(self, e):
    #logger.debug('moveEvent')
    #cp.posGUIMain = (self.pos().x(),self.pos().y())
    #pass

    def closeEvent(self, event):
        logger.debug('closeEvent')
        #self.saveLogTotalInFile() # It will be saved at closing of GUIMain

        #try    : cp.guimain.butFBrowser.setStyleSheet(style.styleButtonBad)
        #except : pass

        #try    : cp.guidark.but_browse.setStyleSheet(style.styleButtonBad)
        #except : pass

        self.box_txt.close()

        #cp.guifilebrowser = None

        #try    : del cp.guifilebrowser # QWFileBrowser
        #except : pass

    def onClose(self):
        logger.debug('onClose')
        self.close()

    def onSave(self):
        logger.debug('onSave')
        path = gu.get_save_fname_through_dialog_box(self,
                                                    self.fname,
                                                    'Select file to save',
                                                    filter='*.txt')
        if path is None or path == '': return
        text = str(self.box_txt.toPlainText())
        logger.info('Save in file:\n' + text)
        f = open(path, 'w')
        f.write(text)
        f.close()

    def onBrow(self):
        logger.debug('onBrow - select file')

        path0 = './'
        if len(self.list_of_files) > 1: path0 = self.list_of_files[1]

        path = gu.get_open_fname_through_dialog_box(
            self,
            path0,
            'Select text file for browser',
            filter='Text files (*.txt *.dat *.data *.cfg *.npy)\nAll files (*)'
        )
        if path is None or path == '' or path == path0:
            #logger.debug('Loading is cancelled...')
            return

        #logger.info('File selected for browser: %s' % path)

        if not path in self.list_of_files:
            self.list_of_files.append(path)
            self.box_txt.setText(load_textfile(path))

            self.setListOfFiles(self.list_of_files[1:])
            self.box_file.setCurrentIndex(len(self.list_of_files) - 1)
            self.setStatus(0, 'Status: browsing selected file')

    def onBox(self):
        self.fname = str(self.box_file.currentText())
        #logger.debug('onBox - selected file: ' + self.fname)

        if self.fname == '': return

        #self.list_of_supported = ['cfg', 'log', 'txt', 'txt-tmp', '', 'dat', 'data']
        self.list_of_supported = ['ALL']
        self.str_of_supported = ''
        for ext in self.list_of_supported:
            self.str_of_supported += ' ' + ext

        logger.debug('self.fname = %s' % self.fname)
        logger.debug('self.list_of_files: %s' % ', '.join(self.list_of_files))

        if self.list_of_files.index(self.fname) == 0:
            self.setStatus(0, 'Waiting for file selection...')
            self.box_txt.setText(
                'Click on file-box and select the file from pop-up list...')

        elif os.path.lexists(self.fname):
            ext = os.path.splitext(self.fname)[1].lstrip('.')

            if ext in self.list_of_supported or self.list_of_supported[
                    0] == 'ALL':
                self.box_txt.setText(load_textfile(self.fname))
                self.setStatus(0,
                               'Status: enjoy browsing the selected file...')

            else:
                self.box_txt.setText(
                    'Sorry, but this browser supports text files with extensions:'
                    + self.str_of_supported +
                    '\nTry to select another file...')
                self.setStatus(1,
                               'Status: ' + ext + '-file is not supported...')

        else:
            self.box_txt.setText(
                'Selected file is not avaliable...\nTry to select another file...'
            )
            self.setStatus(2, 'Status: WARNING: FILE IS NOT AVAILABLE!')

    def startFileBrowser(self, selected_file=None):
        logger.debug('Start the QWFileBrowser.')
        self.setStatus(0, 'Waiting for file selection...')

        if selected_file is not None and selected_file in self.list_of_files:
            index = self.list_of_files.index(selected_file)
            self.box_file.setCurrentIndex(index)

        elif len(self.list_of_files) == 2:
            self.box_file.setCurrentIndex(1)
            #self.onBox()
        else:
            self.box_file.setCurrentIndex(0)
        #self.box_txt.setText('Click on file-box and select the file from pop-up list...')

    def appendGUILog(self, msg='...'):
        self.box_txt.append(msg)
        scrol_bar_v = self.box_txt.verticalScrollBar()  # QScrollBar
        scrol_bar_v.setValue(scrol_bar_v.maximum())

    def setStatus(self, status_index=0, msg=''):
        list_of_states = ['Good', 'Warning', 'Alarm']
        if status_index == 0:
            self.tit_status.setStyleSheet(style.styleStatusGood)
        if status_index == 1:
            self.tit_status.setStyleSheet(style.styleStatusWarning)
        if status_index == 2:
            self.tit_status.setStyleSheet(style.styleStatusAlarm)

        #self.tit_status.setText('Status: ' + list_of_states[status_index] + msg)
        self.tit_status.setText(msg)
Esempio n. 23
0
class WAtQtMain(CjAt, TgWai):
    def __init__(self):
        super().__init__()

    def preStart(self):
        self.wn_init()

    def wn_init(self):
        JC_LOG.info(self.tm_wai('Initializing ...'))
        self.wn_init_ni()
        self.wn_init_ui()

    def wn_init_ni(self):
        self.wv_i_recent_pn = QStandardPaths.writableLocation(
            QStandardPaths.DesktopLocation)
        self.wv_o_recent_pn = None

    def wn_init_ui(self):
        def nf2_qw():
            fu2_it = QMainWindow()
            fu2_it.setWindowTitle(GC_APP_NM)
            self.wu_qw_cw = nf2_qw_central_widget()
            fu2_it.setCentralWidget(self.wu_qw_cw)
            self.wu_qw_a_exit = QAction('E&xit', fu2_it)
            self.wu_qw_a_exit.setShortcut(QKeySequence('Alt+X'))
            fu2_it.addAction(self.wu_qw_a_exit)
            fu2_it.show()
            fu2_it.raise_()
            self.wn_move_center(fu2_it)
            return fu2_it

        def nf2_qw_central_widget():
            fu2_it = QWidget()
            self.wu_qw_lo = nf2_qw_layout()
            fu2_it.setLayout(self.wu_qw_lo)
            return fu2_it

        def nf2_qw_layout():
            fu2_lo = QGridLayout()
            fu2_lo.setColumnStretch(0, 1)
            fu2_lo.setColumnStretch(1, 100)

            def ff3_add_qw_input(x3_row):
                fv3_row = x3_row
                self.wu_qw_i_pn_le = ff3_qw_le()
                self.wu_qw_i_pn_le.setText(self.wv_i_recent_pn)
                self.wu_qw_i_fn_pb = QPushButton('…')
                self.wu_qw_i_fn_pb.setMaximumWidth(27)
                self.wu_qw_i_bn_le = ff3_qw_le()
                self.wu_qw_i_nfo_le = ff3_qw_le()
                fu2_lo.addWidget(QLabel('Input path'), fv3_row, 0, 1, 1,
                                 Qt.AlignRight)
                fu2_lo.addWidget(self.wu_qw_i_pn_le, fv3_row, 1, 1, 3)
                fu2_lo.addWidget(self.wu_qw_i_fn_pb, fv3_row, 4, 2, 1)
                fv3_row += 1
                fu2_lo.addWidget(QLabel('Input base name'), fv3_row, 0, 1, 1,
                                 Qt.AlignRight)
                fu2_lo.addWidget(self.wu_qw_i_bn_le, fv3_row, 1, 1, 3)
                fv3_row += 1
                fu2_lo.addWidget(QLabel('Input file info'), fv3_row, 0, 1, 1,
                                 Qt.AlignRight)
                fu2_lo.addWidget(self.wu_qw_i_nfo_le, fv3_row, 1, 1, -1)
                return fv3_row

            def ff3_add_qw_hor_ln(x3_row):
                fv3_row = x3_row
                fu3_ln = QFrame()
                fu3_ln.setGeometry(QRect(1, 1, 1, 1))
                fu3_ln.setFrameShape(QFrame.HLine)
                fu3_ln.setFrameShadow(QFrame.Sunken)
                fu2_lo.addWidget(fu3_ln, fv3_row, 0, 1, -1)
                return fv3_row

            def ff3_add_qw_config(x3_row):
                fv3_row = x3_row
                self.wu_qw_c_lo = QHBoxLayout()
                self.wu_qw_c_lo.setContentsMargins(0, 0, 0, 0)
                self.wu_qw_c_lo.setSpacing(1)

                def ff4_qw_dsb(x4_px, x4_val):
                    fu4_dsb = QDoubleSpinBox()
                    fu4_dsb.setMinimum(1)
                    fu4_dsb.setMaximum(1_000_000)
                    fu4_dsb.setValue(x4_val)
                    fu4_dsb.setPrefix(f'{x4_px} ')
                    fu4_dsb.setSuffix(' mm')
                    fu4_dsb.setSingleStep(1)
                    fu4_dsb.setAlignment(Qt.AlignRight)
                    return fu4_dsb

                self.wu_qw_c_width_mm_dsb = ff4_qw_dsb('Width', 210)
                self.wu_qw_c_height_mm_dsb = ff4_qw_dsb('Height', 297)
                self.wu_qw_c_lo.addWidget(self.wu_qw_c_width_mm_dsb)
                self.wu_qw_c_lo.addItem(
                    QSpacerItem(10, 1, QSizePolicy.Fixed, QSizePolicy.Minimum))
                self.wu_qw_c_lo.addWidget(self.wu_qw_c_height_mm_dsb)
                self.wu_qw_c_lo.addItem(
                    QSpacerItem(10, 1, QSizePolicy.Fixed, QSizePolicy.Minimum))
                self.wu_qw_c_lo.addItem(
                    QSpacerItem(1, 1, QSizePolicy.Expanding,
                                QSizePolicy.Minimum))
                self.wu_qw_c_w = QWidget()
                self.wu_qw_c_w.setLayout(self.wu_qw_c_lo)
                self.wu_qw_c_w.setEnabled(False)
                fu2_lo.addWidget(QLabel('Config'), fv3_row, 0, 1, 1,
                                 Qt.AlignRight)
                fu2_lo.addWidget(self.wu_qw_c_w, fv3_row, 1, 1, -1)
                return fv3_row

            def ff3_add_qw_output(x3_row):
                fv3_row = x3_row
                self.wu_qw_o_fn_le = ff3_qw_le()
                self.wu_qw_o_fn_pb = QPushButton('…')
                self.wu_qw_o_fn_pb.setMaximumWidth(27)
                self.wu_qw_o_fn_pb.setEnabled(False)
                self.wu_qw_o_fn_lo = QHBoxLayout()
                for bu4_it in [self.wu_qw_o_fn_le, self.wu_qw_o_fn_pb]:
                    self.wu_qw_o_fn_lo.addWidget(bu4_it)
                self.wu_qw_o_nfo_le = ff3_qw_le()
                fu2_lo.addWidget(QLabel('Output file name'), fv3_row, 0,
                                 Qt.AlignRight | Qt.AlignCenter)
                fu2_lo.addLayout(self.wu_qw_o_fn_lo, fv3_row, 1, 1, -1)
                fv3_row += 1
                fu2_lo.addWidget(QLabel('Output file info'), fv3_row, 0, 1, 1,
                                 Qt.AlignRight)
                fu2_lo.addWidget(self.wu_qw_o_nfo_le, fv3_row, 1, 1, -1)
                return fv3_row

            def ff3_add_qw_process(x3_row):
                fv3_row = x3_row
                self.wu_qw_p_lo = QHBoxLayout()
                fu2_lo.addWidget(QLabel('Process'), fv3_row, 0, 1, 1,
                                 Qt.AlignRight)
                fu2_lo.addLayout(self.wu_qw_p_lo, fv3_row, 1, 1, -1)
                self.wu_qw_p_pgb = QProgressBar()
                self.wu_qw_p_pgb.setMinimum(0)
                self.wu_qw_p_pgb.setAlignment(Qt.AlignCenter)
                self.wu_qw_p_do_pb = QPushButton('D&o')
                self.wu_qw_p_do_pb.setEnabled(False)
                self.wu_qw_p_lo.addWidget(self.wu_qw_p_pgb)
                self.wu_qw_p_lo.addWidget(self.wu_qw_p_do_pb)
                self.wu_qw_p_do_pb.setMaximumWidth(50)
                return fv3_row

            def ff3_add_qw_log(x3_row):
                fv3_row = x3_row
                self.wu_qw_log_te = QTextEdit()
                self.wu_qw_log_te.setFont(
                    QFontDatabase.systemFont(QFontDatabase.FixedFont))
                self.wu_qw_log_te.setReadOnly(True)
                self.wu_qw_log_te.setWordWrapMode(QTextOption.NoWrap)
                self.wu_qw_log_te.setMinimumHeight(200)
                fu2_lo.addWidget(QLabel('Log'), fv3_row, 0, 1, 1,
                                 Qt.AlignTop | Qt.AlignRight)
                fu2_lo.addWidget(self.wu_qw_log_te, fv3_row, 1, 1, -1)
                return fv3_row

            def ff3_qw_le():
                fu3_le = QLineEdit()
                fu3_le.setMinimumWidth(800)
                fu3_le.setAlignment(Qt.AlignLeft)
                fu3_le.setReadOnly(True)
                return fu3_le

            fv2_row = 0
            fv2_row = ff3_add_qw_input(fv2_row) + 1
            fv2_row = ff3_add_qw_hor_ln(fv2_row) + 1
            fv2_row = ff3_add_qw_config(fv2_row) + 1
            fv2_row = ff3_add_qw_hor_ln(fv2_row) + 1
            fv2_row = ff3_add_qw_output(fv2_row) + 1
            fv2_row = ff3_add_qw_hor_ln(fv2_row) + 1
            fv2_row = ff3_add_qw_process(fv2_row) + 1
            fv2_row = ff3_add_qw_hor_ln(fv2_row) + 1
            fv2_row = ff3_add_qw_log(fv2_row) + 1
            return fu2_lo

        self.wu_qw = nf2_qw()
        self.wu_qw.closeEvent = self.wn_qw_close_event
        self.wu_qw_a_exit.triggered.connect(self.won_qw_a_exit_triggered)
        self.wu_qw_i_fn_pb.clicked.connect(self.won_qw_i_fn_pb_clicked)
        self.wu_qw_o_fn_pb.clicked.connect(self.won_qw_o_fn_pb_clicked)
        self.wu_qw_p_do_pb.clicked.connect(self.won_qw_p_do_pb_clicked)
        self.wu_qw_c_width_mm_dsb.valueChanged.connect(self.wn_c_changed)
        self.wu_qw_c_height_mm_dsb.valueChanged.connect(self.wn_c_changed)
        for bu2_it in gf_banner():
            self.wu_qw_log_te.append(bu2_it)

    def wn_qw_close_event(self, x_ev):
        self.wn_quit()

    def won_qw_a_exit_triggered(self):
        self.wn_quit()

    def won_qw_i_fn_pb_clicked(self, x_checked):
        def np2_do():
            pu2_i_fn = QFileDialog.getOpenFileName(self.wu_qw,
                                                   'Select PDF file',
                                                   self.wu_qw_i_pn_le.text(),
                                                   'PDF file (*.pdf)')[0]
            if not gf_if(pu2_i_fn): return
            self.wn_log_clear()
            self.wn_log_info(f'Requested file => {pu2_i_fn}')
            self.wn_log_info('Getting total pages of the requested file ...')
            self.wu_qw_i_pn_le.setText(gf_pn(pu2_i_fn))
            pu2_nop = self.wm_pdf_nop(pu2_i_fn)
            self.wu_qw_i_bn_le.setText(gf_bn(pu2_i_fn))
            self.wn_log_info(
                f"Total pages of the requested file => {pu2_nop:,d}")
            self.wu_qw_i_nfo_le.setText(f'{pu2_nop:,d} page(s)')
            self.wn_c_changed()
            self.wv_i_recent_pn = gf_pn(pu2_i_fn)

        try:
            np2_do()
        except:
            gp_log_exception(self.wn_log_error, 'Following error occurs !!!',
                             gf_exception_to_list(), 30)
            self.wn_log_error('Check your PDF file or this program logic !!!')

    def won_qw_o_fn_pb_clicked(self, x_checked):
        if self.wv_o_recent_pn == None:
            self.wv_o_recent_pn = self.wv_i_recent_pn
        nu_o_fn, _ = QFileDialog.getSaveFileName(self.wu_qw,
                                                 'Specify output PDF file',
                                                 self.wv_o_recent_pn,
                                                 'PDF file (*.pdf)')
        if nu_o_fn == '': return
        self.wv_o_recent_pn = gf_pn(nu_o_fn)
        self.wu_qw_o_fn_le.setText(nu_o_fn)

    def won_qw_p_do_pb_clicked(self, x_checked):
        if self.wu_qw_o_fn_le.text() == '':
            bu2_msg = 'Specify output file name !!!'
            self.wn_log_warn(bu2_msg)
            QMessageBox.warning(self.wu_qw, self.wu_qw.windowTitle(), bu2_msg)
            return
        nu_o_fn = self.wu_qw_o_fn_le.text()
        if gf_if(nu_o_fn):
            self.wn_log_warn('Oputput file is already exist !!!')
            bu2_overwrite = QMessageBox.question(self.wu_qw,
                                                 self.wu_qw.windowTitle(),
                                                 'Overwrite ?')
            if bu2_overwrite == QMessageBox.No: return

        def nf2_mm2pt(x2_mm):
            return x2_mm / 25.4 * 72.0

        def nf2_scale_bx(x2_bx, x2_width_ratio, x2_height_ratio):
            return CjRectangle(x2_bx.getX() * x2_width_ratio,
                               x2_bx.getY() * x2_height_ratio,
                               x2_bx.getWidth() * x2_width_ratio,
                               x2_bx.getHeight() * x2_height_ratio)

        def np2_do():
            pu2_w_lst = [
                self.wu_qw_i_fn_pb, self.wu_qw_c_w, self.wu_qw_o_fn_pb,
                self.wu_qw_p_do_pb
            ]

            def pp3_set_enabled(x3_bool):
                for bu4_w in pu2_w_lst:
                    bu4_w.setEnabled(x3_bool)

            try:
                pp3_set_enabled(False)
                bu3_st = datetime.now()
                gp_log_header(self.wn_log_info, 'Start processing ...', 23)
                bu3_i_fn = gf_pj(self.wu_qw_i_pn_le.text(),
                                 self.wu_qw_i_bn_le.text())
                self.wn_log_info('Opening input file ...')
                bu3_i_doc = CjPdfDocument(CjPdfReader(bu3_i_fn))
                self.wn_log_info('Opening output file ...')
                bu3_o_doc = CjPdfDocument(CjPdfWriter(nu_o_fn))
                JC_LOG.info('Initializing progress bar ...')
                bu3_i_nop = bu3_i_doc.getNumberOfPages()
                self.wu_qw_p_pgb.setMaximum(bu3_i_nop)
                self.wu_qw_p_pgb.setValue(0)
                try:
                    self.wn_log_info(
                        'Generating output file ( may take a long time ) ...')
                    bv4_o_nop_so_far = 0
                    bu4_page_no_list = list(range(1, bu3_i_nop + 1))
                    for bu5_i_pg_no in bu4_page_no_list:
                        bu5_i_pg = bu3_i_doc.getPage(bu5_i_pg_no)
                        bu5_i_pg_mb = bu5_i_pg.getMediaBox()
                        bu5_i_pg_bb = bu5_i_pg.getBleedBox()
                        bu5_i_pg_tb = bu5_i_pg.getTrimBox()
                        bu5_i_pg_cb = bu5_i_pg.getCropBox()
                        bu5_i_pg.setCropBox(bu5_i_pg_mb)
                        bu5_o_pg_cp = bu5_i_pg.copyAsFormXObject(bu3_o_doc)
                        bu5_width_ratio = nf2_mm2pt(
                            self.wu_qw_c_width_mm_dsb.value(
                            )) / bu5_i_pg_tb.getWidth()
                        bu5_height_ratio = nf2_mm2pt(
                            self.wu_qw_c_height_mm_dsb.value(
                            )) / bu5_i_pg_tb.getHeight()
                        bu5_scaled_mb = nf2_scale_bx(bu5_i_pg_mb,
                                                     bu5_width_ratio,
                                                     bu5_height_ratio)
                        bu5_o_pg = bu3_o_doc.addNewPage(
                            CjPageSize(bu5_scaled_mb))
                        bu5_o_pg.setMediaBox(bu5_scaled_mb)
                        bu5_o_pg.setBleedBox(
                            nf2_scale_bx(bu5_i_pg_bb, bu5_width_ratio,
                                         bu5_height_ratio))
                        bu5_o_pg.setTrimBox(
                            nf2_scale_bx(bu5_i_pg_tb, bu5_width_ratio,
                                         bu5_height_ratio))
                        bu5_o_pg.setCropBox(
                            nf2_scale_bx(bu5_i_pg_cb, bu5_width_ratio,
                                         bu5_height_ratio))
                        bu5_canvas = CjPdfCanvas(bu5_o_pg)
                        bu5_canvas.concatMatrix(
                            CjAffineTransform.getScaleInstance(
                                bu5_width_ratio, bu5_height_ratio))
                        bu5_canvas.addXObject(bu5_o_pg_cp,
                                              bu5_scaled_mb.getX(),
                                              bu5_scaled_mb.getY())
                        bv4_o_nop_so_far += 1
                        self.wu_qw_p_pgb.setValue(bv4_o_nop_so_far)
                        GC_QAPP.processEvents()
                finally:
                    bu3_o_doc.close()
                    bu3_i_doc.close()
                self.wn_log_info(
                    'Done processing => elapsed {} ...'.format(datetime.now() -
                                                               bu3_st))
            finally:
                pp3_set_enabled(True)

        try:
            np2_do()
        except:
            gp_log_exception(self.wn_log_error, 'Following error occurs !!!',
                             gf_exception_to_list(), 30)
            self.wn_log_error('Check your PDF file or this program logic !!!')

    def wm_pdf_nop(self, x_fn):  # (n)umber (o)f (p)ages
        mu_doc = CjPdfDocument(CjPdfReader(x_fn))
        mu_nop = mu_doc.getNumberOfPages()
        mu_doc.close()
        return mu_nop

    def wn_c_changed(self):
        self.wu_qw_c_w.setEnabled(True)
        self.wu_qw_o_fn_pb.setEnabled(True)
        self.wu_qw_p_do_pb.setEnabled(True)
        self.wu_qw_o_nfo_le.setText(
            f'Size => { self.wu_qw_c_width_mm_dsb .value () } x { self.wu_qw_c_height_mm_dsb .value () } mm'
        )

    def wn_quit(self):
        JC_LOG.info(self.tm_wai('About to quit ...'))
        jp_request_exit(GC_EC_SUCCESS)

    def wn_move_center(self, x_it):
        nu_cp = QDesktopWidget().availableGeometry().center()  # center point
        nu_fg = x_it.frameGeometry()
        nu_fg.moveCenter(nu_cp)
        x_it.move(nu_fg.topLeft())

    def wn_log_clear(self):
        self.wu_qw_log_te.clear()

    def wn_log_goto_bottom(self):
        nu_vsb = self.wu_qw_log_te.verticalScrollBar()
        nu_vsb.setValue(nu_vsb.maximum())

    def wn_log_info(self, x_msg):
        JC_LOG.info(x_msg)
        self.wu_qw_log_te.append(
            f"<font color=black>[I] { self. wm_2_html (x_msg) }</font>")

    def wn_log_warn(self, x_msg):
        JC_LOG.warn(x_msg)
        self.wu_qw_log_te.append(
            f"<font color=magenta>[W] { self. wm_2_html (x_msg) }</font>")

    def wn_log_error(self, x_msg):
        JC_LOG.error(x_msg)
        self.wu_qw_log_te.append(
            f"<font color=red>[E] { self. wm_2_html (x_msg) }</font>")

    def wm_2_html(self, x_msg):
        nv_msg = re.sub(r'(?:\<)', '&lt;', x_msg)
        nv_msg = re.sub(r'(?:\>)', '&gt;', nv_msg)
        nv_msg = re.sub(r'(?:\r\n|\r|\n)', '<br>', nv_msg)
        return nv_msg.replace(' ', '&nbsp;')
Esempio n. 24
0
class DMTool(QMainWindow):
    SEARCH_BOX_WIDTH = 200

    def __init__(self, db_path, validate_views=False):
        super().__init__()
        self._database_path = db_path
        sys.excepthook = self.excepthook
        self.settings = dict({"query_srd": True})
        self.load_meta()
        self._setup_ui()
        self._setup_menu()
        self.bind_signals()
        self.load_session()
        self._display_ui()
        if validate_views:
            self.validate_views()

    def _setup_ui(self):
        """
        Layout is a windowLayout with a horizontal box on the left and a tab widget on the right
        :return:
        """
        self.setStyleSheet(
            open(os.path.join("assets", "styles", "default.css")).read())
        self.setWindowIcon(QIcon(os.path.join('assets', 'tear.png')))
        self.setWindowTitle("RainyDM")
        self.setGeometry(100, 100, 1280, 720)
        self.window_frame = QFrame()
        self.window_layout = QHBoxLayout()
        # Left side tab
        self.tab_widget = QTabWidget()

        # Viewers
        # - monster viewer
        monster_button_bar = QFrame()
        monster_button_bar_layout = QHBoxLayout()
        monster_button_bar.setLayout(monster_button_bar_layout)
        self.monster_viewer = MonsterViewer(monster_button_bar, self.system)
        monster_viewer_frame_layout = QVBoxLayout()
        self.monster_viewer_frame = QFrame()
        self.monster_viewer_frame.setLayout(monster_viewer_frame_layout)
        self.monster_viewer_frame.layout().setContentsMargins(0, 0, 0, 0)
        self.monster_viewer_frame.setFrameStyle(0)

        # - spell viewer
        self.spell_viewer = SpellViewer(self.system)

        # - item viewer
        self.item_viewer = ItemViewer(self.system)

        # Text box
        self.text_box = QTextEdit()
        self.text_box.setObjectName("OutputField")
        self.text_box.setReadOnly(True)
        self.text_box.setFontPointSize(10)

        ## Tables
        # Spell Table
        self.spell_table_widget = SpellTableWidget(self, self.spell_viewer)

        # Monster table
        self.monster_table_widget = MonsterTableWidget(self,
                                                       self.monster_viewer)

        # Item table
        self.item_table_widget = ItemTableWidget(self, self.item_viewer)
        self.item_table_widget.layout().addWidget(self.item_viewer)

        self.load_resources(self._database_path)

        # Loot Generator Widget
        self.lootViewer = ItemViewer(self.system)
        self.loot_widget = TreasureHoardTab(self, self.item_viewer,
                                            self.item_table_widget)

        # Initiative list
        self.encounterWidget = EncounterWidget(self.monster_viewer)

        # bookmark
        self.bookmark_widget = BookmarkWidget(self.monster_table_widget,
                                              self.monster_viewer,
                                              self.spell_table_widget,
                                              self.spell_viewer)

        encounter_frame = QFrame()
        encounter_layout = QVBoxLayout()
        encounter_layout.addWidget(self.encounterWidget)
        encounter_layout.addWidget(self.bookmark_widget)
        encounter_frame.setLayout(encounter_layout)

        # player tab
        player_table_frame = QFrame()
        player_table_layout = QVBoxLayout()
        encounter_button_layout = QHBoxLayout()
        self.add_player_button = QPushButton("Add Player")
        self.add_player_button.setSizePolicy(QSizePolicy.Minimum,
                                             QSizePolicy.Minimum)
        self.playerWidget = PlayerTable()
        encounter_button_layout.addWidget(self.add_player_button)
        encounter_button_layout.addStretch(0)
        player_table_layout.addWidget(self.playerWidget)
        player_table_layout.addLayout(encounter_button_layout)
        player_table_frame.setLayout(player_table_layout)

        self.monster_viewer_bar = QFrame()
        self.monster_viewer_bar.setContentsMargins(0, 0, 0, 0)

        monster_viewer_frame_layout.addWidget(self.monster_viewer)
        monster_viewer_frame_layout.addWidget(monster_button_bar)
        monster_viewer_frame_layout.addWidget(self.monster_viewer_bar)
        monster_viewer_frame_layout.setStretch(3, 1)
        monster_viewer_frame_layout.setStretch(0, 2)

        middle_frame_layout = QVBoxLayout()
        self.middle_frame = QTabWidget()
        self.middle_frame.setLayout(middle_frame_layout)
        self.middle_frame.setContentsMargins(0, 0, 0, 0)

        layout = QHBoxLayout()
        monster_plaintext_button = QPushButton("Copy plaintext to clipboard")
        monster_plaintext_button.clicked.connect(
            self.copy_plaintext_monster_to_clipboard)
        layout.addWidget(monster_plaintext_button)
        self.monster_viewer_bar.setLayout(layout)

        # middle_frame_layout.addWidget(self.spell_viewer)
        middle_frame_layout.setStretch(0, 2)
        middle_frame_layout.setContentsMargins(0, 0, 0, 0)

        # Leftmost tab
        self.tab_widget.addTab(encounter_frame, "Encounter")
        self.tab_widget.addTab(player_table_frame, "Players")
        self.tab_widget.addTab(self.loot_widget, "Loot")

        # Center tab
        self.middle_frame.addTab(self.monster_table_widget, "Monster")
        self.middle_frame.addTab(self.spell_table_widget, "Spell")
        self.middle_frame.addTab(self.item_table_widget, "Item")
        self.middle_frame.addTab(self.text_box, "Text Box")

        # Right frame
        self.right_tab = QTabWidget()
        self.right_tab.addTab(self.monster_viewer_frame, "Monster")
        self.right_tab.addTab(self.spell_viewer, "Spell")
        self.right_tab.addTab(self.item_viewer, "Item")

        self.window_layout.addWidget(self.tab_widget)
        self.window_layout.addWidget(self.middle_frame)
        self.window_layout.addWidget(self.right_tab)
        self._set_widget_stretch(GlobalParameters.MAIN_TOOL_POSITION,
                                 GlobalParameters.MAIN_TOOL_STRETCH)
        self._set_widget_stretch(GlobalParameters.MIDDLE_FRAME_POSITION, 0)
        self._set_widget_stretch(GlobalParameters.RIGHT_FRAME_POSITION,
                                 GlobalParameters.RIGHT_FRAME_STRETCH)

        self.monster_viewer_bar.setHidden(True)

        self.window_frame.setLayout(self.window_layout)

    def _setup_menu(self):
        ### Menubar
        menu = self.menuBar()
        version = menu.addMenu("Version")
        # button_3_5 = QAction("3.5 Edition", self)
        # button_3_5.setStatusTip("3.5 Edition")
        # version.addAction(button_3_5)
        button_5 = QAction("5th Edition", self)
        button_5.setStatusTip("5th Edition")
        version.addAction(button_5)
        button_5.triggered.connect(lambda: self.change_version(System.DnD5e))
        button_sw5e = QAction("SW 5th Edition", self)
        button_sw5e.setStatusTip("SW 5th Edition")
        version.addAction(button_sw5e)
        button_sw5e.triggered.connect(lambda: self.change_version(System.SW5e))
        # button_3_5.triggered.connect(lambda: self.change_version("3.5"))

        experimental = menu.addMenu("Experimental")
        button_plain_text = QAction("Plain text monsters",
                                    self,
                                    checkable=True)
        button_plain_text.setStatusTip("Plain text monsters")
        button_plain_text.triggered.connect(self.toggle_monster_bar)
        # raise_exception = QAction("Raise Exception", self)
        # raise_exception.setStatusTip("Raise an Exception")
        # raise_exception.triggered.connect(self.raise_exception)
        self.edit_entries_action = QAction("Edit Entries",
                                           self,
                                           checkable=True)
        self.edit_entries_action.setStatusTip("Enable edit data entries")
        # development
        self.edit_entries_action.setChecked(True)  # default ON
        self.enable_edit_data_entries()
        ##
        self.edit_entries_action.triggered.connect(
            self.enable_edit_data_entries)

        experimental.addAction(button_plain_text)
        experimental.addAction(self.edit_entries_action)
        # experimental.addAction(raise_exception)

        self.window_frame.setLayout(self.window_layout)

    # def raise_exception(self):
    #     raise EnvironmentError("Forced an exception")

    def enable_edit_data_entries(self):
        cond = self.edit_entries_action.isChecked()
        self.monster_table_widget.EDITABLE = False  # not for monsters
        self.spell_table_widget.EDITABLE = cond
        self.item_table_widget.EDITABLE = cond

    def bind_signals(self):
        self.encounterWidget.add_players_button.clicked.connect(
            self.addPlayersToCombat)
        self.encounterWidget.sort_init_button.clicked.connect(
            self.sort_init_handle)
        self.encounterWidget.roll_init_button.clicked.connect(
            self.roll_init_handle)
        self.encounterWidget.save_encounter_button.clicked.connect(
            self.encounterWidget.save)
        self.encounterWidget.load_encounter_button.clicked.connect(
            lambda: self.encounterWidget.load(self.monster_table_widget))
        self.encounterWidget.clear_encounter_button.clicked.connect(
            self.clear_encounter_handle)
        self.bookmark_widget.clear_bookmark_button.clicked.connect(
            self.clear_bookmark_handle)
        self.bookmark_widget.toggle_bookmark_button.clicked.connect(
            self.toggle_bookmark_handle)

        self.add_player_button.clicked.connect(self.add_player)
        sNexus.attackSignal.connect(self.attackSlot)
        sNexus.addSpellsSignal.connect(self.addSpellsToBookmark)
        sNexus.printSignal.connect(self.print)
        sNexus.addMonstersToEncounter.connect(
            self.encounterWidget.addMonsterToEncounter)
        sNexus.setWidgetStretch.connect(self._set_widget_stretch)
        sNexus.viewerSelectChanged.connect(self.viewer_select_changed)

    def _display_ui(self):
        self.setCentralWidget(self.window_frame)

    def _set_widget_stretch(self, widget, stretch):
        self.window_layout.setStretch(widget, stretch)

    def toggle_monster_bar(self):
        if self.monster_viewer_bar.isHidden():
            self.monster_viewer_bar.setHidden(False)
        else:
            self.monster_viewer_bar.setHidden(True)

    def copy_plaintext_monster_to_clipboard(self):
        pyperclip.copy(html2text.html2text(self.monster_viewer.html))

    def viewer_select_changed(self, idx):
        self.right_tab.setCurrentIndex(idx)

    def change_version(self, version):
        if self.system == version:
            return
        self.system = version
        self.clear_bookmark_handle()
        self.clear_encounter_handle()

        self.monster_table_widget.table.clear()
        self.spell_table_widget.table.clear()
        self.item_table_widget.table.clear()

        self.monster_table_widget.filter.clear_filters()

        self.load_resources(self._database_path)

    def addMonsterToBookmark(self, monster):
        row_position = self.bookmark_widget.monster_bookmark.rowCount()
        self.bookmark_widget.monster_bookmark.insertRow(row_position)
        if type(monster) == list:
            for itt, value in enumerate(monster):
                self.bookmark_widget.monster_bookmark.setItem(
                    row_position, itt, QTableWidgetItem(str(value)))
        else:
            self.bookmark_widget.monster_bookmark.setItem(
                row_position, 0, QTableWidgetItem(str(monster.name)))
            self.bookmark_widget.monster_bookmark.setItem(
                row_position, 1, QTableWidgetItem(str(monster.index)))

    def addSpellsToBookmark(self, spells):
        for spell in spells:
            _spell = self.spell_table_widget.find_entry('name', spell)
            self.add_to_bookmark_spell(_spell)

    def add_to_bookmark_spell(self, spell):
        row_position = self.bookmark_widget.spell_bookmark.rowCount()
        self.bookmark_widget.spell_bookmark.insertRow(row_position)
        if type(spell) == list:
            for itt, value in enumerate(spell):
                self.bookmark_widget.spell_bookmark.setItem(
                    row_position, itt, QTableWidgetItem(str(value)))
        elif spell is not None:
            self.bookmark_widget.spell_bookmark.setItem(
                row_position, 0, QTableWidgetItem(str(spell.name)))
            self.bookmark_widget.spell_bookmark.setItem(
                row_position, 1, QTableWidgetItem(str(spell.index)))
            self.bookmark_widget.spell_bookmark.setItem(
                row_position, 2, QTableWidgetItem(str(spell.level)))

    def load_resources(self, database_path):
        self.db = RainyDatabase(database_path, system=self.system)
        self.item_table_widget.set_entries(self.db.get_items())
        self.item_table_widget.fill_table()
        self.item_table_widget.define_filters(self.system)
        self.monster_table_widget.set_entries(self.db.get_monsters())
        self.monster_table_widget.fill_table()
        self.monster_table_widget.define_filters(self.system)
        # self.spell_table_widget.load_all("./spell", "{}/{}/Spells/".format(resource_path, self.version), spell_cls)
        self.spell_table_widget.set_entries(self.db.get_spells())
        self.spell_table_widget.fill_table()
        self.spell_table_widget.define_filters(self.system)

    def add_player(self, player=None):
        self.playerWidget.add(PlayerFrame(self.playerWidget))

    def addPlayersToCombat(self):
        encounterWidget = self.encounterWidget
        characterNames = encounterWidget.getCharacterNames()
        # Get active players

        for entry in self.playerWidget.m_widgetList:
            # character in encounter, and should be
            if entry.getCharacter().getCharName(
            ) in characterNames and entry.isEnabled():
                # print("Character in encounter, and should be")
                encounterWidget.update_character(entry.getCharacter())

            # character in encounter, but shouldn't be
            elif entry.getCharacter().getCharName(
            ) in characterNames and not entry.isEnabled():
                # print("Character in enocunter, shouldn't be")
                # print(entry.getCharacter().getCharName(), entry.isEnabled())
                encounterWidget.remove_character(entry.getCharacter())

            # character not in encounter, but should be
            elif entry.getCharacter().getCharName(
            ) not in characterNames and entry.isEnabled():
                # print("Character not in encounter, should be")
                encounterWidget.addPlayerToEncounter(entry.getCharacter())

            # character not in encounter, and shouldn't be
            else:
                pass

    def sort_init_handle(self):
        self.encounterWidget.sortInitiative()

    def roll_init_handle(self):
        self.encounterWidget.rollInitiative()

    def clear_encounter_handle(self):
        self.encounterWidget.clear()

    def clear_bookmark_handle(self):
        self.bookmark_widget.monster_bookmark.clear()
        self.bookmark_widget.monster_bookmark.setRowCount(0)
        self.bookmark_widget.spell_bookmark.clear()
        self.bookmark_widget.spell_bookmark.setRowCount(0)

    def toggle_bookmark_handle(self):
        self.bookmark_widget.toggle_hide()

    def print(self, s):
        self.middle_frame.setCurrentIndex(GlobalParameters.TEXT_BOX_INDEX)
        self.text_box.append(s)

    def print_attack(self, monster_name, attack):
        attack = attack.strip(" ")
        comp = attack.split("|")
        if attack == "":
            s = "{} used an action".format(monster_name)
        else:
            s = "{} uses {} -- ".format(monster_name, comp[0])

            if comp[1] not in [
                    "", " "
            ]:  # this means there's an attack roll and a damage roll
                attack_roll = roll_function("1d20+" + comp[1])
                s = s + "{}({}) to hit".format(attack_roll,
                                               attack_roll - int(comp[1]))
            damage_roll = roll_function(comp[2])
            if damage_roll is not None:
                if type(damage_roll) is list:
                    halved = [max(1, int(dr / 2)) for dr in damage_roll]
                else:
                    # print("\trainydm - print_attack: \"{}\"".format(damage_roll))
                    halved = max(1, int(damage_roll / 2))
                s = s + " -- for {} ({} halved)".format(
                    str(damage_roll), str(halved))
        self.print(s)

    def extract_and_add_spellbook(self, monster):
        spells = monster.extract_spellbook()
        if spells is not None:
            for spell in spells:
                spell_entry = self.spell_table_widget.find_entry("name", spell)
                if spell_entry is not None:
                    self.add_to_bookmark_spell(spell_entry)
                else:
                    print("Failed to locate spell for", monster.name,
                          "with spellname {}".format(spell))

    def load_meta(self):
        if not os.path.exists("metadata/"):
            os.mkdir("metadata")

        meta_path = os.path.join("metadata", "meta.txt")
        if os.path.exists(meta_path):
            with open(meta_path, "r") as f:
                meta_dict = json.load(f)
                self.system = System.from_plaintext(meta_dict['system'])
                self.settings = meta_dict['settings']
        else:
            self.system = System.DnD5e

    def load_session(self):
        if not os.path.exists("metadata/"):
            os.mkdir("metadata")
        if os.path.exists("metadata/session.txt"):
            with open("metadata/session.txt", "r") as f:
                meta_dict = eval(f.read())
                for monster_tuple in meta_dict['bookmark_meta']:
                    self.addMonsterToBookmark(monster_tuple)

                for player in meta_dict['player_meta']:
                    player_dict = json.loads(player)
                    self.playerWidget.add(
                        PlayerFrame(self.playerWidget,
                                    charName=player_dict["characterName"],
                                    playerName=player_dict["playerName"],
                                    init=player_dict["initiative"],
                                    perception=player_dict["perception"],
                                    insight=player_dict["insight"],
                                    isEnabled=player_dict["isEnabled"]))

                for entry in meta_dict['initiative_meta']:
                    entry_dict = json.loads(entry)
                    if entry_dict["type"] == "Monster":
                        self.encounterWidget.add(
                            MonsterWidget(self.monster_table_widget.find_entry(
                                "name", entry_dict["monster"]),
                                          self.encounterWidget,
                                          viewer=self.monster_viewer,
                                          init=entry_dict["init"],
                                          hp=entry_dict["hp"]))
                    elif entry_dict["type"] == "Player":
                        self.encounterWidget.add(
                            PlayerWidget(
                                self.encounterWidget,
                                self.playerWidget.findCharacterByName(
                                    entry_dict["name"])))

    def closeEvent(self, event):
        bookmark_meta = self.bookmark_widget.monster_bookmark.jsonlify()
        initiative_meta = self.encounterWidget.jsonlify()
        player_meta = self.playerWidget.jsonlify()

        with open("metadata/session.txt", "w") as f:
            json.dump(
                dict(bookmark_meta=bookmark_meta,
                     initiative_meta=initiative_meta,
                     player_meta=player_meta), f)

        with open("metadata/meta.txt", "w") as f:
            json.dump(
                dict(system=System.to_plaintext(self.system),
                     settings=self.settings), f)

    # SLOTS
    @pyqtSlot(str, str)
    def attackSlot(self, name, attack):
        self.print_attack(name, attack)
        self.middle_frame.setCurrentIndex(GlobalParameters.TEXT_BOX_INDEX)

    def excepthook(self, type, value, tb):
        box = QMessageBox()
        box.setWindowTitle("Oof!")
        box.setText("RainyDM has crashed!")
        box.setIcon(QMessageBox.Critical)
        details = "".join(traceback.format_exception(type, value, tb))
        box.setDetailedText(details)

        spacer = QSpacerItem(500, 0, QSizePolicy.Minimum, QSizePolicy.Minimum)
        box.layout().addItem(spacer,
                             box.layout().rowCount(), 0, 1,
                             box.layout().columnCount())

        box.exec_()
        old_excepthook(type, value, tb)
        self.close()

    def validate_views(self):
        for spell in self.db.get_spells().values():
            self.spell_viewer.draw_view(spell)
        for monster in self.db.get_monsters().values():
            self.monster_viewer.draw_view(monster)
        for item in self.db.get_items().values():
            self.item_viewer.draw_view(item)
Esempio n. 25
0
class GUI(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        # 执行时间标签
        self.time = QLabel('', self)
        self.time.move(100, 80)
        self.time.resize(200, 20)
        # ID标签
        self.sid = QLabel('ID', self)
        self.sid.move(25, 50)
        self.sid.resize(50, 20)
        # ID搜索框
        self.searchBar = QLineEdit(self)
        self.searchBar.move(100, 30)
        self.searchBar.resize(450, 50)
        # 搜索按钮
        self.searchButton = QPushButton("Search", self)
        self.searchButton.move(600, 30)
        self.searchButton.resize(80, 50)
        # 清空按钮
        self.clearButton = QPushButton("Clear", self)
        self.clearButton.move(700, 30)
        self.clearButton.resize(80, 50)
        # cnlabels
        self.cnlabels = QLabel('LABELS', self)
        self.cnlabels.move(15, 140)
        self.cnlabels.resize(50, 20)
        self.cnlabelsEdit = QTextEdit(self)
        self.cnlabelsEdit.move(100, 120)
        self.cnlabelsEdit.resize(680, 60)

        # descriptions
        self.descriptions = QLabel('DESCRIPTIONS', self)
        self.descriptions.move(15, 200)
        self.descriptions.resize(80, 20)
        self.descriptionsEdit = QTextEdit(self)
        self.descriptionsEdit.move(100, 180)
        self.descriptionsEdit.resize(680, 60)
        # aliases
        self.aliases = QLabel('ALIASES', self)
        self.aliases.move(15, 260)
        self.aliases.resize(80, 20)
        self.aliasesEdit = QTextEdit(self)
        self.aliasesEdit.move(100, 240)
        self.aliasesEdit.resize(680, 60)
        # properties
        self.properties = QLabel('PROPERTIES', self)
        self.properties.move(15, 320)
        self.properties.resize(80, 20)
        self.propertiesEdit = QTextEdit(self)
        self.propertiesEdit.move(100, 300)
        self.propertiesEdit.resize(680, 60)
        # datavalue
        self.datavalue = QLabel('DATAVALUE', self)
        self.datavalue.move(15, 380)
        self.datavalue.resize(80, 20)
        self.datavalueEdit = QTextEdit(self)
        self.datavalueEdit.move(100, 360)
        self.datavalueEdit.resize(680, 160)

        self.resize(800, 600)
        self.center()
        self.setWindowTitle('WikiData---Qs2 ID-Search')
        self.setWindowIcon(QIcon('icon.jpg'))
        self.show()
        self.searchButton.clicked.connect(self.fun)
        self.clearButton.clicked.connect(self.clear)

    def fun(self):
        start = time.clock()
        queryid = self.searchBar.text()

        sql1 = "SELECT lable FROM web_main WHERE entity_id = '%s'" % (queryid)
        cur.execute(sql1)
        cnlabels = str(cur.fetchall()).replace('\'',
                                               '').replace(',', '').replace(
                                                   '(', '').replace(')', '')
        con.commit()
        self.cnlabelsEdit.append(cnlabels)

        sql3 = "SELECT description FROM web_main WHERE entity_id = '%s'" % (
            queryid)
        cur.execute(sql3)
        descriptions = str(cur.fetchall()).replace('\'', '').replace(
            ',', '').replace('(', '').replace(')', '')
        con.commit()
        self.descriptionsEdit.append(descriptions)

        sql4 = "SELECT aliase FROM web_main WHERE entity_id = '%s'" % (queryid)
        cur.execute(sql4)
        aliases = str(cur.fetchall()).replace('\'',
                                              '').replace(',', '').replace(
                                                  '(', '').replace(')', '')
        con.commit()
        self.aliasesEdit.append(aliases)

        sql5 = "SELECT property_id FROM web_claims WHERE entity_id = '%s'" % (
            queryid)
        cur.execute(sql5)
        properties = str(cur.fetchall()).replace('\'',
                                                 '').replace(',', '').replace(
                                                     '(', '').replace(')', '')
        con.commit()
        self.propertiesEdit.append(properties)

        sql6 = "SELECT datavalue_value FROM web_claims WHERE entity_id = '%s'" % (
            queryid)
        cur.execute(sql6)
        datavalue = str(cur.fetchall()).replace('\'',
                                                '').replace(',', '').replace(
                                                    '(', '').replace(')', '')
        con.commit()
        self.datavalueEdit.append(datavalue)

        end = time.clock()
        ex_time = 'Execution Time:' + str(end - start)
        # print(ex_time)
        self.time.setText(ex_time)

    def clear(self):
        self.searchBar.setText('')
        self.cnlabelsEdit.setText('')
        self.enlabelsEdit.setText('')
        self.descriptionsEdit.setText('')
        self.aliasesEdit.setText('')
        self.propertiesEdit.setText('')
        self.datavalueEdit.setText('')
        self.qhashEdit.setText('')
        self.qdatavalueEdit.setText('')
        self.rhashEdit.setText('')
        self.rdatavalueEdit.setText('')
        self.snakorderEdit.setText('')
        self.time.setText('')

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def closeEvent(self, event):
        reply = QMessageBox.question(self, 'Message', "Are you sure to exit?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
Esempio n. 26
0
class ScoreDB(QWidget):
    def __init__(self):
        super().__init__()
        self.textedit = QTextEdit()
        self.lineedit = QLineEdit()

        self.name = QLineEdit()
        self.age = QLineEdit()
        self.score = QLineEdit()
        self.amount = QLineEdit()
        self.key = QComboBox()
        self.key.addItem("Name")
        self.key.addItem("Age")
        self.key.addItem("Score")

        self.dbfilename = 'assignment6.dat'
        self.scoredb = self.readScoreDB()


        self.initUI()

        def initUI(self):
        name = QLabel("Name: ")
        age = QLabel("Age: ")
        score = QLabel("Score: ")
        amount = QLabel("Amount: ")
        key = QLabel("Key: ")

        self.nameEdit = QLineEdit()
        self.ageEdit = QLineEdit()
        self.scoreEdit = QLineEdit()
        self.amountEdit = QLineEdit()
        self.keyCombo = QComboBox()
        self.keyCombo.addItems(["Name", "Age", "Score"])


        addButton = QPushButton("Add", self)
        delButton = QPushButton("Del", self)
        findButton = QPushButton("Find", self)
        incButton = QPushButton("Inc", self)
        showButton = QPushButton("Show", self)

        shbox = QHBoxLayout()
        thbox = QHBoxLayout()
        hbox = QHBoxLayout()
        vbox = QVBoxLayout()
        tvbox = QVBoxLayout()

        result = self.textedit

        shbox.addStretch(1)
        shbox.addWidget(name)
        shbox.addWidget(self.nameEdit)
        shbox.addWidget(age)
        shbox.addWidget(self.ageEdit)
        shbox.addWidget(score)
        shbox.addWidget(self.scoreEdit)
        thbox.addStretch(1)
        thbox.addWidget(amount)
        thbox.addWidget(self.amountEdit)
        thbox.addWidget(key)
        thbox.addWidget(self.keyCombo)
        hbox.addStretch(1)
        hbox.addWidget(addButton)
        hbox.addWidget(delButton)
        hbox.addWidget(findButton)
        hbox.addWidget(incButton)
        hbox.addWidget(showButton)
        vbox.addWidget(QLabel("Result: "))
        vbox.addWidget(result)

        addButton.clicked.connect(self.buttonClicked)
        delButton.clicked.connect(self.buttonClicked)
        findButton.clicked.connect(self.buttonClicked)
        incButton.clicked.connect(self.buttonClicked)
        showButton.clicked.connect(self.buttonClicked)

        tvbox.addLayout(shbox)
        tvbox.addLayout(thbox)
        tvbox.addLayout(hbox)
        tvbox.addLayout(vbox)

        self.setLayout(tvbox)
        self.setGeometry(300, 300, 500, 250)
        self.setWindowTitle('Assignment6')
        self.show()

    def buttonClicked(self):
        sender = self.sender()

        command = {
            'add': "{0} {1} {2} {3} {4}".format(sender.text().lower(), self.name.text(), self.age.text(),
                                                self.score.text(), self.key.currentText()),
            'del': "{0} {1} {2}".format(sender.text().lower(), self.name.text(), self.key.currentText()),
            'find': "{0} {1} {2}".format(sender.text().lower(), self.name.text(), self.key.currentText()),
            'inc': "{0} {1} {2} {3} {4}".format(sender.text().lower(), self.name.text(), self.age.text(),
                                                self.amount.text(), self.key.currentText()),
            'show': "{0} {1}".format(sender.text().lower(), self.key.currentText())
        }

        user_input = command[sender.text().lower()]

        realCommand = {
            'show': self.showScoreDB,
            'add': self.addDB,
            'inc': self.incDB,
            'find': self.findDB,
            'del': self.delDB
        }

        self.textedit.append(user_input)
        realCommand[sender.text().lower()](user_input)
        pass

    def showScoreDB(self, user_input):
        command, key = user_input.split(" ")
        tmp = sorted(self.scoredb, key=lambda row: row[key])
        for row in tmp:
            strm = ""
            for info in row:
                strm += str(info) + "=" + str(row[info]) + "\t"
                pass
            self.textedit.append(strm)
            pass
        self.textedit.append("\n")
        pass

    def addDB(self, user_input):
        command, name, age, score, key = user_input.split(" ")
        try:
            record = {'Name': name, 'Age': int(age), 'Score': int(score)}

            self.scoredb += [record]

        except:
            print("Please rewrite")

        pass

    def incDB(self, user_input):

        command, name, age, amount, key = user_input.split(" ")

        try:
            for p in self.scoredb:
                if p['Name'] == name:
                    p['Score'] = str(int(p['Score']) + int(amount))
        except:
            print("Please rewrite")

    def findDB(self, user_input):
        command, name, key = user_input.split(" ")
        for i in self.scoredb:
            if i['Name'] == name:
                result = ""
                for attr in sorted(i):
                    result += attr + "=" + str(i[attr]) + "\t"

                self.textedit.append(result)

    def delDB(self, user_input):
        command, name, key = user_input.split(" ")
        del_list = []
        for p in self.scoredb:
            if p['Name'] == name:
                del_list.append(p)

        for count in range(len(del_list)):
            self.scoredb.remove(del_list[count])

    def closeEvent(self, event):

        self.writeScoreDB()

    def readScoreDB(self):
        try:
            fH = open(self.dbfilename, 'rb')
        except FileNotFoundError as e:
            print("New DB: ", self.dbfilename)
            return []

        scdb = []
        try:
            scdb = pickle.load(fH)
        except:
            print("Empty DB: ", self.dbfilename)
        else:
            print("Open DB: ", self.dbfilename)
        fH.close()
        return scdb

    # write the data into person db
    def writeScoreDB(self):
        fH = open(self.dbfilename, 'wb')
        pickle.dump(self.scoredb, fH)
        fH.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = ScoreDB()
    sys.exit(app.exec_())
class Example(QMainWindow):
    def __init__(self):
        self.pttn = re.compile(r'[s]\d+[e]\d+')
        self.match_num = 0
        self.no_match_num = 0
        self.has_match_num = 0
        super().__init__()

        self.initUI()

    def initUI(self):

        self.textEdit = QTextEdit()
        self.setCentralWidget(self.textEdit)
        self.statusBar()

        # 打开文件夹
        openFile = QAction(QIcon('icon/open.png'), 'Open dir', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open dir')
        openFile.triggered.connect(self.showDialog)

        # 退出程序
        exitAction = QAction(QIcon('icon/exit.png'), 'Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit')
        exitAction.triggered.connect(qApp.quit)

        # 设置菜单栏
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openFile)
        fileMenu.addAction(exitAction)

        # 设置窗口大小、位置及名称
        self.resize(1000, 618)
        self.center()
        self.setWindowTitle('字幕匹配')
        self.show()

    def center(self):

        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def showDialog(self):

        top = QFileDialog.getExistingDirectory(self, 'Open dir', 'C:\\Files')
        start = time.time()
        self.matchSubtitle(top)
        self.textEdit.append(
            f"原本有{self.has_match_num}个字幕已经匹配,本次有{self.match_num}个字幕完成匹配, 仍有{self.no_match_num}个字幕未匹配。"
        )
        end = time.time()
        self.textEdit.append(f"共耗时{round(end-start, 5)}秒")
        self.match_num = 0
        self.no_match_num = 0
        self.has_match_num = 0

    def matchSubtitle(self, top):

        for path, dirlist, filelist in os.walk(top):
            videos = [
                name for name in filelist
                if name.endswith(('.mkv', '.mp4', '.avi', '.rmvb', '.rm',
                                  '.flv', '.3gp'))
            ]
            subtitles = [
                name for name in filelist
                if name.endswith(('.ass', '.srt', '.sup', '.ssa'))
            ]
            # 如果只有一个字幕文件,则默认为电影,直接匹配同文件夹下的视频文件
            if len(subtitles) == len(videos) == 1:
                subtitle = subtitles[0]
                video = videos[0]
                if os.path.splitext(subtitle)[0] == os.path.splitext(video)[0]:
                    self.has_match_num += 1
                    continue
                else:
                    subtitle_oldname = os.path.join(path, subtitle)
                    subtitle_newname = os.path.join(
                        path,
                        os.path.splitext(video)[0] +
                        os.path.splitext(subtitle)[1])
                    os.rename(subtitle_oldname, subtitle_newname)
                    self.textEdit.append(f"{subtitle_oldname}匹配成功。")
                    self.match_num += 1
            else:
                for subtitle in subtitles:
                    # 提取出包含季数与集数的字符串
                    try:
                        episode = re.search(self.pttn,
                                            subtitle.lower()).group()
                    except AttributeError as e:
                        self.textEdit.append(
                            f"'{os.path.join(path, subtitle)}'中未找到匹配季数与集数的字符串。"
                        )
                        break
                    for video in videos:
                        # print(subtitle,video)
                        # 尝试匹配对应的video
                        if episode in video.lower():
                            if os.path.splitext(
                                    subtitle)[0] == os.path.splitext(video)[0]:
                                self.has_match_num += 1
                                break
                            else:
                                subtitle_oldname = os.path.join(path, subtitle)
                                subtitle_newname = os.path.join(
                                    path,
                                    os.path.splitext(video)[0] +
                                    os.path.splitext(subtitle)[1])
                                # 将字幕重命名
                                os.rename(subtitle_oldname, subtitle_newname)
                                self.textEdit.append(
                                    f"{subtitle_oldname}匹配成功。")
                                self.match_num += 1
                                break
                    else:
                        self.textEdit.append(
                            f"'{os.path.join(path, subtitle)}'未找到与之匹配的视频文件。")
                        self.no_match_num += 1
class ScoreDB_Gui(QWidget):
    def __init__(self):
        super().__init__()

        self.is_first_shown = False
        self.db = ScoreDB('assignment6.dat')
        self.db.read()

        self.initUI()

    def initUI(self):
        # set window size and title
        self.setGeometry(300, 300, 500, 250)
        self.setWindowTitle('Assignment6')

        # to send warning to user
        self.warning_msg = QMessageBox()
        self.warning_msg.setIcon(QMessageBox.Warning)
        self.warning_msg.setText("empty DB")
        self.warning_msg.setDetailedText("Add Student's Data")
        self.warning_msg.setWindowTitle(self.windowTitle())
        self.warning_msg.setStandardButtons(QMessageBox.Ok)

        # to send is Ok or not
        self.ask_msg = QMessageBox()
        self.ask_msg.setIcon(QMessageBox.Question)
        self.ask_msg.setText("are you sure?")
        self.ask_msg.setWindowTitle(self.windowTitle())
        self.ask_msg.setStandardButtons(QMessageBox.Yes | QMessageBox.No)

        # first row is user input
        name_lbl = QLabel('Name:')
        age_lbl = QLabel('Age:')
        score_lbl = QLabel('Score:')

        self.name_edit = QLineEdit()
        self.age_edit = QLineEdit()
        self.score_edit = QLineEdit()

        vbox = QVBoxLayout()
        user_data_hbox = QHBoxLayout()

        user_data_hbox.addWidget(name_lbl)
        user_data_hbox.addWidget(self.name_edit)
        user_data_hbox.addWidget(age_lbl)
        user_data_hbox.addWidget(self.age_edit)
        user_data_hbox.addWidget(score_lbl)
        user_data_hbox.addWidget(self.score_edit)

        vbox.addLayout(user_data_hbox)
        # end of first row

        # second row is key combo and amount
        amount_lbl = QLabel('Amount:')
        self.amount_edit = QLineEdit()

        sort_key_lbl = QLabel('Key')
        self.sort_key_combo = QComboBox()
        self.sort_key_combo.addItems(ScoreDB.ColumnName)

        key_and_amount_hbox = QHBoxLayout()
        key_and_amount_hbox.addStretch(1)

        key_and_amount_hbox.addWidget(amount_lbl)
        key_and_amount_hbox.addWidget(self.amount_edit)
        key_and_amount_hbox.addWidget(sort_key_lbl)
        key_and_amount_hbox.addWidget(self.sort_key_combo)

        vbox.addLayout(key_and_amount_hbox)
        # end of second row

        # third row is 5 push buttons
        # command buttons
        self.add_btn = QPushButton('Add')
        self.del_btn = QPushButton('Del')
        self.find_btn = QPushButton('Find')
        self.inc_btn = QPushButton('Inc')
        self.show_btn = QPushButton('show')

        command_hbox = QHBoxLayout()
        command_hbox.addStretch(1)

        command_hbox.addWidget(self.add_btn)
        command_hbox.addWidget(self.del_btn)
        command_hbox.addWidget(self.find_btn)
        command_hbox.addWidget(self.inc_btn)
        command_hbox.addWidget(self.show_btn)

        vbox.addLayout(command_hbox)
        # end of third row

        # last row is label and text edit
        result_lbl = QLabel('Result:')
        self.result_txt = QTextEdit()
        self.result_txt.setReadOnly(True)

        result_hbox = QHBoxLayout()
        result_vbox = QVBoxLayout()
        result_vbox.addWidget(result_lbl)

        result_vbox.addStretch(1)
        result_hbox.addLayout(result_vbox)
        result_hbox.addWidget(self.result_txt)

        vbox.addLayout(result_hbox)
        # end of last row

        self.setLayout(vbox)
        self.is_first_shown = True
        self.connect_events()

        self.show()

    def connect_events(self):
        self.add_btn.clicked.connect(self.add_btn_on_clicked)
        self.show_btn.clicked.connect(self.show_btn_on_clicked)
        self.del_btn.clicked.connect(self.del_btn_on_clicked)
        self.find_btn.clicked.connect(self.find_btn_on_clicked)
        self.inc_btn.clicked.connect(self.inc_btn_on_clicked)

    def closeEvent(self, event):
        self.db.write()

    def showEvent(self, event):
        # it must execute one time.
        if self.is_first_shown:
            self.showScoreDB(self.db.show('Name'))

    def show_btn_on_clicked(self):
        key = self.sort_key_combo.currentText()
        self.showScoreDB(self.db.show(key))

    def add_btn_on_clicked(self):
        if self.db.add_record(self.name_edit.text(), self.age_edit.text(),
                              self.score_edit.text()):
            self.show_btn_on_clicked()
        else:
            self.show_message('input right name and age and score')

        self.name_edit.clear()
        self.age_edit.clear()
        self.score_edit.clear()

    def del_btn_on_clicked(self):
        self.ask_msg.show()
        self.ask_msg.buttonClicked.connect(self.del_data)
        self.name_edit.clear()

    def del_data(self, event):
        if self.ask_msg.result() == QMessageBox.Yes:
            if not self.db.del_record(self.name_edit.text()):
                self.show_message('input right name')
            self.show_btn_on_clicked()

    def find_btn_on_clicked(self):
        finded_list = self.db.find(self.name_edit.text())
        if not finded_list:
            self.result_txt.clear()
            self.show_message('not found')
        else:
            self.showScoreDB(finded_list)

    def inc_btn_on_clicked(self):
        if not self.db.inc(self.name_edit.text(), self.amount_edit.text()):
            self.show_message("input right name or amount")
            self.amount_edit.clear()
        self.show_btn_on_clicked()
        self.name_edit.clear()
        self.amount_edit.clear()

    def show_message(self, msg):
        self.warning_msg.setText(msg)
        self.warning_msg.show()

    def showScoreDB(self, listed_db):
        self.result_txt.clear()
        if listed_db is None or not listed_db:
            self.result_txt.setText("db is emtpy")
        if not listed_db:
            self.warning_msg.show()
        self.result_txt.clear()
        for record in listed_db:
            temp_str = ''
            for column in ScoreDB.ColumnName:
                temp_str += '%s = %-20s' % (column, str(record[column]))
            self.result_txt.append(temp_str)
Esempio n. 29
0
class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setupUi()
        self.main()

    def setupUi(self):

        #classname objects
        classLayout = QHBoxLayout()
        classLabel = QLabel('Class\t')
        self.classText = QLineEdit()
        classLayout.addWidget(classLabel)
        classLayout.addWidget(self.classText)

        #credits objects
        creditsLayout = QHBoxLayout()
        creditsLabel = QLabel('Credits\t')
        self.creditsText = QLineEdit()
        creditsLayout.addWidget(creditsLabel)
        creditsLayout.addWidget(self.creditsText)

        #grade objects
        gradeLayout = QHBoxLayout()
        gradeLabel = QLabel('Grade\t')
        self.gradeText = QLineEdit()
        gradeLayout.addWidget(gradeLabel)
        gradeLayout.addWidget(self.gradeText)

        #button objects
        buttonLayout = QHBoxLayout()
        self.addButton = QPushButton('Add')
        self.deleteButton = QPushButton('Delete')
        buttonLayout.addWidget(self.addButton)
        buttonLayout.addWidget(self.deleteButton)

        #entire window
        self.textArea = QTextEdit()
        winLayout = QVBoxLayout()
        winLayout.addLayout(classLayout)
        winLayout.addLayout(creditsLayout)
        winLayout.addLayout(gradeLayout)
        winLayout.addLayout(buttonLayout)
        winLayout.addWidget(self.textArea)

        self.setLayout(winLayout)
        self.show()

    def main(self):
        self.addButton.clicked.connect(self.add)
        self.deleteButton.clicked.connect(self.delete)

        #init text area
        self.calcGPA()
        self.updateText()

        #test code

    def add(self):
        try:
            cTup = (self.classText.text(), int(self.creditsText.text()),
                    float(self.gradeText.text()))
            self.insertDB(cTup)
        except Exception as e:
            QMessageBox.about(self, 'Error',
                              'Make sure Credits and Grade are both numbers')

        #calc new GPA and update text area
        self.calcGPA()
        self.updateText()

    def delete(self):
        dname, entered = QInputDialog.getText(self, "Delete Class",
                                              "Class Name:")

        if not entered:
            return
        else:
            self.delDB(dname)

        #calc new GPA and update text area

        self.calcGPA()
        self.updateText()

    def calcGPA(self):

        self.gpa = 0

        conn = sqlite3.connect('classes.db')
        c = conn.cursor()

        c.execute('''SELECT * FROM classes''')
        clist = c.fetchall()
        creditsList = []
        gradesList = []

        for item in clist:
            creditsList.append(item[1])

        for item in clist:
            gradesList.append(item[2])

        def sumCredits():
            creds = 0
            for i in creditsList:
                creds += i

            return creds

        def sumGradePoints():
            points = 0

            def gradeToPoints(x):
                if x >= 93:
                    return 4
                elif x >= 90:
                    return 3.67
                elif x >= 87:
                    return 3.33
                elif x >= 83:
                    return 3
                elif x >= 80:
                    return 2.67
                elif x >= 77:
                    return 2.33
                elif x >= 73:
                    return 2
                elif x >= 70:
                    return 1.67
                elif x >= 67:
                    return 1.33
                elif x >= 63:
                    return 1
                elif x >= 60:
                    return 0.67
                else:
                    return 0

            for i in gradesList:
                j = 0
                gpoints = gradeToPoints(i)
                points += gpoints * creditsList[j]
                j += 1

            return points

        if creditsList != []:
            self.gpa = sumGradePoints() / sumCredits()
        else:
            self.gpa = 0

    def updateText(self):
        conn = sqlite3.connect('classes.db')
        c = conn.cursor()
        self.textArea.setText(
            'GPA : {} \nclass \tgrade\n========\t========'.format(self.gpa))

        c.execute('''SELECT * FROM classes''')
        clist = c.fetchall()

        for item in clist:
            self.textArea.append("{}\t{}\n--------\t--------".format(
                item[0], item[2]))

        conn.close()

    def insertDB(self, tup):
        conn = sqlite3.connect('classes.db')
        c = conn.cursor()
        c.execute('''INSERT INTO classes VALUES ('{}', {}, {})'''.format(
            tup[0], tup[1], tup[2]))

        conn.commit()
        conn.close()

    def delDB(self, classname):
        conn = sqlite3.connect('classes.db')
        c = conn.cursor()
        c.execute(
            '''DELETE FROM classes WHERE cname = '{}' '''.format(classname))
        conn.commit()
        conn.close()
Esempio n. 30
0
class AnalysisTab(QWidget):
    def __init__(self):

        self.analysisManager = AnalysisXmlManager()

        super().__init__()
        stringsPOI = []
        functionsPOI = []
        variablesPOI = []
        protocolsPOI = []
        structuresPOI = []
        poiSuperList = []
        self.BeatTree = ET.parse('../xml/Beat.xml')
        self.BeatRoot = self.BeatTree.getroot()
        self.poiSuperList2 = []
        mainlayout = QGridLayout()
        leftLayout = QGridLayout()
        rightLayout = QGridLayout()
        self.topLayout = QGridLayout()
        mainlayout.addLayout(self.topLayout, 0, 0, 1, 6)
        mainlayout.addLayout(leftLayout, 1, 0, 6, 1)
        mainlayout.addLayout(rightLayout, 1, 1, 6, 5)
        self.static_analysis_label = QLabel('Dynamic Analysis ')

        # Top layout elements
        self.pluginDropdown = QComboBox()
        self.runStatic = QPushButton('Run')
        self.poiDropdown = QComboBox()
        self.runDynamic = QPushButton('Run')
        self.stopDynamic = QPushButton('Stop')

        self.topLayout.addWidget(QLabel('Plugin'), 0, 0)
        self.topLayout.addWidget(self.pluginDropdown, 0, 1, 1, 2)
        self.topLayout.addWidget(QLabel('Static Analysis'), 1, 0)
        self.topLayout.addWidget(self.runStatic, 1, 1, 1, 1)
        self.topLayout.addWidget(QLabel('Point of Interest Type'), 2, 0)
        self.topLayout.addWidget(self.poiDropdown, 2, 1, 1, 2)
        self.topLayout.addWidget(self.static_analysis_label, 1, 5, 1, 1)
        self.topLayout.addWidget(self.runDynamic, 1, 6)
        self.topLayout.addWidget(self.stopDynamic, 1, 7)
        self.topLayout.addWidget(QLabel(), 0, 3, 1, 15)

        # Left panel
        self.searchBox = QLineEdit()
        self.searchButton = QPushButton('Search')
        self.searchedWord = []

        self.poiList = QListWidget()
        leftPanelLabel = QLabel('Point of Interest View')
        leftPanelLabel.setFont(
            QtGui.QFont('Arial', 12, weight=QtGui.QFont().Bold))
        leftPanelLabel.setAlignment(Qt.AlignCenter)

        leftLayout.addWidget(leftPanelLabel, 0, 0, 1, 4)
        leftLayout.addWidget(self.searchBox, 1, 0, 1, 3)
        leftLayout.addWidget(self.searchButton, 1, 3, 1, 1)
        leftLayout.addWidget(self.poiList, 2, 0, 1, 4)

        # Right panel
        rightPanelLabel = QLabel('Point of Interest View')
        rightPanelLabel.setFont(
            QtGui.QFont('Arial', 12, weight=QtGui.QFont().Bold))
        rightPanelLabel.setAlignment(Qt.AlignCenter)
        self.poiContentArea = QScrollArea()
        self.terminal = QTextEdit()
        self.commentButton = QPushButton('Comments')
        self.current_project = QLabel('Current Project: ')

        rightLayout.addWidget(rightPanelLabel, 0, 0, 1, 10)
        rightLayout.addWidget(self.poiContentArea, 1, 0, 10, 8)
        rightLayout.addWidget(self.terminal, 11, 0, 10, 8)
        rightLayout.addWidget(self.commentButton, 2, 8)

        # Functionality
        self.commentButton.clicked.connect(self.openCommentWindow)

        # set Plugin name
        self.pluginDropdown.addItem("Select Plugin")
        self.pluginDropdown.activated[str].connect(self.onActivated)

        self.poiDropdown.activated[str].connect(self.displayPOI)
        self.runStatic.clicked.connect(self.clickStaticAnalysis)
        self.searchButton.clicked.connect(self.clickedSearch)
        self.poiList.clicked.connect(self.expandPOI)
        self.setLayout(mainlayout)

        # this should not be visible at start
        self.runDynamic.hide()
        self.stopDynamic.hide()
        self.static_analysis_label.hide()
        self.displayCurrentProject("No Project Selected", "")

        self.setLayout(mainlayout)
        self.populatePluginDropdown()

    def populatePluginDropdown(self):
        pluginList = self.analysisManager.getListOfPluginsForAnalysis()
        for plugin in pluginList:
            self.pluginDropdown.addItem(plugin)

    def displayCurrentProject(self, project_name, project_path):
        self.current_project.clear()
        self.topLayout.addWidget(self.current_project, 0, 20)
        current = 'Current Project:  ' + project_name + '\n' + 'Binary File: ' + project_path
        self.current_project = QLabel(current)
        self.topLayout.addWidget(self.current_project, 0, 20)

    def clickedSearch(self):
        global poiSuperList
        target = self.searchBox.text()
        self.searchedWord = [s for s in poiSuperList if target in s]
        self.poiList.clear()
        for items in self.searchedWord:
            self.poiList.addItem(items)

    def displayPOIparam(self):
        content_widget = QWidget()
        self.poiContentArea.setWidget(content_widget)
        layoutForPOI = QGridLayout(content_widget)
        self.poiContentArea.setWidgetResizable(True)
        option = self.poiDropdown.currentText()
        if option == "Strings":
            for i in range(layoutForPOI.count()):
                layoutForPOI.itemAt(i).widget().close()
            value = QLabel('Value:')
            sectionInBinary = QLabel('Section In Binary:')
            self.valueLine = QLineEdit()
            self.sectionInBinaryLine = QLineEdit()
            layoutForPOI.addWidget(value, 1, 0)
            layoutForPOI.addWidget(self.valueLine, 1, 1)
            layoutForPOI.addWidget(sectionInBinary, 2, 0)
            layoutForPOI.addWidget(self.sectionInBinaryLine, 2, 1)
        elif option == "Functions":
            for i in range(layoutForPOI.count()):
                layoutForPOI.itemAt(i).widget().close()

            order = QLabel('Order of Parameters:')
            fpType = QLabel('Parameter Type:')
            fpValue = QLabel('Parameter Value:')
            frType = QLabel('Return Type:')
            frValue = QLabel('Return Value:')
            fRelativeOrder = QLabel('Order in Relation to :')

            self.orderLine = QLineEdit()
            self.fpTypeLine = QLineEdit()
            self.fpValueLine = QLineEdit()
            self.frValueLine = QLineEdit()
            self.frTypeLine = QLineEdit()
            self.fRelativeOrderLine = QLineEdit()

            layoutForPOI.addWidget(order, 1, 0)
            layoutForPOI.addWidget(self.orderLine, 1, 1)
            layoutForPOI.addWidget(fpType, 2, 0)
            layoutForPOI.addWidget(self.fpTypeLine, 2, 1)
            layoutForPOI.addWidget(frValue, 3, 0)
            layoutForPOI.addWidget(self.frValueLine, 3, 1)
            layoutForPOI.addWidget(fRelativeOrder, 4, 0)
            layoutForPOI.addWidget(self.fRelativeOrderLine, 4, 1)

        elif option == "Variables":
            for i in range(layoutForPOI.count()):
                layoutForPOI.itemAt(i).widget().close()
            variableType = QLabel('Variable Type:')
            value = QLabel('Value:')
            sectionInBinary = QLabel('Section In Binary:')
            variableTypeLine = QLineEdit()
            valueLine = QLineEdit()
            sectionInBinaryLine = QLineEdit()
            layoutForPOI.addWidget(variableType, 1, 0)
            layoutForPOI.addWidget(variableTypeLine, 1, 1)
            layoutForPOI.addWidget(value, 2, 0)
            layoutForPOI.addWidget(valueLine, 2, 1)
            layoutForPOI.addWidget(sectionInBinary, 3, 0)
            layoutForPOI.addWidget(sectionInBinaryLine, 3, 1)
        elif option == "Structures":
            for i in range(layoutForPOI.count()):
                layoutForPOI.itemAt(i).widget().close()
            memberOrder = QLabel('Member Order:')
            memberType = QLabel('Value:')
            sectionInBinary = QLabel('Section In Binary:')
            memberValue = QLabel('Member Value:')
            memberOrderLine = QLineEdit()
            memberTypeLine = QLineEdit()
            sectionInBinaryLine = QLineEdit()
            memberValueLine = QLineEdit()
            layoutForPOI.addWidget(sectionInBinary, 1, 0)
            layoutForPOI.addWidget(sectionInBinaryLine, 1, 1)
            layoutForPOI.addWidget(memberOrder, 2, 0)
            layoutForPOI.addWidget(memberOrderLine, 2, 1)
            layoutForPOI.addWidget(memberType, 3, 0)
            layoutForPOI.addWidget(memberTypeLine, 3, 1)
            layoutForPOI.addWidget(memberValue, 4, 0)
            layoutForPOI.addWidget(memberValueLine, 4, 1)
        elif option == "Protocols":
            for i in range(layoutForPOI.count()):
                layoutForPOI.itemAt(i).widget().close()
            pStructure = QLabel('Structure')
            pSize = QLabel('Size')
            sectionInBinary = QLabel('Section In Binary:')
            pSizeLine = QLineEdit()
            pStructureLine = QLineEdit()
            sectionInBinaryLine = QLineEdit()
            layoutForPOI.addWidget(sectionInBinary, 1, 0)
            layoutForPOI.addWidget(sectionInBinaryLine, 1, 1)
            layoutForPOI.addWidget(pStructure, 2, 0)
            layoutForPOI.addWidget(pStructureLine, 2, 1)
            layoutForPOI.addWidget(pSize, 3, 0)
            layoutForPOI.addWidget(pSizeLine, 3, 1)
        else:
            for i in range(layoutForPOI.count()):
                layoutForPOI.itemAt(i).widget().close()

    def parseNetworkItems(self):
        global poiSuperList
        target = ['socket', 'send', 'rec', 'ipv', 'main']
        for i in target:
            self.searchedWord.append([s for s in poiSuperList if i in s])

        self.poiList.clear()
        poiSuperList = []
        for items in self.searchedWord:
            for item2 in items:
                self.poiList.addItem(item2)
        self.searchedWord = []

    def expandPOI(self):
        dataSet = self.analysisManager.getAnalysis()
        pois = dataSet[1]
        option = self.poiDropdown.currentText()

        if option == 'Strings':
            currentItem = self.poiList.currentItem().text()
            strings = pois['Project']['StaticAnalysis'][
                'stringPointOfInterest']
            for i in range(
                    len(strings)):  # access each individual function POI
                poi = strings[i]
                if currentItem == poi['value']:
                    self.valueLine.setText(poi['address'])
                    self.sectionInBinaryLine.setText(poi['section'])

        if option == 'Functions':
            currentItem = self.poiList.currentItem().text()
            functions = pois['Project']['StaticAnalysis'][
                'functionPointOfInterest']
            for i in range(
                    len(functions)):  # access each individual function POI
                poi = functions[i]
                if currentItem == poi['name']:
                    self.orderLine.setText(poi['name'])
                    self.fpTypeLine.setText(poi['parameterType'])
                    self.frValueLine.setText(poi['address'])
                    self.fRelativeOrderLine.setText(
                        poi['breakpoints']['breakpoint'])

    def displayPOI(self, option):
        dataSet = self.analysisManager.getAnalysis()
        pois = dataSet[1]

        if option == "Strings":
            self.poiList.clear()
            strings = pois['Project']['StaticAnalysis'][
                'stringPointOfInterest']
            for i in range(len(strings)):
                self.poiList.addItem(strings[i]['value'])

        if option == "Functions":
            self.poiList.clear()
            functions = pois['Project']['StaticAnalysis'][
                'functionPointOfInterest']
            for i in range(len(functions)):
                self.poiList.addItem(functions[i]['name'])
        self.displayPOIparam()

    def onActivated(self, option):
        # make invisible
        self.runDynamic.hide()
        self.stopDynamic.hide()
        self.static_analysis_label.hide()

        data = []
        BeatTree = ET.parse("../xml/Beat.xml")
        root = BeatTree.getroot()
        pluginData = root.find('./Plugins/Plugin/DataInPlugin')
        pluginName = root.findall('./Plugins/Plugin/Plugin_name')
        self.poiDropdown.clear()
        self.poiDropdown.addItem("Select POI to display")
        self.poiDropdown.addItem("Display All for {}".format(option))
        for item in pluginName:
            data.append(item.text)
            if item.text == option:
                pluginData = root.find(
                    './Plugins/Plugin[@nameOfPlugin="{}"]/DataInPlugin'.format(
                        option))
                for element in pluginData:
                    plugin = element.get('name')
                    self.poiDropdown.addItem(plugin)

    def makeStringTree(self, stringsData, parentRoot):
        poiHolderElement = parentRoot.find('./StaticAnalysis')

        for index in range(len(stringsData)):  # access each string
            myString = stringsData[
                index]  # this dictionary contains one String POI
            tree = ET.parse('../xml/StringPointOfInterest.xml')
            root = tree.getroot()
            b2tf = root.find("./value")
            b2tf.text = str(base64.standard_b64decode(myString['string']))
            b2tf = root.find("./address")
            b2tf.text = str(hex(myString['vaddr']))
            b2tf = root.find("./section")
            b2tf.text = str(myString['section'])
            poiHolderElement.append(root)

    def makeFunctionsTree(self, functionsData, parentRoot, r2buffer):
        poiHolderElement = parentRoot.find('./StaticAnalysis')
        r2buffer.cmd(
            'doo'
        )  # need to open file in debug mode to find references for breakpoints

        for index in range(len(functionsData)):  # access each function
            myFunction = functionsData[
                index]  # this dictionary contains one function POI
            tree = ET.parse('../xml/FunctionPointOfInterest.xml')
            root = tree.getroot()
            b2tf = root.find("./name")
            b2tf.text = str(myFunction['name'])
            b2tf = root.find("./address")
            b2tf.text = str(hex(myFunction['offset']))
            b2tf = root.find("./parameterType")

            breakpoints = []  # this will hold a list of our breakpoints
            breakpointElement = root.find('./breakpoints')
            jsonReferences = json.loads(
                r2buffer.cmd('axtj ' + myFunction['name']))
            breakpoints.clear()

            for i in range(len(jsonReferences)):
                breakpoints.append(str(hex(jsonReferences[i]['from'])))
            for bp in breakpoints:
                tempElement = ET.SubElement(breakpointElement, 'breakpoint')
                tempElement.text = bp
            poiHolderElement.append(root)

    def clickStaticAnalysis(self):
        global stringsPOI
        global variablesPOI
        global functionsPOI
        global protocolsPOI
        global structuresPOI

        global parentRoot  # holds all POIs from static analysis

        self.poiList.clear()
        self.terminal.setText("Running Static Analysis..")
        project_name = pt.project['Project']['Project_name']['#text']
        project_path = pt.project['Project']['BinaryFilePath']['#text']
        self.displayCurrentProject(project_name, project_path)

        bina = r2pipe.open(pt.project['Project']['BinaryFilePath']['#text'])
        bina.cmd("aaa")  # analyze binary in Radare2

        # extracting POI data from Radare2 and storing as json dictionaries
        stringsPOI = bina.cmd("izj")
        jsonStrings = json.loads(stringsPOI)
        functionsPOI = bina.cmd("aflj")
        jsonFunctions = json.loads(functionsPOI)

        # get handle to Project xml, create POI xmls, and upload them to DB
        parentTree = ET.parse('../xml/Project.xml')

        parentRoot = parentTree.getroot()
        parentRootName = parentRoot.find('./Project_name')
        parentRootName.text = project_name

        self.makeStringTree(jsonStrings, parentRoot)
        self.makeFunctionsTree(jsonFunctions, parentRoot, bina)
        parent_dict = ET.tostring(parentRoot, encoding='utf8').decode('utf8')
        self.analysisManager.uploadAnalysis(parent_dict)

        self.terminal.append("Static Analysis done!")

        # Make dynamic visible here
        self.runDynamic.show()
        self.stopDynamic.show()
        self.static_analysis_label.show()

    # Methods to open windows
    def openCommentWindow(self):
        self.window = QtWidgets.QDialog()
        self.ui = comment_window()
        self.ui.setupUi(self.window)
        self.window.show()

    def openAnalysisWindow(self):
        self.window = QtWidgets.QDialog()
        self.ui = analysis_window()
        self.ui.setupUi(self.window)
        self.window.show()

    def openOutputWindow(self):
        self.window = QtWidgets.QDialog()
        self.ui = output_Field_Window()
        self.ui.setupUi(self.window)
        self.window.show()
class App(QWidget):
    # References for the UI elements
    comboSerialPorts = None
    btnRefreshPorts = None
    btnFlashMicroPython = None
    btnFlashKanoCode = None
    logArea = None
    # Reference for the thread which will run the flash process
    flash_thread = None

    def __init__(self):
        super().__init__()
        # Initializes the UI elements
        self.initUi()
        # Populate the `comboSerialPorts` with current serial connections
        self.refreshPorts()

    def initUi(self):
        """
        Initializes the UI elements
        """
        # Create and set a layout to stack the components
        layout = QVBoxLayout()
        self.setLayout(layout)

        # Create UI elements:
        # List of ports (dropdown/combo box)
        self.comboSerialPorts = QComboBox(self)
        self.comboSerialPorts.currentIndexChanged.connect(self.portChanged)
        self.comboSerialPorts.addItem('Select serial port...')
        # Button to refresh ports
        self.btnRefreshPorts = QPushButton('Refresh ports', self)
        # Button to flash MicroPython and Kano Code firmwares
        self.btnFlashMicroPython = QPushButton('Flash MicroPython + Pixel32',
                                               self)
        self.btnFlashKanoCode = QPushButton('Flash Kano Code', self)
        # Text area for printing the logs (not editable)
        self.logArea = QTextEdit(self)
        self.logArea.setReadOnly(True)

        # Bind the clicks to its methods
        self.btnRefreshPorts.clicked.connect(self.refreshPorts)
        self.btnFlashMicroPython.clicked.connect(self.flashMicroPython)
        self.btnFlashKanoCode.clicked.connect(self.flashKanoCode)

        # Adding the UI components to the layout
        layout.addWidget(self.comboSerialPorts)
        layout.addWidget(self.btnRefreshPorts)
        layout.addWidget(self.btnFlashMicroPython)
        layout.addWidget(self.btnFlashKanoCode)
        layout.addWidget(self.logArea)

        # Set the window properties
        self.setGeometry(100, 100, 300, 300)
        self.setWindowTitle('Kano Pixel Kit Flasher Tool')
        self.show()

    def log(self, data):
        """
        Writes to text area on the UI
        """
        self.logArea.append(data)
        # Repaint will make sure it does change the textarea looks are updated
        self.logArea.repaint()

    def enableFlashButtons(self, enabled=True):
        """
        Enable buttons related to flashing firmwares
        """
        # If there are no buttons, skip it
        if not self.btnFlashKanoCode or not self.btnFlashMicroPython:
            return
        self.btnFlashMicroPython.setEnabled(enabled)
        self.btnFlashKanoCode.setEnabled(enabled)
        # Repaint will make sure it does change the button looks are updated
        self.btnFlashMicroPython.repaint()
        self.btnFlashKanoCode.repaint()

    def updateButtonState(self):
        """
        Check if buttons should be enabled or disabled and update them
        """
        if self.flash_thread or\
           self.comboSerialPorts.currentIndex() < 1:
            self.enableFlashButtons(False)
        else:
            self.enableFlashButtons(True)

    def portChanged(self, i):
        """
        Once the ports are changed, update button states
        """
        self.updateButtonState()

    def refreshPorts(self):
        """
        Scan the available serial ports for Pixel Kits and update the combo
        box that list them.
        """
        ports = list_serial_ports()
        # Filter the ports by Pixel Kit's vendor and product ids.
        rpks = list(
            filter(lambda port: (port.vid, port.pid) == (0x0403, 0x6015),
                   ports))
        # Reset the combo box
        self.comboSerialPorts.clear()
        self.comboSerialPorts.addItem('Select serial port...')
        self.comboSerialPorts.setCurrentIndex(0)
        # Add ports to the combo box and update its looks
        for port in rpks:
            self.comboSerialPorts.addItem(port.device)
        self.comboSerialPorts.repaint()

    def flashMicroPython(self):
        """
        Start thread for flashing MicroPython
        """
        msg = 'Flashing MicroPython (version {0}) and Pixel32 (version {1})'
        self.log(msg.format(micropython_version, pixel32_version))
        selectedPort = self.comboSerialPorts.currentText()
        self.flash_thread = MicroPythonFlasher(selectedPort)
        self.startFlashing()

    def flashKanoCode(self):
        """
        Start thread for flashing Kano Code firmware
        """
        msg = 'Flashing Kano Code firmware (version {0})'
        self.log(msg.format(kanocode_version))
        selectedPort = self.comboSerialPorts.currentText()
        self.flash_thread = KanoCodeFlasher(selectedPort)
        self.startFlashing()

    def startFlashing(self):
        """
        Bind flash thread signals, start it and update UI
        """
        self.flash_thread.finished.connect(self.flash_finished)
        self.flash_thread.on_flash_fail.connect(self.flash_failed)
        self.flash_thread.on_data.connect(self.on_flash_data)
        self.flash_thread.on_progress.connect(self.on_flash_data)
        self.flash_thread.start()
        self.updateButtonState()

    def flash_finished(self):
        """
        Called when flash is finished
        """
        self.log('Flash finished')
        self.flash_thread = None
        self.updateButtonState()

    def flash_failed(self, err):
        """
        Called when flash fails
        """
        self.log("ERROR: " + err)
        self.flash_thread = None
        self.updateButtonState()

    def on_flash_data(self, data):
        """
        Called when the thread running the flasher process emits a signal
        """
        self.log(data)
Esempio n. 32
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow, self).__init__(*args, **kwargs)
        # 在初始化之前设置pg,因为初始化会写死配置,无法在更改
        # pg.setConfigOption('foreground', 'd')
        # 使曲线看起来光滑
        pg.setConfigOptions(antialias=True)
        # 设置文字的字体
        font = QFont()
        font.setFamily("Microsoft Yahei")
        font.setPointSize(11)

        self.setMinimumHeight(750)
        self.setMinimumWidth(1000)
        # self.setFixedSize(1000, 750)

        # 统一设置按钮的字体
        btn_list = []

        # 设置题目和状态栏
        self.setWindowTitle("心电平台检测")

        # 设置状态栏
        self.status = self.statusBar()
        self.status.showMessage("检测~")

        # 整体布局
        pagelayout = QVBoxLayout()

        # 顶层按钮布局
        top = QFrame(self)
        top.setFrameShape(QFrame.StyledPanel)
        btn_layout = QHBoxLayout(top)
        self.data_com = QComboBox()
        delegate = QStyledItemDelegate()
        self.data_com.setItemDelegate(delegate)
        self.data_com.addItem("选择心电数据")
        self.data_com.setFixedSize(200, 40)
        self.data_com.setFont(font)
        set_btn = QPushButton("设置")
        help_btn = QPushButton("帮助")
        save_btn = QPushButton("存储")
        back_btn = QPushButton("回放")
        fig_btn = QPushButton("截图")
        patient_table_btn = QPushButton("病例表")
        self.stop_btn = QPushButton("暂停")
        btn_list.append(set_btn)
        btn_list.append(help_btn)
        btn_list.append(save_btn)
        btn_list.append(back_btn)
        btn_list.append(self.stop_btn)
        btn_list.append(fig_btn)
        btn_list.append(patient_table_btn)
        btn_layout.addWidget(self.data_com)
        btn_layout.addWidget(set_btn)
        btn_layout.addWidget(help_btn)
        btn_layout.addWidget(save_btn)
        btn_layout.addWidget(self.stop_btn)
        btn_layout.addWidget(back_btn)
        btn_layout.addWidget(fig_btn)
        btn_layout.addWidget(patient_table_btn)

        for btn in btn_list:
            btn.setFont(font)
            btn.setFixedSize(100, 40)

        # 以此统计病人数量
        self.patient = 0
        for i in range(0, 10):
            self.patient += 1
            self.data_com.addItem(str(100 + i))

        # 底层布局
        bottom = QFrame(self)
        bottom.setFrameShape(QFrame.StyledPanel)
        self.bottom_layout = QStackedLayout(bottom)

        # 1. 绘图区域
        plot_widget = QWidget(bottom)
        plot_layout = QHBoxLayout()
        win = pg.GraphicsLayoutWidget()
        self.p = win.addPlot()
        self.p.getAxis("bottom").tickFont = font
        self.p.getAxis("left").tickFont = font
        # 背景透明
        win.setBackground(background=None)
        plot_layout.addWidget(win)
        plot_widget.setLayout(plot_layout)
        self.bottom_layout.addWidget(plot_widget)

        # 2. 帮助文档
        help_widget = QWidget(bottom)
        help_layout = QHBoxLayout()
        self.help_text = QTextEdit()
        self.help_text.setReadOnly(True)
        help_layout.addWidget(self.help_text)
        help_widget.setLayout(help_layout)
        self.bottom_layout.addWidget(help_widget)
        help_btn.clicked.connect(self.show_help)

        # 3. 设置
        set_widget = QWidget(bottom)
        set_layout = QVBoxLayout()
        theme_layout = QHBoxLayout()
        self.theme_white_radio = QRadioButton("白色主题")
        self.theme_white_radio.setFixedWidth(120)
        self.theme_black_radio = QRadioButton("黑色主题")
        theme_label = QLabel("主题颜色选择")
        theme_label.setFixedWidth(120)
        theme_layout.addWidget(theme_label)
        theme_layout.addWidget(self.theme_white_radio)
        theme_layout.addWidget(self.theme_black_radio)
        line_width_layout = QHBoxLayout()
        line_width = QLabel("设置线宽(范围1-4)")
        line_width.setFixedWidth(150)
        line_width_layout.addWidget(line_width)
        self.line_width_spin = QSpinBox()
        self.line_width_spin.setMinimum(1)
        self.line_width_spin.setMaximum(4)
        line_width_layout.addWidget(self.line_width_spin)
        set_layout.addLayout(theme_layout)
        set_layout.addLayout(line_width_layout)
        set_widget.setLayout(set_layout)
        self.bottom_layout.addWidget(set_widget)
        self.theme_white_radio.toggled.connect(self.change_status)
        self.theme_black_radio.toggled.connect(self.change_status)
        set_btn.clicked.connect(self.set_)

        # 暂停与启动的切换
        self.stop_btn.clicked.connect(self.stop_)

        # 截图功能
        fig_btn.clicked.connect(self.save_fig)

        # 回放功能
        back_btn.clicked.connect(self.back_show)

        # 保存数据功能
        save_widget = QWidget(bottom)
        save_layout = QHBoxLayout()
        save_label = QLabel("请选择保存数据的区间")
        save_label.setFixedHeight(40)
        self.left_interval = QLineEdit()
        self.left_interval.setFixedHeight(40)
        self.left_interval.setPlaceholderText("起始点,左区间")
        self.right_interval = QLineEdit()
        self.right_interval.setFixedHeight(40)
        self.right_interval.setPlaceholderText("终止点,右区间")
        save_confirm_btn = QPushButton("确认")
        save_confirm_btn.setFixedHeight(40)
        save_layout.addWidget(save_label)
        save_layout.addWidget(self.left_interval)
        save_layout.addWidget(self.right_interval)
        save_layout.addWidget(save_confirm_btn)
        save_widget.setLayout(save_layout)
        save_btn.clicked.connect(self.save_widget_)
        save_confirm_btn.clicked.connect(self.save_data)
        self.bottom_layout.addWidget(save_widget)

        # 病例表的填写
        table_widget = QWidget(bottom)
        table_layout = QHBoxLayout()
        self.patient_table = QTableWidget()
        self.patient_table.setColumnCount(9)
        self.patient_table.setRowCount(self.patient)
        self.patient_table.setHorizontalHeaderLabels([
            '标号', '年龄', '性别', '用药', '房性早博', '室性早博', '心室融合心博', '右束支传导阻塞心博',
            '左束支传导阻塞心博'
        ])
        # self.patient_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.patient_table.resizeColumnsToContents()
        self.patient_table.verticalHeader().setVisible(False)
        table_layout.addWidget(self.patient_table)
        table_widget.setLayout(table_layout)
        self.bottom_layout.addWidget(table_widget)
        patient_table_btn.clicked.connect(self.show_table)

        # 设置最终的窗口布局与控件-------------------------------------
        splitter = QSplitter(Qt.Vertical)
        splitter.addWidget(top)
        splitter.addWidget(bottom)

        widget = QWidget()
        pagelayout.addWidget(splitter)
        widget.setLayout(pagelayout)
        self.setCentralWidget(widget)

        # 计时器 当时间到了就出发绘图函数
        self.timer = QTimer()
        self.timer.timeout.connect(self.update)

        # 记录当前用户
        self.people = ""
        # 当用户改变时出发函数 重新绘图
        self.data_com.currentIndexChanged.connect(self.show_ecg1)
        self.data_com.view().pressed.connect(self.show_ecg)
        # 读取数据的标志
        self.flag = 0
        # 帮助文档的标志
        self.help = 0
        # 暂停的标志
        self.stop = 0

    def show_table(self):
        # 这么多行
        self.timer.stop()
        self.bottom_layout.setCurrentIndex(4)
        rows = self.patient
        for row in range(0, rows):
            item = QTableWidgetItem(str(100 + row))
            self.patient_table.setItem(row, 0, item)
            head = wfdb.rdheader('MIT-BIH/mit-bih-database/' + str(100 + row))
            age, gender, _, _, _ = head.comments[0].split(" ")
            item = QTableWidgetItem(str(age))
            self.patient_table.setItem(row, 1, item)
            item = QTableWidgetItem(str(gender))
            self.patient_table.setItem(row, 2, item)
            drugs = head.comments[1]
            item = QTableWidgetItem(str(drugs))
            self.patient_table.setItem(row, 3, item)
            record = wfdb.rdann('MIT-BIH/mit-bih-database/' + str(100 + row),
                                "atr",
                                sampfrom=0,
                                sampto=650000)
            A, V, F, R, L = 0, 0, 0, 0, 0
            for index in record.symbol:
                if index == 'A':
                    A += 1
                if index == "V":
                    V += 1
                if index == "F":
                    F += 1
                if index == "R":
                    R += 1
                if index == "L":
                    L += 1
            item = QTableWidgetItem(str(A))
            self.patient_table.setItem(row, 4, item)
            item = QTableWidgetItem(str(V))
            self.patient_table.setItem(row, 5, item)
            item = QTableWidgetItem(str(F))
            self.patient_table.setItem(row, 6, item)
            item = QTableWidgetItem(str(R))
            self.patient_table.setItem(row, 7, item)
            item = QTableWidgetItem(str(L))
            self.patient_table.setItem(row, 8, item)
            self.patient_table.resizeColumnsToContents()

    # 选择区间断和数据,保存即可
    def save_data(self):
        left = int(self.left_interval.text())
        right = int(self.right_interval.text())
        print(self.people)
        record = wfdb.rdrecord('MIT-BIH/mit-bih-database/' + self.people,
                               physical=False,
                               sampto=100000)
        data = record.d_signal
        data = data[left:right]
        channels = data.shape[1]
        # print(data)
        columns = ["channel_" + str(i) for i in range(channels)]
        df = pd.DataFrame(data, columns=columns, index=range(left, right))
        filename, _ = QFileDialog.getSaveFileName(self, "文件保存", os.getcwd(),
                                                  "Text Files (*.csv)")
        if filename == "":
            return
        df.to_csv(filename)

    # 只是打开保存的页面
    def save_widget_(self):
        self.timer.stop()
        self.bottom_layout.setCurrentIndex(3)

    def timer_(self):
        self.timer.start(20)

    def back_show(self):
        self.p.clear()
        self.flag = 0
        self.stop = 0
        self.stop_btn.setText("暂停")
        self.timer_()

    def save_fig(self):
        exporter = pg.exporters.ImageExporter(self.p)
        exporter.parameters()['width'] = 1080
        file_name = str(datetime.datetime.now())
        file_name = file_name.replace(" ", "-")
        file_name = file_name.replace(".", "-")
        file_name = file_name.replace(":", "-")
        file_name = file_name + ".png"
        exporter.export(file_name)
        QMessageBox.information(None, ("友情提示"), ("保存完毕"), QMessageBox.Cancel)

    # 停止时关闭计时器
    def stop_(self):
        if self.stop == 0:
            self.stop = 1
            self.stop_btn.setText("启动")
            self.timer.stop()
        else:
            self.stop = 0
            self.timer.start()
            self.stop_btn.setText("暂停")

    # 设置时停止计时器
    def set_(self):
        self.timer.stop()
        self.bottom_layout.setCurrentIndex(2)

    def change_status(self):
        self.timer.stop()
        if self.theme_white_radio.isChecked():
            self.setStyleSheet("")
        else:
            self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())

    def show_help(self):
        self.timer.stop()
        self.bottom_layout.setCurrentIndex(1)
        if (self.help == 0):
            self.help += 1
            with open("help.txt", "r") as f:
                text = f.readlines()
                for line in text:
                    self.help_text.append(line)

    def show_ecg1(self):
        string = self.data_com.currentText()
        self.people = string
        self.p.clear()
        # 重置为 0 方可读取数据
        self.flag = 0
        self.timer_()

    def show_ecg(self):
        # 捕获当前用户
        self.bottom_layout.setCurrentIndex(0)

    def update(self):
        if self.people == "":
            pass
        else:
            # 第一次只读取 10000 数据
            if self.flag == 0:
                self.data = wfdb.rdrecord('MIT-BIH/mit-bih-database/' +
                                          self.people,
                                          sampfrom=0,
                                          sampto=10000,
                                          physical=False,
                                          channels=[
                                              0,
                                          ])
                # 先取这么多数据
                self.count = 250
                data = self.data.d_signal[:self.count].reshape(self.count)
                self.curve = self.p.plot(
                    data, pen=pg.mkPen(width=self.line_width_spin.value()))
                self.flag += 1
            # 第二次开始绘制,每次只绘制一个数据点
            else:
                if self.stop != 1:
                    self.count += 1
                    # 每次多取一个数据
                    data = self.data.d_signal[:self.count].reshape(self.count)
                    # 删除第一个数据 新加一个数据
                    data[:-1] = data[1:]
                    data[-1] = self.data.d_signal[self.count]
                    self.curve.setData(data)
Esempio n. 33
0
    def __init__(self, File, SoftName, Title, Parent=None):
        super().__init__(Parent)


        ### Création de la fenêtre
        Dialog = QDialog(self)
        Dialog.setWindowTitle(Title)
        Dialog.setAttribute(Qt.WA_DeleteOnClose)
        Dialog.setMinimumHeight(400)
        Dialog.setMinimumWidth(500)


        ### Création du QTextEdit
        Text = QTextEdit(Dialog)
        Text.setReadOnly(True)
        Text.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        Text.setLineWrapMode(QTextEdit.WidgetWidth)


        ### Lecture du fichier changelog
        with gzip.open(File, 'rb') as f:
            file_content = f.read()


        ### Lecture ligne par ligne du texte
        for Line in file_content.decode('utf-8').split("\n"):
            NewLine = Line

            ## Coloration du nom du soft
            if SoftName in Line:
                NewLine = NewLine.replace(SoftName, '<span style="color:red">{}</span>'.format(SoftName))

            ## Coloration du texte entre parentheses
            if "(" in Line:
                text = Line.split("(")[1].split(")")[0]
                NewLine = NewLine.replace(text, '<span style="color:blue">{}</span>'.format(text))

            ## Coloration du texte entre crochets
            if "[" in Line:
                text = Line.split("[")[1].split("]")[0]
                NewLine = NewLine.replace(text, '<span style="color:green">{}</span>'.format(text))

            ## Coloration du texte entre crochets
            if "<" in Line:
                text = Line.split("<")[1].split(">")[0]
                NewLine = NewLine.replace("<{}>".format(text), '&lt;<span style="color:gray">{}</span>&gt;'.format(text))

            ## Coloration du nom du créateur
            if "Belleguic Terence" in Line or "hizoka" in Line or "Hizoka" in Line:
                NewLine = NewLine.replace("Belleguic Terence", '<span style="color:darkblue">Belleguic Terence</span>')
                NewLine = NewLine.replace("Hizoka", '<span style="color:darkblue">Hizoka</span>')
                NewLine = NewLine.replace("hizoka", '<span style="color:darkblue">Hizoka</span>')

            ## Envoie de la lgine dans le widget
            Text.append(NewLine)


        ### Placement en haut du texte
        Text.moveCursor(QTextCursor.Start)


        ### Bouton de sortie
        Button = QDialogButtonBox(QDialogButtonBox.Close, Dialog)
        Button.clicked.connect(Dialog.close)


        ### Présentation de la fenêtre
        Layout1 = QHBoxLayout()
        Layout1.addStretch()
        Layout1.addWidget(Button)

        Layout2 = QVBoxLayout()
        Layout2.addWidget(Text)
        Layout2.addLayout(Layout1)

        Dialog.setLayout(Layout2)


        ### Affichage de la fenêtre
        Dialog.exec()
Esempio n. 34
0
class Browser(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        # 脚本
        self.profile = QWebEngineProfile.defaultProfile()
        self.script = QWebEngineScript()
        self.prepare_script()

    def init_ui(self):
        self.webView = QWebEngineView()
        self.logEdit = QTextEdit()
        self.logEdit.setFixedHeight(100)
        self.addrEdit = QLineEdit()
        self.addrEdit.returnPressed.connect(self.load_url)
        self.webView.urlChanged.connect(
            lambda i: self.addrEdit.setText(i.toDisplayString()))
        self.jsEdit = QLineEdit()
        self.jsEdit.setText('inject.js')
        loadUrlBtn = QPushButton('加载')
        loadUrlBtn.clicked.connect(self.load_url)
        chooseJsBtn = QPushButton('选择脚本文件')
        chooseJsBtn.clicked.connect(self.choose_js_file)
        # 导航/工具
        top = QWidget()
        top.setFixedHeight(80)
        topBox = QVBoxLayout(top)
        topBox.setSpacing(0)
        topBox.setContentsMargins(5, 0, 0, 5)
        progBar = QProgressBar()
        progBox = QHBoxLayout()
        progBox.addWidget(progBar)
        topBox.addLayout(progBox)
        naviBox = QHBoxLayout()
        naviBox.addWidget(QLabel('网址'))
        naviBox.addWidget(self.addrEdit)
        naviBox.addWidget(loadUrlBtn)
        topBox.addLayout(naviBox)
        naviBox = QHBoxLayout()
        naviBox.addWidget(QLabel('注入脚本文件'))
        naviBox.addWidget(self.jsEdit)
        naviBox.addWidget(chooseJsBtn)
        topBox.addLayout(naviBox)
        self.webView.loadProgress.connect(progBar.setValue)
        # 主界面
        layout = QVBoxLayout(self)
        layout.addWidget(self.webView)
        layout.addWidget(top)
        layout.addWidget(self.logEdit)
        self.show()
        self.resize(1024, 900)
        self.center()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    @pyqtSlot()
    def load_url(self):
        url = self.addrEdit.text().strip()
        if not url.lower().startswith(
                'http://') and not url.lower().startswith('https://'):
            url = 'http://{}'.format(url)
        self.load(url)

    @pyqtSlot()
    def choose_js_file(self):
        f, _ = QFileDialog.getOpenFileName(filter="Javascript files(*.js)")
        if os.path.isfile(f):
            self.jsEdit.setText(f)
            self.prepare_script()

    def prepare_script(self):
        path = self.jsEdit.text().strip()
        if not os.path.isfile(path):
            self.log('invalid js path')
            return
        self.profile.scripts().remove(self.script)
        with open(path, 'r') as f:
            self.script.setSourceCode(f.read())
        self.profile.scripts().insert(self.script)
        self.log('injected js ready')

    def log(self, msg, *args, **kwargs):
        m = msg.format(*args, **kwargs)
        self.logEdit.append('{} {}'.format(datetime.now().strftime('%H:%M:%S'),
                                           m))

    def load(self, url):
        self.log(f'loading {url}')
        self.addrEdit.setText(url)
        self.webView.load(QUrl(url))
class Mainframe(QWidget):
    def __init__(self):
        super().__init__()

        self.layout = QGridLayout()
        self.pannel = QWidget(self)
        self.qp = QPainter()
        self.sizeScreen = QDesktopWidget().availableGeometry()

        self.newWindow = None

        self.figures = []

        self.set1 = []
        self.set2 = []

        self.newWindow = None

        self.textEdit1 = QTextEdit()
        self.textEdit2 = QTextEdit()

        self.text_edit_x = QDoubleSpinBox()
        self.text_edit_change_x = QDoubleSpinBox()
        self.text_edit_y = QDoubleSpinBox()
        self.text_edit_change_y = QDoubleSpinBox()

        self.button_add = QPushButton("Добавить")
        self.button_find = QPushButton("Ответ")
        self.button_delete_all = QPushButton("Удалить все")
        self.button_change = QPushButton("Изменить точку")
        self.button_delete = QPushButton("Удалить")

        self.radio_button_1 = QRadioButton("set 1")
        self.radio_button_2 = QRadioButton("set 2")
        self.radio_group = QButtonGroup()

        self.label_x = QLabel("x")
        self.label_y = QLabel("y")
        self.label_set1 = QLabel("Set 1")
        self.label_set2 = QLabel("Set 2")

        self.__adjustWidgets()

        self.initUI()

    def __adjustWidgets(self):
        self.textEdit1.setReadOnly(True)
        self.textEdit2.setReadOnly(True)

        self.text_edit_x.setMinimum(-1 * self.sizeScreen.width())
        self.text_edit_x.setMaximum(self.sizeScreen.width())

        self.text_edit_change_x.setMinimum(-1 * self.sizeScreen.width() - 10)
        self.text_edit_change_x.setMaximum(self.sizeScreen.width())

        self.text_edit_y.setMinimum(-1 * self.sizeScreen.height())
        self.text_edit_y.setMaximum(self.sizeScreen.height())

        self.text_edit_change_y.setMinimum(-1 * self.sizeScreen.height())
        self.text_edit_change_y.setMaximum(self.sizeScreen.height())

        self.radio_group.addButton(self.radio_button_1)
        self.radio_group.addButton(self.radio_button_2)

        self.button_add.clicked.connect(self.__OnAddClicked)
        self.button_find.clicked.connect(self.__OnFindClicked)
        self.button_change.clicked.connect(self.__buttonChangeEvent)
        self.button_delete.clicked.connect(self.__deletePoint)
        self.button_delete_all.clicked.connect(self.__deleteAllButtonEvent)

    def __deletePoint(self):
        cursor1 = self.textEdit1.textCursor()
        cursor2 = self.textEdit2.textCursor()

        textSelected1 = cursor1.selectedText()
        textSelected2 = cursor2.selectedText()

        textSelected1.strip()
        textSelected2.strip()

        x1, y1 = self.__isPoinFormat(textSelected1)
        x2, y2 = self.__isPoinFormat(textSelected2)

        if x1 != None and y1 != None:
            idx = self.getIndex(self.set1, MyPoint(x1, y1))
            self.set1.pop(idx)
            self.__fillEditText(self.textEdit1, self.set1)
        elif x2 != None and y2 != None:
            idx = self.getIndex(self.set2, MyPoint(x2, y2))
            self.set2.pop(idx)
            self.__fillEditText(self.textEdit2, self.set2)

    def getIndex(self, set, point):
        for i in range(len(set)):
            if set[i].get_x() == point.get_x() and set[i].get_y(
            ) == point.get_y():
                return i
        return -1

    def __buttonChangeEvent(self):
        cursor1 = self.textEdit1.textCursor()
        cursor2 = self.textEdit2.textCursor()

        textSelected1 = cursor1.selectedText()
        textSelected2 = cursor2.selectedText()

        x1, y1 = self.__isPoinFormat(textSelected1)
        x2, y2 = self.__isPoinFormat(textSelected2)
        newX = self.text_edit_change_x.value()
        newY = self.text_edit_change_y.value()

        newPoint = MyPoint(newX, newY)

        if x1 != None and y1 != None:
            point1 = MyPoint(x1, y1)
            if not self.__isIn(self.set1, newPoint):
                self.__replacePoint(point1, newPoint, self.set1)
                self.__fillEditText(self.textEdit1, self.set1)
        elif x2 != None and y2 != None:
            point2 = MyPoint(x2, y2)
            if not self.__isIn(self.set2, newPoint):
                self.__replacePoint(point2, newPoint, self.set2)
                self.__fillEditText(self.textEdit2, self.set2)

    def __replacePoint(self, oldPoint, newPoint, set):
        for i in range(len(set)):
            if set[i].get_x() == oldPoint.get_x() and set[i].get_y(
            ) == oldPoint.get_y():
                set[i].set_x(newPoint.get_x())
                set[i].set_y(newPoint.get_y())

    def __isPoinFormat(self, text):
        text = text.__str__()
        splited = text.split(',')
        if len(splited) == 2:
            splited[0].strip()
            splited[1].strip()
            try:
                return float(splited[0]), float(splited[1])
            except ValueError:
                return None, None
        return None, None

    def __isInt(self, str):
        return true

    def __isIn(self, set, point):
        for i in range(len(set)):
            if set[i].get_x() == point.get_x() and set[i].get_y(
            ) == point.get_y():
                return True
        return False

    def __OnAddClicked(self):
        x = self.text_edit_x.value()
        y = self.text_edit_y.value()
        newPoint = MyPoint(x, y)
        if self.radio_button_1.isChecked() and not self.__isIn(
                self.set1, newPoint):
            self.set1.append(newPoint)
            str = ""
            str += (newPoint.get_x()).__str__()
            str += ','
            str += (newPoint.get_y()).__str__()
            self.textEdit1.append(str)
        elif self.radio_button_2.isChecked() and not self.__isIn(
                self.set2, newPoint):
            self.set2.append(newPoint)
            str = ""
            str += (newPoint.get_x()).__str__()
            str += ','
            str += (newPoint.get_y()).__str__()
            self.textEdit2.append(str)

    def __fillEditText(self, textEdit, set):
        textEdit.clear()
        text = ""
        for i in range(len(set)):
            text += str(set[i].get_x())
            text += ","
            text += str(set[i].get_y())
            #text += "\n"
            textEdit.append(text)
            text = ""
        #textEdit.setPlainText(text)

    def initUI(self):
        self.pannel.setGeometry(QRect(0, 0, 400, 500))
        self.setGeometry(0, 0, 400, 500)

        self.__addWidgets()

        self.pannel.setLayout(self.layout)
        self.setWindowTitle('Lab 1')
        self.show()

    def __clearInput(self):
        self.textEdit1.clear()
        self.textEdit2.clear()
        self.set1.clear()
        self.set2.clear()

    # def __clearDrawing(self):
    #     self.figures.clear()

    def __OnFindClicked(self):
        self.figures.clear()
        self.__findPoints(self.set1, self.set2)
        if len(self.figures):

            self.newWindow = Drawing(self.figures, self.set1, self.set2)
            # self.newWindow.setFigures(self.figures)
            self.newWindow.show()
        else:
            self.__showErrorMessage("Ничего не найдено!")

    def __deleteAllButtonEvent(self):
        self.__clearInput()

    def __parseText(self):
        self.__findPoints(set1, set2)

    def findCenter(self, p1, p2, p3):
        A = 2 * (p2.get_x() - p1.get_x())
        B = 2 * (p2.get_y() - p1.get_y())
        C = (p2.get_x()**2) - (p1.get_x()**2) + (p2.get_y()**2) - (p1.get_y()**
                                                                   2)
        D = 2 * (p3.get_x() - p2.get_x())
        E = 2 * (p3.get_y() - p2.get_y())
        F = (p3.get_x()**2) - (p2.get_x()**2) + (p3.get_y()**2) - (p2.get_y()**
                                                                   2)

        x0 = round((C * E - B * F) / (A * E - B * D), 2)
        y0 = round((A * F - D * C) / (A * E - D * B), 2)
        return MyPoint(x0, y0)

    def findRadius(self, center, p):
        a = (p.get_x() - center.get_x())**2 + (p.get_y() - center.get_y())**2
        rad = sqrt((p.get_x() - center.get_x())**2 +
                   (p.get_y() - center.get_y())**2)
        return rad

    def __findPoints(self, set1, set2):
        for i in range(len(set1)):
            for j in range(i + 1, len(set1)):
                for k in range(i + 2, len(set1)):
                    if not self.__isPointsInOneLine(set1[i], set1[j], set1[k]):
                        for i2 in range(len(set2)):
                            for j2 in range(i2 + 1, len(set2)):
                                for k2 in range(i2 + 2, len(set2)):
                                    if not self.__isPointsInOneLine(
                                            set2[i2], set2[j2], set2[k2]):

                                        point11 = MyPoint(
                                            set1[i].get_x(), set1[i].get_y())
                                        point12 = MyPoint(
                                            set1[j].get_x(), set1[j].get_y())
                                        point13 = MyPoint(
                                            set1[k].get_x(), set1[k].get_y())

                                        point21 = MyPoint(
                                            set2[i2].get_x(), set2[i2].get_y())
                                        point22 = MyPoint(
                                            set2[j2].get_x(), set2[j2].get_y())
                                        point23 = MyPoint(
                                            set2[k2].get_x(), set2[k2].get_y())

                                        center1 = self.findCenter(
                                            point11, point12, point13)
                                        center2 = self.findCenter(
                                            point21, point22, point23)

                                        rad1 = round(
                                            self.findRadius(center1, point11),
                                            2)
                                        rad2 = round(
                                            self.findRadius(center2, point21),
                                            2)
                                        self.__checkCircles(
                                            center1, center2, rad1, rad2)

    def addCircles(self, c1, c2, r1, r2, position):
        a = 1
        n = TwoCircles(c1, c2, r1, r2, position)
        self.figures.append(n)

    def __randomColor(self):
        return (random.randint(0, 255), random.randint(0, 255),
                random.randint(0, 255))

    def __checkCircles(self, c1, c2, r1, r2):
        if c1.get_x() == c2.get_x() and c1.get_y() == c2.get_y() and r1 != r2:
            return False
        max_y1 = c1.get_y() + r1
        max_y2 = c2.get_y() + r2
        min_y1 = c1.get_y() - r1
        min_y2 = c2.get_y() - r2
        position = None
        if max_y1 == max_y2:
            position = (MyPoint(c1.get_x(), max_y1),
                        MyPoint(c2.get_x(), max_y2))  #TangentPosition.downDown
        # elif max_y1 == min_y2:
        #     position =  (MyPoint(c1.get_x(), max_y1),
        #                  MyPoint(c2.get_x(), min_y2))#TangentPosition.downUp
        elif min_y1 == min_y2:
            position = (MyPoint(c1.get_x(), min_y1),
                        MyPoint(c2.get_x(), min_y2))  #TangentPosition.upUp
        # elif min_y1 == max_y2:
        #     position = (MyPoint(c1.get_x(), min_y1),
        #                 MyPoint(c2.get_x(), max_y2)) #TangentPosition.upDown

        if (position != None):
            self.addCircles(c1, c2, r1, r2, position)

    def __isPointsInOneLine(self, p1, p2, p3):
        return ((p2.get_y() - p1.get_y()) *
                (p3.get_x() - p1.get_x()) == (p3.get_y() - p1.get_y()) *
                (p2.get_x() - p1.get_x()))
        #return (p1.get_y() - p2.get_y()) * p3.get_x() + (p2.get_x() - p1.get_x()) * p3.get_y() + (p1.get_x() * p2.get_y() - p2.get_x() * p1.get_y()) == 0

    def __toCoordFormat(self, set):
        message = ""
        res = []
        for i in range(0, len(set)):
            tmp = set[i].split(',')
            if len(tmp) == 2 and tmp[0].isdecimal() and tmp[1].isdecimal():
                res.append([float(tmp[0]), float(tmp[1])])
            else:
                if len(tmp) != 2:
                    message = "Incorrect input!"
                if tmp[0].isdecimal() and tmp[1].isdecimal():
                    message = "You must imput at least 3 points in each set!"
                return None, message
        return res, message

    def __checkPointFormat(self, arr):
        for i in range(0, len(arr)):
            splitArr = arr[i].split(',')
            if len(splitArr) == 2 and splitArr[0].isdecimal(
            ) and splitArr[1].isdecimal():
                continue
            return False
        return True

    def __infoButtonEvent(self):
        self.__showMessage(self.info)

    def __addWidgets(self):
        self.layout.addWidget(self.label_set1, 0, 0)
        self.layout.addWidget(self.label_set2, 0, 1)
        self.layout.addWidget(self.textEdit1, 1, 0)
        self.layout.addWidget(self.textEdit2, 1, 1)

        self.layout.addWidget(self.button_add, 2, 0)
        self.layout.addWidget(self.text_edit_x, 2, 1)
        self.layout.addWidget(QLabel("x"), 2, 2)
        self.layout.addWidget(self.text_edit_y, 3, 1)
        self.layout.addWidget(QLabel("y"), 3, 2)
        self.layout.addWidget(QLabel("set"), 4, 0)
        self.layout.addWidget(self.radio_button_1, 4, 1)
        self.layout.addWidget(self.radio_button_2, 5, 1)

        self.layout.addWidget(self.button_find, 6, 0)
        self.layout.addWidget(self.button_change, 7, 0)
        self.layout.addWidget(self.text_edit_change_x, 7, 1)
        self.layout.addWidget(QLabel("x"), 7, 2)
        self.layout.addWidget(self.text_edit_change_y, 8, 1)
        self.layout.addWidget(QLabel("y"), 8, 2)

        self.layout.addWidget(self.button_delete, 9, 0)
        self.layout.addWidget(self.button_delete_all, 10, 0)

    # def __showMessage(self, message):
    #     message_box = QMessageBox.information(self, "Info", message)

    def __showErrorMessage(self, message):
        error_message = QErrorMessage(self)
        error_message.setWindowTitle("Error")
        error_message.showMessage(message)

    def paintEvent(self, e):
        self.drawPlane()

    # def drawAxes(self):
    #     self.qp.drawLine(10,0, 10, self.sizeScreen.height())

    def drawPlane(self):
        self.coordinatePlane = CoordinatePlane(self.size())
        self.qp.begin(self)
        self.qp.setPen(Qt.black)

        self.qp.end()
Esempio n. 36
0
 def setupUI(self):
    self.setWindowTitle('Nemu Settings')
    self.mainLayout = QVBoxLayout(self)
    
    self.tabs = QTabWidget(self)
    self.mainLayout.addWidget(self.tabs)
    
    importPage = QWidget()
    importPageLayout = QVBoxLayout(importPage)
    self.importFileText = QLineEdit()
    self.importFileSelect = QPushButton('System')
    self.importFileSelect.clicked.connect(self.importSelectClicked)
    self.importFileUser = QPushButton('User')
    self.importFileUser.clicked.connect(self.importUserClicked)
    self.addWidgets(importPageLayout, 'Menu File', [self.importFileText, self.importFileSelect, self.importFileUser])
    
    themes = self.getIconThemes()
    self.themeCombo = QComboBox()
    self.themeCombo.addItems(themes)
    self.themeCombo.setToolTip('Use icons from this theme if possible')
    self.addWidgets(importPageLayout, 'Preferred Icon Theme', [self.themeCombo])
    
    self.replaceCheck = QCheckBox('Replace Existing')
    self.replaceCheck.setToolTip('Replace current menu with imported one - otherwise the imported menu will be merged')
    importPageLayout.addWidget(self.replaceCheck)
    
    self.importButton = QPushButton('Import')
    self.importButton.clicked.connect(self.importClicked)
    importPageLayout.addWidget(self.importButton)
    
    self.refreshButton = QPushButton('Refresh Existing')
    self.refreshButton.clicked.connect(self.refreshClicked)
    self.refreshButton.setToolTip('Import any items added to previously imported menus')
    importPageLayout.addWidget(self.refreshButton)
    
    self.importProgress = QProgressBar()
    importPageLayout.addWidget(self.importProgress)
    
    self.importStatus = QLabel()
    self.importStatus.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
    importPageLayout.addWidget(self.importStatus)
    
    quitPage = QWidget()
    quitPageLayout = QVBoxLayout(quitPage)
    quitText = QTextEdit()
    quitText.append('For performance reasons, Nemu only hides itself when it loses focus.  If this causes problems, such as Nemu not hiding properly, click the box below to force it to quit completely.  Note that this will likely cause it to start more slowly.')
    quitText.setReadOnly(True)
    self.quitCheck = QCheckBox('Quit instead of hide')
    quitPageLayout.addWidget(quitText)
    quitPageLayout.addWidget(self.quitCheck)
    
    aboutPage = QWidget()
    aboutPageLayout = QVBoxLayout(aboutPage)
    aboutText = QTextEdit()
    aboutText.setAlignment(Qt.AlignCenter)
    aboutText.append('Nemu\n')
    aboutText.append('Copyright 2012 Ben Nemec\n')
    aboutText.append("Distributed under the GPLv3\n")
    aboutText.append("Web: TBD\n")
    aboutText.append("E-Mail: [email protected]\n")
    aboutText.setReadOnly(True)
    aboutPageLayout.addWidget(aboutText)
    
    self.tabs.addTab(importPage, 'Import Menu')
    self.tabs.addTab(quitPage, 'Quit')
    self.tabs.addTab(aboutPage, 'About')
    
    self.bottomButtonLayout = QHBoxLayout()
    self.okButton = QPushButton('OK')
    self.okButton.clicked.connect(self.okClicked)
    self.bottomButtonLayout.addWidget(self.okButton)
    
    self.cancelButton = QPushButton('Cancel')
    self.cancelButton.clicked.connect(self.close)
    self.bottomButtonLayout.addWidget(self.cancelButton)
    
    self.mainLayout.addLayout(self.bottomButtonLayout)
    
    self.resize(500, 280)
Esempio n. 37
0
class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setWindowTitle(__namever__)
        self.setWindowIcon(icons.get_icon('master'))

        if platform.system() == 'Windows':
            import ctypes
            myappid = 'gwhat_application'  # arbitrary string
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                myappid)

        # Setup preferences :

        self.whatPref = WHATPref(self)
        self.projectfile = self.whatPref.projectfile
        self.projectdir = osp.dirname(self.projectfile)

        # Setup the project and data managers.
        splash.showMessage("Initializing project and data managers...")
        self.pmanager = ProjetManager(self)
        self.pmanager.currentProjetChanged.connect(self.new_project_loaded)
        self.dmanager = DataManager(parent=self, pm=self.pmanager)
        self.dmanager.setMaximumWidth(250)
        self.dmanager.sig_new_console_msg.connect(self.write2console)

        # Generate the GUI.
        self.__initUI__()
        splash.finish(self)
        self.showMaximized()

        # Load the last opened project :

        result = self.pmanager.load_project(self.projectfile)
        if result is False:
            self.tab_dwnld_data.setEnabled(False)
            self.tab_fill_weather_data.setEnabled(False)
            self.tab_hydrograph.setEnabled(False)
            self.tab_hydrocalc.setEnabled(False)

    def __initUI__(self):

        # ---- TAB WIDGET

        # download weather data :

        splash.showMessage("Initializing download weather data...")
        self.tab_dwnld_data = DwnldWeatherWidget(self)
        self.tab_dwnld_data.set_workdir(self.projectdir)

        # gapfill weather data :

        splash.showMessage("Initializing gapfill weather data...")
        self.tab_fill_weather_data = GapFillWeatherGUI(self)
        self.tab_fill_weather_data.set_workdir(self.projectdir)

        # hydrograph :

        splash.showMessage("Initializing plot hydrograph...")
        self.tab_hydrograph = HydroPrint.HydroprintGUI(self.dmanager)

        splash.showMessage("Initializing analyse hydrograph...")
        self.tab_hydrocalc = HydroCalc.WLCalc(self.dmanager)
        self.tab_hydrocalc.sig_new_mrc.connect(
            self.tab_hydrograph.mrc_wl_changed)
        self.tab_hydrocalc.rechg_eval_widget.sig_new_gluedf.connect(
            self.tab_hydrograph.glue_wl_changed)

        # ---- TABS ASSEMBLY

        self.tab_widget = TabWidget()
        self.tab_widget.addTab(self.tab_dwnld_data, 'Download Weather')
        self.tab_widget.addTab(self.tab_fill_weather_data, 'Gapfill Weather')
        self.tab_widget.addTab(self.tab_hydrograph, 'Plot Hydrograph')
        self.tab_widget.addTab(self.tab_hydrocalc, 'Analyze Hydrograph')
        self.tab_widget.setCornerWidget(self.pmanager)

        self.tab_widget.currentChanged.connect(self.sync_datamanagers)

        # ---- Main Console

        splash.showMessage("Initializing main window...")
        self.main_console = QTextEdit()
        self.main_console.setReadOnly(True)
        self.main_console.setLineWrapMode(QTextEdit.NoWrap)

        style = 'Regular'
        family = StyleDB().fontfamily
        size = self.whatPref.fontsize_console
        fontSS = ('font-style: %s;'
                  'font-size: %s;'
                  'font-family: %s;'
                  ) % (style, size, family)
        self.main_console.setStyleSheet("QWidget{%s}" % fontSS)

        msg = '<font color=black>Thanks for using %s.</font>' % __appname__
        self.write2console(msg)
        self.write2console('<font color=black>'
                           'Please report any bug or wishful feature at'
                           ' [email protected].'
                           '</font>')

        # ---- Signal Piping

        issuer = self.tab_dwnld_data
        issuer.ConsoleSignal.connect(self.write2console)

        issuer = self.tab_fill_weather_data
        issuer.ConsoleSignal.connect(self.write2console)

        issuer = self.tab_hydrograph
        issuer.ConsoleSignal.connect(self.write2console)

        # ---- Splitter Widget

        splitter = QSplitter(self)
        splitter.setOrientation(Qt.Vertical)

        splitter.addWidget(self.tab_widget)
        splitter.addWidget(self.main_console)

        splitter.setCollapsible(0, True)
        splitter.setStretchFactor(0, 100)
        # Forces initially the main_console to its minimal height:
        splitter.setSizes([100, 1])

        # ---- Main Grid

        main_widget = QWidget()
        self.setCentralWidget(main_widget)

        mainGrid = QGridLayout(main_widget)

        mainGrid.addWidget(splitter, 0, 0)
        mainGrid.addWidget(self.tab_fill_weather_data.pbar, 1, 0)
        mainGrid.addWidget(self.tab_dwnld_data.pbar, 2, 0)
        mainGrid.addWidget(
            self.tab_hydrocalc.rechg_eval_widget.progressbar, 3, 0)

    def write2console(self, text):
        """
        This function is the bottle neck through which all messages writen
        in the console must go through.
        """
        textime = '<font color=black>[%s] </font>' % ctime()[4:-8]
        self.main_console.append(textime + text)

    def sync_datamanagers(self):
        """
        Move the data manager from tab _Plot Hydrograph_ to tab
        _Analyze Hydrograph_ and vice-versa.
        """
        current = self.tab_widget.tabBar().currentIndex()
        if current == 3:
            self.tab_hydrocalc.right_panel.addWidget(self.dmanager, 0, 0)
        elif current == 2:
            self.tab_hydrograph.right_panel.addWidget(self.dmanager, 0, 0)

    def new_project_loaded(self):
        """Handles when a new project is loaded in the project manager."""

        filename = self.pmanager.projet.filename
        dirname = os.path.dirname(filename)

        # Update WHAT.pref file :

        self.whatPref.projectfile = filename
        self.whatPref.save_pref_file()

        # Update UI :

        self.tab_dwnld_data.setEnabled(True)
        self.tab_fill_weather_data.setEnabled(True)
        self.tab_hydrograph.setEnabled(True)
        self.tab_hydrocalc.setEnabled(True)

        # Update the child widgets :

        # dwnld_weather_data
        lat = self.pmanager.projet.lat
        lon = self.pmanager.projet.lon
        self.tab_dwnld_data.set_workdir(dirname)
        self.tab_dwnld_data.set_station_browser_latlon((lat, lon))

        # fill_weather_data
        self.tab_fill_weather_data.set_workdir(dirname)
        self.tab_fill_weather_data.load_data_dir_content()

    def show(self):
        """Qt method override to center the app on the screen."""
        super(MainWindow, self).show()
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def closeEvent(self, event):
        """Qt method override to close the project before close the app."""
        print('Closing projet')
        self.pmanager.close_projet()
        print('Closing GWHAT')
        event.accept()
Esempio n. 38
0
class Window(QWidget):
    finished = pyqtSignal(int)

    def __init__(self):
        QWidget.__init__(self)
        layout = QVBoxLayout(self)
        self.button = QPushButton('Get Messages')
        self.edit = QTextEdit()
        layout.addWidget(self.edit)
        layout.addWidget(self.button)
        self.button.clicked.connect(self.handleTest)

        log('About to setup the EMailServer')
        self.email_server = EMailServer(EmailAccount)

        self.setGeometry(100, 100, 900, 600)
        self.setWindowTitle('Mail Headers')
        self.show()

        self.update_headers(self.email_server.headers)
#        self.start_worker()

    def handleTest(self):
        self.edit.setReadOnly(False)
        self.edit.clear()
        self.refresh()
        self.edit.setReadOnly(True)

    def refresh(self, latest=None):
        """Get all headers after given ID.

        latest  ID of last received email
        """

        if latest is None:
            headers = self.email_server.get_headers(EmailBox)
        else:
            headers = self.email_server.get_headers(EmailBox)
        log('refresh: headers=%s' % str(headers))
        self.email_server.put_saved_headers(headers)
        self.update_headers(headers)

    def update_headers(self, headers):
        for (id, header, frm, datetime) in headers:
            self.edit.append(header + ' ' + frm)

    def start_worker(self):
        log('start_worker: starting')
        self.thread = QThread()
        self.finished[int].connect(self.refresh_box)
        self.thread.started.connect(self.get_all_headers)
        self.thread.start()

    @pyqtSlot(int)
    def refresh_box(self, i):
        log("refresh_box: Base caught finished, {}".format(i))

    def get_all_headers(self, result=42):
        log("Worker work")
        self.refresh()
        self.finished.emit(result)
Esempio n. 39
0
class MainWidget(QWidget):
    def __init__(self, user):
        super().__init__()

        self.serverRole = False
        self.tcp_ip = '192.168.1.1'
        #self.tcp_ip = '127.0.0.1'
        self.tcp_port = 5005
        self.buffer_size = 1024
        self.message = ""
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        if sys.argv[1] != "test":
            self.db = shelve.open('database5', 'c')


        self.serverThread = ServerWaitThread(self.s, self.buffer_size)
        self.clientThread = ClientWaitThread(self.s, self.buffer_size)
        self.clientThread.receivedMessage.connect(self.handleReceivedMessage)
        self.serverThread.receivedMessage.connect(self.handleReceivedMessage)

        self.user = user
        self.messageLineEdit = QLineEdit("enter text here", self)
        self.conversationTextEdit = QTextEdit(self)
        self.sendButton = QPushButton("Send", self)

        self.setConversationTextEdit()

        self.setConnections()

        self.initLayout()

        self.initialize_socket()

    def metoda(self, text):
        print(text)

    def setConversationTextEdit(self):
        self.conversationTextEdit.setReadOnly(True)
        self.conversationTextEdit.setLineWrapMode(QTextEdit.NoWrap)

        font = self.conversationTextEdit.font()
        font.setFamily("Courier")
        font.setPointSize(10)

    def setConnections(self):
        self.sendButton.clicked.connect(self.sendButtonClicked)
        self.messageLineEdit.returnPressed.connect(self.sendButtonClicked)

    def initLayout(self):
        self.grid = QGridLayout()
        self.grid.setSpacing(10)

        self.grid.addWidget(self.messageLineEdit, 3, 1)
        self.grid.addWidget(self.conversationTextEdit, 1, 1, 2, 2)
        self.grid.addWidget(self.sendButton, 3, 2)

        self.setLayout(self.grid)

    def sendButtonClicked(self):
        text = self.user.name + "(" + time.strftime("%H:%M:%S") + ")" + "\n" + self.messageLineEdit.text()
        self.conversationTextEdit.append(text)
        text +="\n"
        if sys.argv[1] != "test":
            if self.user.name in self.db:
                self.db[self.user.name] += text
            else:
                self.db[self.user.name] = ""
                self.db[self.user.name] += text
        self.messageLineEdit.setText("")

        if self.serverRole:
            self.serverThread.sendMessageToClient(bytes(text, 'UTF-8'))
        else:
            self.clientThread.sendMessageToServer(bytes(text, 'UTF-8'))

    def handleReceivedMessage(self, data):
        self.conversationTextEdit.append(data.rstrip())
        if sys.argv[1] != "test":
            self.db[self.user.name].append(data)

    def initialize_socket(self):
        try:
            self.create_server()
            self.serverThread.begin()
            self.serverRole = True
        except:
            self.s.connect((self.tcp_ip, self.tcp_port))
            #self.s.send(bytes(self.message, 'UTF-8'))
            self.clientThread.begin()

    def create_server(self):
        print("create server")
        i = self.s.bind((self.tcp_ip, self.tcp_port))
        print(i)
        self.s.listen(2)
Esempio n. 40
0
class MainWindow(QMainWindow):

    """Main window class."""

    def __init__(self):
        """Init class."""
        super(MainWindow, self).__init__()
        self.pixmap_syncthingui = QPixmap(":/images/syncthingui.svg")
        tf = QTransform()
        self.pixmap_syncthingui0 = QPixmap(":/images/syncthingui.svg")
        tf.rotate(90.0)
        self.pixmap_syncthingui1 = self.pixmap_syncthingui0.transformed(tf)
        tf.rotate(180.0)
        self.pixmap_syncthingui2 = self.pixmap_syncthingui0.transformed(tf)
        tf.rotate(270.0)
        self.pixmap_syncthingui3 = self.pixmap_syncthingui0.transformed(tf)

        self.init_gui()
        self.init_menu()
        self.init_systray()

        self.run()

    def init_gui(self):
        """init gui setup"""
        self.setWindowIcon(QIcon(self.pixmap_syncthingui))

        self.progressbar = QProgressBar()
        self.statusBar().showMessage(getoutput(SYNCTHING + ' --version'))
        self.statusBar().addPermanentWidget(self.progressbar)
        self.setWindowTitle(__doc__.strip().capitalize())
        self.setMinimumSize(900, 600)
        self.setMaximumSize(1280, 1024)
        self.resize(self.minimumSize())
        self.center()

        # QWebView
        # self.view = QWebView(self)
        self.view = QWebEngineView(self)
        self.view.loadStarted.connect(self.start_loading)
        self.view.loadFinished.connect(self.finish_loading)
        self.view.loadProgress.connect(self.loading)
        self.view.titleChanged.connect(self.set_title)
        self.view.page().linkHovered.connect(
            lambda link_txt: self.statusBar().showMessage(link_txt[:99], 3000))
        QShortcut("Ctrl++", self, activated=lambda:
                  self.view.setZoomFactor(self.view.zoomFactor() + 0.2))
        QShortcut("Ctrl+-", self, activated=lambda:
                  self.view.setZoomFactor(self.view.zoomFactor() - 0.2))
        QShortcut("Ctrl+0", self, activated=lambda: self.view.setZoomFactor(1))
        QShortcut("Ctrl+q", self, activated=lambda: self.close())

        # syncthing console
        self.consolewidget = QWidget(self)
        # TODO: start at specify (w,h)
        self.consolewidget.setMinimumSize(QSize(200, 100))
        # TODO: setStyleSheet
        # self.consolewidget.setStyleSheet("margin:0px; padding: 0px; \
        # border:1px solid rgb(0, 0, 0);")
        # border-radius: 40px;")
        # TODO read syncthing console visible from setting
        # self.consolewidget.setVisible(False)
        # self.consolewidget.showEvent
        # self.consoletextedit = QPlainTextEdit(parent=self.consolewidget)
        self.consoletoolbar = QWidget(self)
        hlayout = QHBoxLayout()
        hlayout
        self.consoletoolbar.setLayout(hlayout)
        self.consoletextedit = QTextEdit(parent=self.consolewidget)
        self.consoletextedit.setWordWrapMode(QTextOption.NoWrap)
        # self.consoletextedit.setStyleSheet(" border:1px solid rgb(0, 0, 0);")
        # self.consoletextedit.setStyleSheet("margin:0px; padding: 0px;")
        layout = QVBoxLayout()
        layout.addWidget(self.consoletoolbar)
        layout.addWidget(self.consoletextedit)

        self.consolewidget.setLayout(layout)

        self.splitter = QSplitter(Qt.Vertical)
        self.splitter.addWidget(self.view)
        self.splitter.addWidget(self.consolewidget)

        # process
        self.process = QProcess()
        self.process.error.connect(self._process_failed)
        # QProcess emits `readyRead` when there is data to be read
        self.process.readyRead.connect(self._process_dataReady)
        self.process.stateChanged.connect(self._process_stateChanged)
        # Just to prevent accidentally running multiple times
    # Disable the button when process starts, and enable it when it finishes
    # self.process.started.connect(lambda: self.runButton.setEnabled(False))
    # self.process.finished.connect(lambda: self.runButton.setEnabled(True))

        # backend options
        self.chrt = QCheckBox("Smooth CPU ", checked=True)
        self.ionice = QCheckBox("Smooth HDD ", checked=True)
        self.chrt.setToolTip("Use Smooth CPUs priority (recommended)")
        self.ionice.setToolTip("Use Smooth HDDs priority (recommended)")
        self.chrt.setStatusTip(self.chrt.toolTip())
        self.ionice.setStatusTip(self.ionice.toolTip())
        # main toolbar
        self.toolbar = self.addToolBar("SyncthinGUI Toolbar")
        # self.toolbar.addAction(QIcon.fromTheme("media-playback-stop"),
        self.toolbar.addAction(QIcon(":/images/stop.svg"),
                               "Stop Sync", lambda: self.syncthing_stop())
        # self.toolbar.addAction(QIcon.fromTheme("media-playback-start"),
        self.toolbar.addAction(QIcon(":/images/start.svg"),
                               "Restart Sync", lambda: self.run())
        self.toolbar.addSeparator()
        self.toolbar.addWidget(self.chrt)
        self.toolbar.addWidget(self.ionice)
        self.toolbar.addSeparator()
        # TODO: test event API
        self.toolbar.addAction(QIcon(":/images/start.svg"),
                               "test ", lambda: self.test())

        # final gui setup
        self.setCentralWidget(self.splitter)

    def test(self):
        """ test some function """
        print("test")

    def init_menu(self):
        """init menu setup"""
        # file menu
        file_menu = self.menuBar().addMenu("File")
        # TODO: setting menu item
        file_menu.addAction("Exit", lambda: self.close())
        # Syncthing menu
        sync_menu = self.menuBar().addMenu("Syncthing")
        sync_menu.addAction("Start Syncronization", lambda: self.run())
        sync_menu.addAction("Stop Syncronization",
                            lambda: self.syncthing_stop())
        # TODO: restart
        # TODO: reflash F5
        sync_menu.addAction("Open in external browser",
                            lambda: open_new_tab(URL))

        # view menu
        view_menu = self.menuBar().addMenu("View")
        # TODO: syncthing console menu
        view_menu.addAction("syncthing console", lambda: self.show_console)
        #
        zoom_menu = view_menu.addMenu("Zoom browser")
        zoom_menu.addAction(
            "Zoom In",
            lambda: self.view.setZoomFactor(self.view.zoomFactor() + .2))
        zoom_menu.addAction(
            "Zoom Out",
            lambda: self.view.setZoomFactor(self.view.zoomFactor() - .2))
        zoom_menu.addAction(
            "Zoom To...",
            lambda: self.view.setZoomFactor(QInputDialog.getInt(
                self, __doc__, "<b>Zoom factor ?:", 1, 1, 9)[0]))
        zoom_menu.addAction("Zoom Reset", lambda: self.view.setZoomFactor(1))
        view_menu.addSeparator()
        act = view_menu.addAction("View Page Source",
                                  lambda: self.view_syncthing_source)
        act.setDisabled(True)

        # window menu
        window_menu = self.menuBar().addMenu("&Window")
        window_menu.addAction("Minimize", lambda: self.showMinimized())
        window_menu.addAction("Maximize", lambda: self.showMaximized())
        window_menu.addAction("Restore", lambda: self.showNormal())
        window_menu.addAction("Center", lambda: self.center())
        window_menu.addAction("Top-Left", lambda: self.move(0, 0))
        window_menu.addAction("To Mouse",
                              lambda: self.move_to_mouse_position())
        window_menu.addAction("Fullscreen", lambda: self.showFullScreen())
        window_menu.addSeparator()
        window_menu.addAction("Increase size", lambda: self.resize(
            self.size().width() * 1.2, self.size().height() * 1.2))
        window_menu.addAction("Decrease size", lambda: self.resize(
            self.size().width() // 1.2, self.size().height() // 1.2))
        window_menu.addAction("Minimum size", lambda:
                              self.resize(self.minimumSize()))
        window_menu.addAction("Maximum size", lambda:
                              self.resize(self.maximumSize()))
        window_menu.addAction("Horizontal Wide", lambda: self.resize(
            self.maximumSize().width(), self.minimumSize().height()))
        window_menu.addAction("Vertical Tall", lambda: self.resize(
            self.minimumSize().width(), self.maximumSize().height()))
        window_menu.addSeparator()
        window_menu.addAction("Disable Resize",
                              lambda: self.setFixedSize(self.size()))
        # help menu
        help_menu = self.menuBar().addMenu("&Help")
        help_menu.addAction("Support Forum", lambda: open_new_tab(HELP_URL_0))
        help_menu.addAction("Lastest Release",
                            lambda: open_new_tab(HELP_URL_1))
        help_menu.addAction("Documentation", lambda: open_new_tab(HELP_URL_2))
        help_menu.addAction("Bugs", lambda: open_new_tab(HELP_URL_3))
        help_menu.addAction("Source Code", lambda: open_new_tab(HELP_URL_4))
        help_menu.addSeparator()
        help_menu.addAction("About Qt 5", lambda: QMessageBox.aboutQt(self))
        help_menu.addAction("About Python 3",
                            lambda: open_new_tab('https://www.python.org'))
        help_menu.addAction("About " + __doc__,
                            lambda: QMessageBox.about(self, __doc__, HELPMSG))
        help_menu.addSeparator()
        help_menu.addAction("Keyboard Shortcuts", lambda:
                            QMessageBox.information(self, __doc__, SHORTCUTS))
        help_menu.addAction("View GitHub Repo", lambda: open_new_tab(__url__))
        if not sys.platform.startswith("win"):
            help_menu.addAction("Show Source Code", lambda: self.view_source())
        help_menu.addSeparator()
        help_menu.addAction("Check Updates", lambda: self.check_for_updates())

    def init_systray(self):
        """init system tray icon"""
        # self.tray = QSystemTrayIcon(QIcon(self.pixmap_syncthingui), self)
        self.tray = AnimatedSysTrayIcon(QIcon(self.pixmap_syncthingui), self)
        self.tray.add_ani_icon(QIcon(self.pixmap_syncthingui0))
        self.tray.add_ani_icon(QIcon(self.pixmap_syncthingui1))
        self.tray.add_ani_icon(QIcon(self.pixmap_syncthingui2))
        self.tray.add_ani_icon(QIcon(self.pixmap_syncthingui3))

        self.tray.setToolTip(__doc__.strip().capitalize())
        traymenu = QMenu(self)
        traymenu.addAction(__doc__).setDisabled(True)
        traymenu.addSeparator()
        # to test animate
        # traymenu.addAction("start", lambda: self.tray.animate_start())
        # traymenu.addAction("stop", lambda: self.tray.animate_stop())
        # traymenu.addSeparator()
        traymenu.addAction("Stop Sync", lambda: self.syncthing_stop())
        traymenu.addAction("Restart Sync", lambda: self.run())
        traymenu.addSeparator()
        traymenu.addAction("Show", lambda: self.show_gui())
        traymenu.addAction("Hide", lambda: self.hide())
        traymenu.addSeparator()
        # traymenu.addAction("Open Web", lambda: open_new_tab(URL))
        # traymenu.addAction("Quit All", lambda: self.close())
        traymenu.addAction("Quit All", lambda: self.app_exit())
        self.tray.setContextMenu(traymenu)
        self.tray.show()

    def show_gui(self):
        """
        Helper method to show UI, this should not be needed, but I discovered.
        """
        self.showNormal()
        # webview require 70Mb to show webpage
        self.view.load(QUrl(URL))

    def syncthing_start(self):
        """syncthing start"""
        self.run()

    def syncthing_stop(self):
        """syncthing stop"""
        print("try to stop syncthing")
        self.process.kill()
        # check there is no other syncthing is running!
        for proc in psutil.process_iter():
            # check whether the process name matches
            # print("procress: %s " % proc.name())
            if proc.name() == SYNCTHING:
                proc.kill()

    def run(self):
        """Run bitch run!."""
        # Stop first!
        self.syncthing_stop()

        command_to_run_syncthing = " ".join((
            "ionice --ignore --class 3" if self.ionice.isChecked() else "",
            "chrt --verbose --idle 0" if self.chrt.isChecked() else "",
            SYNCTHING, "-no-browser"))
        print(command_to_run_syncthing)
        self.process.start(command_to_run_syncthing)
        if not self.process.waitForStarted():
            self._process_failed()

    @pyqtSlot()
    def _process_failed(self):
        """Read and return errors."""
        self.statusBar().showMessage("ERROR:Fail:Syncthing blow up in pieces!")
        print("ERROR:Fail:Syncthing blow up in pieces! Wheres your God now?")
        return str(self.process.readAllStandardError()).strip().lower()

    @pyqtSlot()
    def _process_dataReady(self):
        """get process stdout/strerr when data ready"""
        # TODO: format the msg to remove extra b and \n
        msg = str(self.process.readAll())
        lines = msg.split("'")
        tmp = lines[1]
        tmp = tmp.splitlines(0)
        lines = tmp[0].split("\\n")
        for line in lines:
            if line != "":
                # print("1: %s" % line)
                self.consoletextedit.append(line)
        self.consoletextedit.ensureCursorVisible()
        # autoscroll to last line's first character
        self.consoletextedit.moveCursor(QTextCursor.End)
        self.consoletextedit.moveCursor(QTextCursor.StartOfLine)

    @pyqtSlot(QProcess.ProcessState)
    def _process_stateChanged(self, state):
        """ procress_stateChanged """
        # TODO handle procress_stateChanged
        print("procress_stateChanged: %s" % state)

    def center(self):
        """Center Window on the Current Screen,with Multi-Monitor support."""
        window_geometry = self.frameGeometry()
        mousepointer_position = QApplication.desktop().cursor().pos()
        screen = QApplication.desktop().screenNumber(mousepointer_position)
        centerpoint = QApplication.desktop().screenGeometry(screen).center()
        window_geometry.moveCenter(centerpoint)
        self.move(window_geometry.topLeft())

    def move_to_mouse_position(self):
        """Center the Window on the Current Mouse position."""
        window_geometry = self.frameGeometry()
        window_geometry.moveCenter(QApplication.desktop().cursor().pos())
        self.move(window_geometry.topLeft())

    def show_console(self):
        """Show syncthing console"""
        visible = not self.consolewidget.isVisible
        print("bVisible: %s" % visible)
        self.consolewidget.setVisible(True)
        self.consolewidget.resize(QSize(200, 100))

    def view_source(self):
        """ TODO: Call methods to load and display source code."""
        # call(('xdg-open ' if sys.platform.startswith("linux") else 'open ')
        #      + __file__, shell=True)
        pass

    def view_syncthing_source(self):
        """Call methods to load and display web page source code."""
        print("view_syncthing_source start")
        # access_manager = self.view.page().networkAccessManager()
        # reply = access_manager.get(QNetworkRequest(self.view.url()))
        # reply.finished.connect(self.slot_source_downloaded)

    def slot_source_downloaded(self):
        """Show actual page source code."""
        reply = self.sender()
        # TODO: highlight html source editor/viewer
        self.textedit = QPlainTextEdit()
        self.textedit.setAttribute(Qt.WA_DeleteOnClose)
        self.textedit.setReadOnly(True)
        self.textedit.setPlainText(QTextStream(reply).readAll())
        self.textedit.show()
        reply.deleteLater()

    @pyqtSlot()
    def start_loading(self):
        """show progressbar when downloading data"""
        self.progressbar.show()

    @pyqtSlot(bool)
    def finish_loading(self, finished):
        """Finished loading content."""
        if not finished:
            # TODO: When loading fail, what should we do?
            print("load fail")
            if self.process.state() == QProcess.NotRunning:
                self.run()
                self.view.reload()
            # if self.process.state != QProcess.Running:
            #    print("syncthing is not running: %s" % self.process.state())
            # pass
        print("finish_loading: %s" % finished)
        # TODO: WebEngineView does not have following function?
        # self.view.settings().clearMemoryCaches()
        # self.view.settings().clearIconDatabase()

        # print("finish_loading %s" % datetime.strftime(datetime.now(),
        #                                              '%Y-%m-%d %H:%M:%S'))
        # TODO: following line need 6 sec to finish!!
        # TODO: (" INFO: Loading Web UI increases >250Mb RAM!.")
        # self.view.page().mainFrame().evaluateJavaScript(BASE_JS)
        # print("finish_loading %s" % datetime.strftime(datetime.now(),
        #                                             '%Y-%m-%d %H:%M:%S'))
        self.progressbar.hide()

    @pyqtSlot(int)
    def loading(self, idx):
        """loading content"""
        #print("loading %s" % idx)
        self.progressbar.setValue(idx)

    @pyqtSlot(str)
    def set_title(self, title):
        """set title when webview's title change"""
        # print("title: %s" % title)
        if len(title.strip()) > 0:
            self.setWindowTitle(self.view.title()[:99])

    def check_for_updates(self):
        """Method to check for updates from Git repo versus this version."""
        # print("TODO: https://github.com/coolshou/syncthingui/releases/latest")

        print("__version__: %s" % __version__)
        '''
        this_version = str(open(__file__).read())
        print("this_version: %s" % this_version)
        last_version = str(request.urlopen(__source__).read().decode("utf8"))
        print("last_version: %s" % last_version)

        TODO: previous use file compare, when diff then there is new file!!
        if this_version != last_version:
            m = "Theres new Version available!<br>Download update from the web"
        else:
            m = "No new updates!<br>You have the lastest version of" + __doc__
        return QMessageBox.information(self, __doc__.title(), "<b>" + m)
'''
    def closeEvent(self, event):
        """Ask to Quit."""
        if self.tray.isVisible():
            if self.tray.supportsMessages():
                self.tray.showMessage("Info",
                                      "The program will keep running in the "
                                      "system tray. To terminate the program,"
                                      " choose <b>Quit</b> in the context "
                                      "menu of the system tray entry.")
            else:
                print(" System tray not supports balloon messages ")
            self.hide()
            event.ignore()

    def app_exit(self):
        """exit app"""
        # TODO: do we need to show UI when doing close?
        # self.show_gui()
        # TODO: show QMessageBox on all virtual desktop
        the_conditional_is_true = QMessageBox.question(
            self, __doc__.title(), 'Quit %s?' % __doc__,
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No) == QMessageBox.Yes
        if the_conditional_is_true:
            self.syncthing_stop()
            self.ani_stop = True
            QApplication.instance().quit
            quit()
Esempio n. 41
0
class DBSyncMenu(QMainWindow):
    msgSignal = pyqtSignal(str)  # timely show

    def __init__(self):
        super(DBSyncMenu, self).__init__()
        self.dbSync = DBSync()
        self.initUI()

    def initUI(self):
        menubar = self.menuBar()

        self.textEd = QTextEdit()
        self.textEd.setReadOnly(True)
        font = QFont()
        font.setPointSize(14)
        self.textEd.setFont(font)
        self.setCentralWidget(self.textEd)

        self.config_menu_init(menubar)
        self.run_menu_init(menubar)

        self.setGeometry(700, 300, 400, 300)
        self.setWindowTitle('数据库同步工具')
        self.show()

    def config_menu_init(self, baseMenu):
        configMenu = baseMenu.addMenu("配置")

        dbSetAct = QAction("配置数据库信息", self)
        dbSetAct.triggered.connect(self.set_db_info)
        configMenu.addAction(dbSetAct)

        dbShowAct = QAction("显示数据库信息", self)
        dbShowAct.triggered.connect(self.show_db_info)
        configMenu.addAction(dbShowAct)

    def run_menu_init(self, baseMenu):
        runMenu = baseMenu.addMenu("运行")

        #clear data file
        clearAct = QAction("清理数据文件", self)
        clearAct.triggered.connect(self.clear_data_file)
        runMenu.addAction(clearAct)

        runMenu.addSeparator()

        #table menu
        tableMenu = runMenu.addMenu("数据表")
        self.table_menu_init(tableMenu)

        #field menu
        fieldMenu = runMenu.addMenu("表字段")
        self.field_menu_init(fieldMenu)

        #constraints menu
        constrMenu = runMenu.addMenu("表约束")
        self.constraints_menu_init(constrMenu)

        runMenu.addSeparator()

        #sync
        syncAct = QAction("同步数据库", self)
        syncAct.triggered.connect(self.sync_database)
        runMenu.addAction(syncAct)

    def table_menu_init(self, baseMenu):
        createTableAct = QAction("创建表", self)
        createTableAct.triggered.connect(self.create_table)
        baseMenu.addAction(createTableAct)

        dropTableAct = QAction("销毁表", self)
        dropTableAct.triggered.connect(self.drop_table)
        baseMenu.addAction(dropTableAct)

    def field_menu_init(self, baseMenu):
        # add table field
        addFieldAct = QAction("添加字段", self)
        addFieldAct.triggered.connect(self.add_field)
        baseMenu.addAction(addFieldAct)

        # modify table field
        # modifyFieldMenu = baseMenu.addMenu("修改字段")
        # self.modify_field_menu_init(modifyFieldMenu)

        # delete table field
        delFieldAct = QAction("删除字段", self)
        delFieldAct.triggered.connect(self.delete_field)
        baseMenu.addAction(delFieldAct)

    def modify_field_menu_init(self, baseMenu):
        modifyNameAct = QAction("修改字段名称", self)
        modifyNameAct.triggered.connect(self.modify_field)
        baseMenu.addAction(modifyNameAct)

        modifyTypeAct = QAction("修改字段属性", self)
        modifyTypeAct.triggered.connect(self.modify_field)
        baseMenu.addAction(modifyTypeAct)

    def constraints_menu_init(self, baseMenu):
        addRowAct = QAction("添加行级约束", self)
        addRowAct.triggered.connect(self.add_row_constraints)
        baseMenu.addAction(addRowAct)

        addTableAct = QAction("添加表级约束", self)
        addTableAct.triggered.connect(self.add_table_constraints)
        baseMenu.addAction(addTableAct)

        baseMenu.addSeparator()

        delRowAct = QAction("删除行级约束", self)
        delRowAct.triggered.connect(self.del_row_constraints)
        baseMenu.addAction(delRowAct)

        delTableAct = QAction("删除表级约束", self)
        delTableAct.triggered.connect(self.del_table_constraints)
        baseMenu.addAction(delTableAct)

    def set_db_info(self):
        self.ui = SetDBWindow(self.dbSync)
        self.ui.show()

    def show_db_info(self):
        text = '''HOST: %s\nPORT: %s\nUSER: %s\nPASSWD: %s\n''' % (
            self.dbSync.host, str(
                self.dbSync.port), self.dbSync.user, self.dbSync.passwd)
        self.msgSignal.emit("clear")
        self.msgSignal.emit(text)

    def display_msg(self, msg):
        if msg == "clear":
            self.textEd.clear()
        else:
            if msg.find("[ERROR]") != -1: self.textEd.setTextColor(Qt.red)
            self.textEd.append(msg)
            self.textEd.setTextColor(Qt.black)

    def clear_data_file(self):
        reply = QMessageBox.question(self, "clear hint", "确定清空数据文件?",
                                     QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes: self.dbSync.clear_data_file()

    def create_table(self):
        self.ui = CreateTableWindow(self.dbSync)
        self.ui.show()

    def drop_table(self):
        self.ui = DropTableWindow(self.dbSync)
        self.ui.show()

    def add_field(self):
        self.ui = AddFieldWindow(self.dbSync)
        self.ui.show()

    def modify_field(self):
        pass

    def delete_field(self):
        self.ui = DelFieldWindow(self.dbSync)
        self.ui.show()

    def add_row_constraints(self):
        self.ui = AddRowConstrWindow(self.dbSync)
        self.ui.show()

    def add_table_constraints(self):
        self.ui = AddTableConstrWindow(self.dbSync)
        self.ui.show()

    def del_row_constraints(self):
        self.ui = DelRowConstrWindow(self.dbSync)
        self.ui.show()

    def del_table_constraints(self):
        self.ui = DelTableConstrWindow(self.dbSync)
        self.ui.show()

    def sync_database(self):
        reply = QMessageBox.question(self, "sync hint",
                                     "同步前请确保配置了数据库信息和检查数据文件, 是否继续执行?",
                                     QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            try:
                self.dbSync.sync_database(self.msgSignal)
            except Exception as e:
                QMessageBox.warning(None, "warning", str(e))

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.ui.close()
            self.close()
class AddTables(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(300, 300, 500, 280)
        self.setWindowTitle('单层评价表合并统计程序')

        self.label1 = QLabel(self)
        self.label1.setGeometry(250, 5, 60, 20)
        self.label1.setText("拼接深度")
        self.lineEdit1 = QLineEdit(self)
        self.lineEdit1.setGeometry(250, 30, 60, 20)

        self.label2 = QLabel(self)
        self.label2.setGeometry(330, 5, 60, 20)
        self.label2.setText("开始深度")
        self.lineEdit2 = QLineEdit(self)
        self.lineEdit2.setGeometry(330, 30, 60, 20)

        self.label3 = QLabel(self)
        self.label3.setGeometry(410, 5, 60, 20)
        self.label3.setText("结束深度")
        self.lineEdit3 = QLineEdit(self)
        self.lineEdit3.setGeometry(410, 30, 60, 20)

        self.tx1 = QTextEdit(self)
        self.tx1.setGeometry(20, 85, 450, 60)

        self.tx2 = QTextEdit(self)
        self.tx2.setGeometry(20, 175, 450, 60)

        self.bt1 = QPushButton('选择上段表格', self)
        self.bt1.move(360, 60)
        self.bt3 = QPushButton('选择下段表格', self)
        self.bt3.move(360, 150)
        self.bt2 = QPushButton('填写完毕->运行', self)
        self.bt2.setGeometry(0, 0, 160, 60)
        self.bt2.move(20, 10)

        self.rbtn1 = QRadioButton('一界面', self)
        self.rbtn1.move(210, 65)
        self.rbtn1.toggled.connect(lambda: self.btnstate(self.rbtn1))
        self.rbtn2 = QRadioButton('二界面', self)
        self.rbtn2.move(270, 65)
        self.rbtn2.toggled.connect(lambda: self.btnstate(self.rbtn2))

        self.bt1.clicked.connect(self.openfiles1)
        self.bt3.clicked.connect(self.openfiles2)

        self.show()

    def btnstate(self, btn):
        # 输出按钮1与按钮2的状态,选中还是没选中
        if btn.text() == '一界面':
            if btn.isChecked() == True:
                print(btn.text() + "is selected")
                self.bt2.clicked.connect(self.run1)
            else:
                pass

        if btn.text() == "二界面":
            if btn.isChecked() == True:
                print(btn.text() + "is selected")
                self.bt2.clicked.connect(self.run2)
            else:
                pass

    def openfiles1(self):
        fnames = QFileDialog.getOpenFileNames(self, '打开第一个文件',
                                              './')  # 注意这里返回值是元组
        if fnames[0]:
            for fname in fnames[0]:
                self.tx1.append(fname)

    def openfiles2(self):
        fnames = QFileDialog.getOpenFileNames(self, '打开第二个文件',
                                              './')  # 注意这里返回值是元组
        if fnames[0]:
            for fname in fnames[0]:
                self.tx2.append(fname)

    def run1(self):
        splicing_Depth = float(self.lineEdit1.text())

        fileDir1 = self.tx1.toPlainText()
        fileDir1 = fileDir1.replace('file:///', '')
        fileDir2 = self.tx2.toPlainText()
        fileDir2 = fileDir2.replace('file:///', '')

        df1 = pd.read_excel(fileDir1, header=2, index='序号')
        df1.drop([0], inplace=True)
        df1.loc[:, '井 段\n (m)'] = df1['井 段\n (m)'].str.replace(' ',
                                                               '')  # 消除数据中空格
        # if len(df1) % 2 == 0:#如果len(df1)为偶数需要删除最后一行NaN,一行的情况不用删
        #     df1.drop([len(df1)], inplace=True)
        df1['井段Start'] = df1['井 段\n (m)'].map(lambda x: x.split("-")[0])
        df1['井段End'] = df1['井 段\n (m)'].map(lambda x: x.split("-")[1])
        # 表格数据清洗
        df1.loc[:, "井段Start"] = df1["井段Start"].str.replace(" ",
                                                           "").astype('float')
        df1.loc[:, "井段End"] = df1["井段End"].str.replace(" ", "").astype('float')

        # 截取拼接点以上的数据体
        df_temp1 = df1.loc[(
            df1['井段Start'] <= splicing_Depth), :].copy()  # 加上copy()可防止直接修改df报错
        # print(df_temp1)

        #####################################################
        df2 = pd.read_excel(fileDir2, header=2, index='序号')
        df2.drop([0], inplace=True)
        df2.loc[:, '井 段\n (m)'] = df2['井 段\n (m)'].str.replace(' ',
                                                               '')  # 消除数据中空格
        # if len(df2) % 2 == 0:#如果len(df2)为偶数需要删除最后一行NaN,一行的情况不用删
        #     df2.drop([len(df2)], inplace=True)
        df2['井段Start'] = df2['井 段\n (m)'].map(lambda x: x.split("-")[0])
        df2['井段End'] = df2['井 段\n (m)'].map(lambda x: x.split("-")[1])
        # 表格数据清洗
        df2.loc[:, "井段Start"] = df2["井段Start"].str.replace(" ",
                                                           "").astype('float')
        df2.loc[:, "井段End"] = df2["井段End"].str.replace(" ", "").astype('float')

        # 截取拼接点以下的数据体
        df_temp2 = df2.loc[(
            df2['井段End'] >= splicing_Depth), :].copy()  # 加上copy()可防止直接修改df报错
        df_temp2.reset_index(drop=True, inplace=True)  # 重新设置列索引

        # print(df_temp2)

        df_all = df_temp1.append(df_temp2)
        df_all.reset_index(drop=True, inplace=True)  # 重新设置列索引
        # 对df_all进行操作
        df_all.loc[len(df_temp1) - 1, '井 段\n (m)'] = ''.join([str(df_all.loc[len(df_temp1) - 1, '井段Start']), '-', \
                                                              str(df_all.loc[len(df_temp1), '井段End'])])
        df_all.loc[len(df_temp1) - 1, '厚 度\n (m)'] = df_all.loc[len(df_temp1), '井段End'] - \
                                                     df_all.loc[len(df_temp1) - 1, '井段Start']
        df_all.loc[len(df_temp1) - 1, '最大声幅\n (%)'] = max(df_all.loc[len(df_temp1), '最大声幅\n (%)'], \
                                                          df_all.loc[len(df_temp1) - 1, '最大声幅\n (%)'])
        df_all.loc[len(df_temp1) - 1, '最小声幅\n  (%)'] = min(df_all.loc[len(df_temp1), '最小声幅\n  (%)'], \
                                                           df_all.loc[len(df_temp1) - 1, '最小声幅\n  (%)'])
        df_all.loc[len(df_temp1) - 1, '平均声幅\n  (%)'] = np.add(df_all.loc[len(df_temp1), '平均声幅\n  (%)'], \
                                                              df_all.loc[len(df_temp1) - 1, '平均声幅\n  (%)']) / 2
        df_all.loc[len(df_temp1) - 1,
                   '井段End'] = df_all.loc[len(df_temp1),
                                         '井段End']  # 解决后续重计算厚度计算bug
        df_all.drop(len(df_temp1), inplace=True)
        df_all.set_index(["解释\n序号"], inplace=True)
        df_all.reset_index(drop=True, inplace=True)  # 重新设置列索引
        # print(df_all.columns)

        #################################################################
        # 在指定深度段统计

        # calculation_Start = float(input('请输入开始统计深度'))
        # calculation_End = float(input('请输入结束统计深度'))
        calculation_Start = float(self.lineEdit2.text())
        calculation_End = float(self.lineEdit3.text())

        start_Evaluation = df_all.loc[0, '井 段\n (m)'].split('-')[0]
        end_Evaluation = df_all.loc[len(df_all) - 1, '井 段\n (m)'].split('-')[1]
        if (calculation_End <= float(end_Evaluation)) & (
                calculation_Start >= float(start_Evaluation)):
            df_temp = df_all.loc[(df_all['井段Start'] >= calculation_Start) &
                                 (df_all['井段Start'] <= calculation_End), :]
            # 获取起始深度到第一层井段底界的结论
            df_temp_start_to_first_layer = df_all.loc[(
                df_all['井段Start'] <= calculation_Start), :]
            start_to_upper_result = df_temp_start_to_first_layer.loc[
                len(df_temp_start_to_first_layer) - 1, '结论']
            # 获取calculation_Start所在段的声幅值
            df_temp_calculation_Start = df_all.loc[
                (df_all['井段Start'] <= calculation_Start) &
                (df_all['井段End'] >= calculation_Start), :]
            df_temp_calculation_Start.reset_index(
                drop=True, inplace=True)  # 重新设置列索引#防止若截取中段,index不从0开始的bug
            # 补充储层界到井段的深度
            x, y = df_temp.shape
            df_temp = df_temp.reset_index()
            df_temp.drop(['index'], axis=1, inplace=True)
            if x != 0:  # 防止df_temp为空时,loc报错的bug
                first_layer_start = df_temp.loc[0, '井段Start']
            if x > 1 and first_layer_start != calculation_Start:
                upper = pd.DataFrame(
                    {
                        '井 段\n (m)':
                        ''.join([
                            str(calculation_Start), '-',
                            str(first_layer_start)
                        ]),
                        '厚 度\n (m)':
                        first_layer_start - calculation_Start,
                        '最大声幅\n (%)':
                        df_temp_calculation_Start.loc[0, '最大声幅\n (%)'],
                        '最小声幅\n  (%)':
                        df_temp_calculation_Start.loc[0, '最小声幅\n  (%)'],
                        '平均声幅\n  (%)':
                        df_temp_calculation_Start.loc[0, '平均声幅\n  (%)'],
                        '结论':
                        start_to_upper_result,
                        '井段Start':
                        calculation_Start,
                        '井段End':
                        first_layer_start
                    },
                    index=[1])  # 自定义索引为:1 ,这里也可以不设置index
                df_temp.loc[len(df_temp) - 1, '井段End'] = calculation_End
                df_temp = pd.concat([upper, df_temp], ignore_index=True)
                # df_temp = df_temp.append(new, ignore_index=True)  # ignore_index=True,表示不按原来的索引,从0开始自动递增
                df_temp.loc[:, "重计算厚度"] = df_temp.apply(get_thickness, axis=1)
                # 修改df_temp的最末一行
                df_temp.loc[len(df_temp) - 1, '井 段\n (m)'] = ''.join([str(df_temp.loc[len(df_temp) - 1, '井段Start']), \
                                                                      '-', str(df_temp.loc[len(df_temp) - 1, '井段End'])])
                df_temp.loc[len(df_temp) - 1,
                            '厚 度\n (m)'] = df_temp.loc[len(df_temp) - 1,
                                                       '重计算厚度']
            elif x > 1 and first_layer_start == calculation_Start:
                df_temp.loc[len(df_temp) - 1, '井段End'] = calculation_End
                df_temp.loc[:, "重计算厚度"] = df_temp.apply(get_thickness, axis=1)
                # 修改df_temp的最末一行
                df_temp.loc[len(df_temp) - 1, '井 段\n (m)'] = ''.join([str(df_temp.loc[len(df_temp) - 1, '井段Start']), \
                                                                      '-', str(df_temp.loc[len(df_temp) - 1, '井段End'])])
                df_temp.loc[len(df_temp) - 1,
                            '厚 度\n (m)'] = df_temp.loc[len(df_temp) - 1,
                                                       '重计算厚度']
            else:  # 储层包含在一个井段内的情况
                df_temp = pd.DataFrame(
                    {
                        '井 段\n (m)':
                        ''.join([
                            str(calculation_Start), '-',
                            str(calculation_End)
                        ]),
                        '厚 度\n (m)':
                        calculation_End - calculation_Start,
                        '最大声幅\n (%)':
                        df_temp_calculation_Start.loc[0, '最大声幅\n (%)'],
                        '最小声幅\n  (%)':
                        df_temp_calculation_Start.loc[0, '最小声幅\n  (%)'],
                        '平均声幅\n  (%)':
                        df_temp_calculation_Start.loc[0, '平均声幅\n  (%)'],
                        '结论':
                        start_to_upper_result,
                        '井段Start':
                        calculation_Start,
                        '井段End':
                        calculation_End
                    },
                    index=[1])  # 自定义索引为:1 ,这里也可以不设置index
                df_temp.loc[:, "重计算厚度"] = df_temp.apply(get_thickness, axis=1)
                # 修改df_temp的最末一行
                df_temp.loc[len(df_temp), '井 段\n (m)'] = ''.join([
                    str(df_temp.loc[len(df_temp), '井段Start']), '-',
                    str(df_temp.loc[len(df_temp), '井段End'])
                ])
                df_temp.loc[len(df_temp),
                            '厚 度\n (m)'] = df_temp.loc[len(df_temp), '重计算厚度']
            print(df_temp)
            ratio_Series = df_temp.groupby(
                by=['结论'])['重计算厚度'].sum() / df_temp['重计算厚度'].sum() * 100
            if ratio_Series.__len__() == 2:
                if '好' not in ratio_Series:
                    ratio_Series = ratio_Series.append(pd.Series({'好': 0}))
                elif '中' not in ratio_Series:
                    ratio_Series = ratio_Series.append(pd.Series({'中': 0}))
                elif '差' not in ratio_Series:
                    ratio_Series = ratio_Series.append(pd.Series({'差': 0}))
            elif ratio_Series.__len__() == 1:
                if ('好' not in ratio_Series) & ('中' not in ratio_Series):
                    ratio_Series = ratio_Series.append(pd.Series({'好': 0}))
                    ratio_Series = ratio_Series.append(pd.Series({'中': 0}))
                elif ('好' not in ratio_Series) & ('差' not in ratio_Series):
                    ratio_Series = ratio_Series.append(pd.Series({'好': 0}))
                    ratio_Series = ratio_Series.append(pd.Series({'差': 0}))
                elif ('中' not in ratio_Series) & ('差' not in ratio_Series):
                    ratio_Series = ratio_Series.append(pd.Series({'中': 0}))
                    ratio_Series = ratio_Series.append(pd.Series({'差': 0}))
        # print(ratio_Series)

        # 统计结论
        actual_Hao = str(
            round((calculation_End - calculation_Start) *
                  (ratio_Series['好'] / 100), 2))
        Hao_Ratio = str(round(ratio_Series['好'], 2))

        actual_Zhong = str(
            round((calculation_End - calculation_Start) *
                  (ratio_Series['中'] / 100), 2))
        Zhong_Ratio = str(round(ratio_Series['中'], 2))

        actual_Cha = str(
            round(
                calculation_End - calculation_Start - float(actual_Hao) -
                float(actual_Zhong), 2))
        Cha_Ratio = str(round(ratio_Series['差'], 2))

        PATH = '.\\resources\\'
        wb = openpyxl.load_workbook(PATH + '1统模板.xlsx')
        sheet = wb[wb.sheetnames[0]]
        sheet['A1'] = ''.join([
            '第一界面水泥胶结统计表(',
            str(calculation_Start), '-',
            str(calculation_End), 'm)'
        ])
        sheet['C4'] = actual_Hao
        sheet['D4'] = Hao_Ratio
        sheet['C5'] = actual_Zhong
        sheet['D5'] = Zhong_Ratio
        sheet['C6'] = actual_Cha
        sheet['D6'] = Cha_Ratio

        mkdir('.\\#DataOut')
        wb.save('.\\#DataOut\\统计表(' + str(calculation_Start) + '-' +
                str(calculation_End) + 'm).xlsx')

        # 保存指定起始截止深度的单层统计表
        df_temp.drop(['井段Start', '井段End', '重计算厚度'], axis=1, inplace=True)
        df_temp.reset_index(drop=True, inplace=True)  # 重新设置列索引
        df_temp.index = df_temp.index + 1
        writer = pd.ExcelWriter('.\\#DataOut\\单层评价表(' +
                                str(calculation_Start) + '-' +
                                str(calculation_End) + 'm).xlsx')
        df_temp.to_excel(writer, 'Sheet1')
        writer.save()

        # 单层统计表保存为Excel
        df_all.drop(['井段Start', '井段End'], axis=1, inplace=True)
        df_all.index = df_all.index + 1
        writer = pd.ExcelWriter('.\\#DataOut\\单层评价表(合并)(' +
                                str(start_Evaluation) + '-' +
                                str(end_Evaluation) + 'm).xlsx')
        df_all.to_excel(writer, 'Sheet1')
        writer.save()

        QMessageBox.information(self, "提示", "运行完毕,请查看#DataOut文件夹")

    def run2(self):
        splicing_Depth = float(self.lineEdit1.text())

        fileDir1 = self.tx1.toPlainText()
        fileDir1 = fileDir1.replace('file:///', '')
        fileDir2 = self.tx2.toPlainText()
        fileDir2 = fileDir2.replace('file:///', '')

        df1 = pd.read_excel(fileDir1, header=2, index='序号')
        df1.drop([0], inplace=True)
        df1.loc[:, '井 段\n (m)'] = df1['井 段\n (m)'].str.replace(' ',
                                                               '')  # 消除数据中空格
        # if len(df1) % 2 == 0:#如果len(df1)为偶数需要删除最后一行NaN,一行的情况不用删
        #     df1.drop([len(df1)], inplace=True)
        df1['井段Start'] = df1['井 段\n (m)'].map(lambda x: x.split("-")[0])
        df1['井段End'] = df1['井 段\n (m)'].map(lambda x: x.split("-")[1])
        # 表格数据清洗
        df1.loc[:, "井段Start"] = df1["井段Start"].str.replace(" ",
                                                           "").astype('float')
        df1.loc[:, "井段End"] = df1["井段End"].str.replace(" ", "").astype('float')

        # 截取拼接点以上的数据体
        df_temp1 = df1.loc[(
            df1['井段Start'] <= splicing_Depth), :].copy()  # 加上copy()可防止直接修改df报错
        # print(df_temp1)

        #####################################################
        df2 = pd.read_excel(fileDir2, header=2, index='序号')
        df2.drop([0], inplace=True)
        df2.loc[:, '井 段\n (m)'] = df2['井 段\n (m)'].str.replace(' ',
                                                               '')  # 消除数据中空格
        # if len(df2) % 2 == 0:#如果len(df2)为偶数需要删除最后一行NaN,一行的情况不用删
        #     df2.drop([len(df2)], inplace=True)
        df2['井段Start'] = df2['井 段\n (m)'].map(lambda x: x.split("-")[0])
        df2['井段End'] = df2['井 段\n (m)'].map(lambda x: x.split("-")[1])
        # 表格数据清洗
        df2.loc[:, "井段Start"] = df2["井段Start"].str.replace(" ",
                                                           "").astype('float')
        df2.loc[:, "井段End"] = df2["井段End"].str.replace(" ", "").astype('float')

        # 截取拼接点以下的数据体
        df_temp2 = df2.loc[(
            df2['井段End'] >= splicing_Depth), :].copy()  # 加上copy()可防止直接修改df报错
        df_temp2.reset_index(drop=True, inplace=True)  # 重新设置列索引

        # print(df_temp2)

        df_all = df_temp1.append(df_temp2)
        df_all.reset_index(drop=True, inplace=True)  # 重新设置列索引
        # 对df_all进行操作
        df_all.loc[len(df_temp1) - 1, '井 段\n (m)'] = ''.join([str(df_all.loc[len(df_temp1) - 1, '井段Start']), '-', \
                                                              str(df_all.loc[len(df_temp1), '井段End'])])
        df_all.loc[len(df_temp1) - 1, '厚 度\n (m)'] = df_all.loc[len(df_temp1), '井段End'] - \
                                                     df_all.loc[len(df_temp1) - 1, '井段Start']
        df_all.loc[len(df_temp1) - 1, '最大指数'] = max(df_all.loc[len(df_temp1), '最大指数'], \
                                                    df_all.loc[len(df_temp1) - 1, '最大指数'])
        df_all.loc[len(df_temp1) - 1, '最小指数'] = min(df_all.loc[len(df_temp1), '最小指数'], \
                                                    df_all.loc[len(df_temp1) - 1, '最小指数'])
        df_all.loc[len(df_temp1) - 1, '平均指数'] = np.add(df_all.loc[len(df_temp1), '平均指数'], \
                                                       df_all.loc[len(df_temp1) - 1, '平均指数']) / 2

        df_all.drop(len(df_temp1), inplace=True)
        df_all.set_index(["解释\n序号"], inplace=True)
        df_all.reset_index(drop=True, inplace=True)  # 重新设置列索引
        # print(df_all.columns)

        #################################################################
        # 在指定深度段统计

        # calculation_Start = float(input('请输入开始统计深度'))
        # calculation_End = float(input('请输入结束统计深度'))
        calculation_Start = float(self.lineEdit2.text())
        calculation_End = float(self.lineEdit3.text())

        start_Evaluation = df_all.loc[0, '井 段\n (m)'].split('-')[0]
        end_Evaluation = df_all.loc[len(df_all) - 1, '井 段\n (m)'].split('-')[1]
        if (calculation_End <= float(end_Evaluation)) & (
                calculation_Start >= float(start_Evaluation)):
            df_temp = df_all.loc[(df_all['井段Start'] >= calculation_Start) &
                                 (df_all['井段Start'] <= calculation_End), :]
            # 获取起始深度到第一层井段底界的结论
            df_temp_start_to_first_layer = df_all.loc[(
                df_all['井段Start'] <= calculation_Start), :]
            start_to_upper_result = df_temp_start_to_first_layer.loc[
                len(df_temp_start_to_first_layer) - 1, '结论']
            # 获取calculation_Start所在段的声幅值
            df_temp_calculation_Start = df_all.loc[
                (df_all['井段Start'] <= calculation_Start) &
                (df_all['井段End'] >= calculation_Start), :]
            df_temp_calculation_Start.reset_index(
                drop=True, inplace=True)  # 重新设置列索引#防止若截取中段,index不从0开始的bug
            # 补充储层界到井段的深度
            x, y = df_temp.shape
            df_temp = df_temp.reset_index()
            df_temp.drop(['index'], axis=1, inplace=True)
            if x != 0:  # 防止df_temp为空时,loc报错的bug
                first_layer_start = df_temp.loc[0, '井段Start']
            if x > 1 and first_layer_start != calculation_Start:
                upper = pd.DataFrame(
                    {
                        '井 段\n (m)':
                        ''.join([
                            str(calculation_Start), '-',
                            str(first_layer_start)
                        ]),
                        '厚 度\n (m)':
                        first_layer_start - calculation_Start,
                        '最大指数':
                        df_temp_calculation_Start.loc[0, '最大指数'],
                        '最小指数':
                        df_temp_calculation_Start.loc[0, '最小指数'],
                        '平均指数':
                        df_temp_calculation_Start.loc[0, '平均指数'],
                        '结论':
                        start_to_upper_result,
                        '井段Start':
                        calculation_Start,
                        '井段End':
                        first_layer_start
                    },
                    index=[1])  # 自定义索引为:1 ,这里也可以不设置index
                df_temp.loc[len(df_temp) - 1, '井段End'] = calculation_End
                df_temp = pd.concat([upper, df_temp], ignore_index=True)
                # df_temp = df_temp.append(new, ignore_index=True)  # ignore_index=True,表示不按原来的索引,从0开始自动递增
                df_temp.loc[:, "重计算厚度"] = df_temp.apply(get_thickness, axis=1)
                # 修改df_temp的最末一行
                df_temp.loc[len(df_temp) - 1, '井 段\n (m)'] = ''.join([str(df_temp.loc[len(df_temp) - 1, '井段Start']), \
                                                                      '-',
                                                                      str(df_temp.loc[len(df_temp) - 1, '井段End'])])
                df_temp.loc[len(df_temp) - 1,
                            '厚 度\n (m)'] = df_temp.loc[len(df_temp) - 1,
                                                       '重计算厚度']
            elif x > 1 and first_layer_start == calculation_Start:
                df_temp.loc[len(df_temp) - 1, '井段End'] = calculation_End
                df_temp.loc[:, "重计算厚度"] = df_temp.apply(get_thickness, axis=1)
                # 修改df_temp的最末一行
                df_temp.loc[len(df_temp) - 1, '井 段\n (m)'] = ''.join([str(df_temp.loc[len(df_temp) - 1, '井段Start']), \
                                                                      '-',
                                                                      str(df_temp.loc[len(df_temp) - 1, '井段End'])])
                df_temp.loc[len(df_temp) - 1,
                            '厚 度\n (m)'] = df_temp.loc[len(df_temp) - 1,
                                                       '重计算厚度']
            else:  # 储层包含在一个井段内的情况
                df_temp = pd.DataFrame(
                    {
                        '井 段\n (m)':
                        ''.join([
                            str(calculation_Start), '-',
                            str(calculation_End)
                        ]),
                        '厚 度\n (m)':
                        calculation_End - calculation_Start,
                        '最大指数':
                        df_temp_calculation_Start.loc[0, '最大指数'],
                        '最小指数':
                        df_temp_calculation_Start.loc[0, '最小指数'],
                        '平均指数':
                        df_temp_calculation_Start.loc[0, '平均指数'],
                        '结论':
                        start_to_upper_result,
                        '井段Start':
                        calculation_Start,
                        '井段End':
                        calculation_End
                    },
                    index=[1])  # 自定义索引为:1 ,这里也可以不设置index
                df_temp.loc[:, "重计算厚度"] = df_temp.apply(get_thickness, axis=1)
                # 修改df_temp的最末一行
                df_temp.loc[len(df_temp), '井 段\n (m)'] = ''.join([
                    str(df_temp.loc[len(df_temp), '井段Start']), '-',
                    str(df_temp.loc[len(df_temp), '井段End'])
                ])
                df_temp.loc[len(df_temp),
                            '厚 度\n (m)'] = df_temp.loc[len(df_temp), '重计算厚度']
            print(df_temp)
            ratio_Series = df_temp.groupby(
                by=['结论'])['重计算厚度'].sum() / df_temp['重计算厚度'].sum() * 100
            if ratio_Series.__len__() == 2:
                if '好' not in ratio_Series:
                    ratio_Series = ratio_Series.append(pd.Series({'好': 0}))
                elif '中' not in ratio_Series:
                    ratio_Series = ratio_Series.append(pd.Series({'中': 0}))
                elif '差' not in ratio_Series:
                    ratio_Series = ratio_Series.append(pd.Series({'差': 0}))
            elif ratio_Series.__len__() == 1:
                if ('好' not in ratio_Series) & ('中' not in ratio_Series):
                    ratio_Series = ratio_Series.append(pd.Series({'好': 0}))
                    ratio_Series = ratio_Series.append(pd.Series({'中': 0}))
                elif ('好' not in ratio_Series) & ('差' not in ratio_Series):
                    ratio_Series = ratio_Series.append(pd.Series({'好': 0}))
                    ratio_Series = ratio_Series.append(pd.Series({'差': 0}))
                elif ('中' not in ratio_Series) & ('差' not in ratio_Series):
                    ratio_Series = ratio_Series.append(pd.Series({'中': 0}))
                    ratio_Series = ratio_Series.append(pd.Series({'差': 0}))

        # 统计结论
        actual_Hao = str(
            round((calculation_End - calculation_Start) *
                  (ratio_Series['好'] / 100), 2))
        Hao_Ratio = str(round(ratio_Series['好'], 2))

        actual_Zhong = str(
            round((calculation_End - calculation_Start) *
                  (ratio_Series['中'] / 100), 2))
        Zhong_Ratio = str(round(ratio_Series['中'], 2))

        actual_Cha = str(
            round(
                calculation_End - calculation_Start - float(actual_Hao) -
                float(actual_Zhong), 2))
        Cha_Ratio = str(round(ratio_Series['差'], 2))

        PATH = '.\\resources\\'
        wb = openpyxl.load_workbook(PATH + '2统模板.xlsx')
        sheet = wb[wb.sheetnames[0]]
        sheet['A1'] = ''.join([
            '第二界面水泥胶结统计表(',
            str(calculation_Start), '-',
            str(calculation_End), 'm)'
        ])
        sheet['C4'] = actual_Hao
        sheet['D4'] = Hao_Ratio
        sheet['C5'] = actual_Zhong
        sheet['D5'] = Zhong_Ratio
        sheet['C6'] = actual_Cha
        sheet['D6'] = Cha_Ratio

        mkdir('.\\#DataOut')
        wb.save('.\\#DataOut\\统计表(' + str(calculation_Start) + '-' +
                str(calculation_End) + 'm).xlsx')

        # 保存指定起始截止深度的单层统计表
        df_temp.drop(['井段Start', '井段End', '重计算厚度'], axis=1, inplace=True)
        df_temp.reset_index(drop=True, inplace=True)  # 重新设置列索引
        df_temp.index = df_temp.index + 1
        writer = pd.ExcelWriter('.\\#DataOut\\单层评价表(' +
                                str(calculation_Start) + '-' +
                                str(calculation_End) + 'm).xlsx')
        df_temp.to_excel(writer, 'Sheet1')
        writer.save()

        # 单层统计表保存为Excel
        df_all.drop(['井段Start', '井段End'], axis=1, inplace=True)
        df_all.index = df_all.index + 1
        writer = pd.ExcelWriter('.\\#DataOut\\单层评价表(合并)(' +
                                str(start_Evaluation) + '-' +
                                str(end_Evaluation) + 'm).xlsx')
        df_all.to_excel(writer, 'Sheet1')
        writer.save()

        QMessageBox.information(self, "提示", "运行完毕,请查看#DataOut文件夹")
Esempio n. 43
0
class Example(QMainWindow):
    def __init__(self):
        super().__init__()
        self.copiedtext = ""
        self.initUI()

    def initUI(self):

        self.textEdit = QTextEdit()
        self.setCentralWidget(self.textEdit)
        self.textEdit.setText(" ")

        exitAction = QAction(QIcon('exit.png'), 'Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(self.close)

        newAction = QAction(QIcon('new.png'), 'New', self)
        newAction.setShortcut('Ctrl+N')
        newAction.setStatusTip('New Application')
        newAction.triggered.connect(self.__init__)

        openAction = QAction(QIcon('open.png'), 'Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open Application')
        openAction.triggered.connect(self.openo)

        saveAction = QAction(QIcon('save.png'), 'Save', self)
        saveAction.setShortcut('Ctrl+S')
        saveAction.setStatusTip('Save Application')
        saveAction.triggered.connect(self.save)

        undoAction = QAction(QIcon('undo.png'), 'Undo', self)
        undoAction.setShortcut('Ctrl+Z')
        undoAction.setStatusTip('Undo')
        undoAction.triggered.connect(self.textEdit.undo)

        redoAction = QAction(QIcon('redo.png'), 'Redo', self)
        redoAction.setShortcut('Ctrl+Y')
        redoAction.setStatusTip('Undo')
        redoAction.triggered.connect(self.textEdit.redo)

        copyAction = QAction(QIcon('copy.png'), 'Copy', self)
        copyAction.setShortcut('Ctrl+C')
        copyAction.setStatusTip('Copy')
        copyAction.triggered.connect(self.copy)

        pasteAction = QAction(QIcon('paste.png'), 'Paste', self)
        pasteAction.setShortcut('Ctrl+V')
        pasteAction.setStatusTip('Paste')
        pasteAction.triggered.connect(self.paste)

        cutAction = QAction(QIcon('cut.png'), 'Cut', self)
        cutAction.setShortcut('Ctrl+X')
        cutAction.setStatusTip('Cut')
        cutAction.triggered.connect(self.cut)

        aboutAction = QAction('About', self)
        aboutAction.setStatusTip('About')
        aboutAction.triggered.connect(self.about)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(newAction)
        fileMenu.addAction(openAction)
        fileMenu.addAction(saveAction)
        fileMenu.addAction(exitAction)
        fileMenu2 = menubar.addMenu('&Edit')
        fileMenu2.addAction(undoAction)
        fileMenu2.addAction(redoAction)
        fileMenu2.addAction(cutAction)
        fileMenu2.addAction(copyAction)
        fileMenu2.addAction(pasteAction)
        fileMenu3 = menubar.addMenu('&Help')
        fileMenu3.addAction(aboutAction)

        tb1 = self.addToolBar('File')
        tb1.addAction(newAction)
        tb1.addAction(openAction)
        tb1.addAction(saveAction)

        tb2 = self.addToolBar('Edit')
        tb2.addAction(undoAction)
        tb2.addAction(redoAction)
        tb2.addAction(cutAction)
        tb2.addAction(copyAction)
        tb2.addAction(pasteAction)

        tb3 = self.addToolBar('Exit')
        tb3.addAction(exitAction)

        self.setGeometry(0, 0, 600, 600)
        self.setWindowTitle('Text Editor')
        self.setWindowIcon(QIcon('text.png'))
        self.show()

    def closeEvent(self, event):

        reply = QMessageBox.question(self, 'Message',
                                     "Are you sure to quit without Saving?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply == QMessageBox.Yes:
            self.statusBar().showMessage('Quiting...')
            event.accept()

        else:
            event.ignore()
            self.save()
            event.accept()

    def openo(self):
        self.statusBar().showMessage('Open Text Files ')
        fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')
        self.statusBar().showMessage('Open File')
        if fname[0]:
            f = open(fname[0], 'r')

            with f:
                data = f.read()
                self.textEdit.setText(data)

    def save(self):
        self.statusBar().showMessage('Add extension to file name')
        fname = QFileDialog.getSaveFileName(self, 'Save File')
        data = self.textEdit.toPlainText()

        file = open(fname[0], 'w')
        file.write(data)
        file.close()

    def copy(self):
        cursor = self.textEdit.textCursor()
        textSelected = cursor.selectedText()
        self.copiedtext = textSelected

    def paste(self):
        self.textEdit.append(self.copiedtext)

    def cut(self):
        cursor = self.textEdit.textCursor()
        textSelected = cursor.selectedText()
        self.copiedtext = textSelected
        self.textEdit.cut()

    def about(self):
        url = "https://en.wikipedia.org/wiki/Text_editor"
        self.statusBar().showMessage('Loading url...')
        webbrowser.open(url)
Esempio n. 44
0
class NgMainWin(QMainWindow):
    def __init__(self):
        super().__init__()
        self.enableDebug = False
        self.tabWidget = QTabWidget()
        self.tabWidget.setTabsClosable(True)
        self.logEdit = QTextEdit()
        self.tabWidget.addTab(self.logEdit, 'log')

        self.createActions()
        self.createMenus()

        self.setCentralWidget(self.tabWidget)
        self.setWindowTitle('NG Toolset')
        self.setWindowFlags(self.windowFlags() or Qt.WindowMinMaxButtonsHint)
        self.setWindowState(self.windowState() or Qt.WindowMaximized)
        self.tabWidget.tabCloseRequested.connect(self.onTabCloseRequested)

    def onTabCloseRequested(self, index):
        if index == 0:
            return
        widget = self.tabWidget.widget(index)
        self.tabWidget.removeTab(index)

    def onAbout(self):
        QMessageBox.information(
            self, 'About',
            '<h1>NG Toolset</h1><p>NG toolset is set of useful NPO tools for 4G and 5G.</p>'
            +
            '<p>Author: <a href=mailto:[email protected]>zhengwei.gao(at)yahoo.com</a></p>'
            +
            '<p>Blog: <a href="http://blog.csdn.net/jeffyko">http://blog.csdn.net/jeffyko</a></p>'
        )

    def onEnableDebug(self, checked):
        self.enableDebug = checked

    def onChkSqlPlugin(self):
        drivers = QSqlDatabase().drivers()
        for e in drivers:
            self.logEdit.append('Found SQL driver: %s' % e)

    def onExecXmlParser(self):
        indir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                             'data')
        parser = NgXmlParser(self, indir)
        parser.start()

    def onExecNedsM8015(self):
        args = dict()
        args['dbConf'] = 'oracle_db_config.txt'
        args['sqlQuery'] = [
            'neds_lnadj.sql', 'neds_lnadjl.sql', 'neds_lncel_fdd.sql',
            'neds_lncel_tdd.sql', 'neds_lnhoif.sql', 'neds_lnrel.sql',
            'neds_irfim.sql', 'neds_m8015.sql', 'neds_m8051.sql',
            'neds_m8005.sql', 'neds_m8001.sql', 'neds_m8013.sql',
            'neds_m8006.sql', 'neds_m8007.sql'
        ]

        query = NgSqlQuery(self, args)
        query.exec_()

        if query.queryStat:
            proc = NgM8015Proc(self)
            proc.loadCsvData()
            proc.makeEciMap()
            proc.procUserCase01()
            proc.procUserCase02()
            proc.procUserCase04()
            self.logEdit.append('<font color=blue>Done!</font>')

    def onExecSshSftpClient(self):
        client = NgSshSftp(self)

    def onExecRawPmParser5g(self):
        parser = NgRawPmParser(self, '5g')

    def onExecLteResGrid(self):
        dlg = NgLteGridUi(self)
        dlg.exec_()

    def onExecNbiotResGrid(self):
        dlg = NgNbiotGridUi(self)
        dlg.exec_()

    def onExecNrResGrid(self):
        #QMessageBox.information(self, 'NR Resource Grid', '<p><font color=red><b>Oops, NR resource grid is still under development!</b></font></p>'
        #                        + '<p>Please visit: <a href="http://www.3gpp.org/ftp/Specs/2018-03/Rel-15/38_series/"> http://www.3gpp.org/ftp/Specs/2018-03/Rel-15/38_series/</a> for latest 5G NSA specifications.</p>')
        dlg = NgNrGridUi(self)
        dlg.exec_()

    def createActions(self):
        #File Menu
        self.exitAction = QAction('Exit')
        self.exitAction.triggered.connect(self.close)

        #LTE menu
        self.lteResGridAction = QAction('LTE Resource Grid')
        self.lteResGridAction.triggered.connect(self.onExecLteResGrid)
        self.nbiotResGridAction = QAction('NB-IoT Resource Grid')
        self.nbiotResGridAction.triggered.connect(self.onExecNbiotResGrid)

        #NR menu
        self.nrResGridAction = QAction('NR Resource Grid')
        self.nrResGridAction.triggered.connect(self.onExecNrResGrid)

        #Misc menu
        self.chkSqlAction = QAction('Check SQL Plugin')
        self.chkSqlAction.triggered.connect(self.onChkSqlPlugin)
        self.xmlParserAction = QAction('SCF/Vendor Parser')
        self.xmlParserAction.triggered.connect(self.onExecXmlParser)
        self.sqlQueryAction = QAction('NEDS (M8015 Analyzer)')
        self.sqlQueryAction.triggered.connect(self.onExecNedsM8015)
        self.sshSftpAction = QAction('SSH/SFTP Client')
        self.sshSftpAction.triggered.connect(self.onExecSshSftpClient)
        self.rawPmParserAction = QAction('Raw PM Parser(5G)')
        self.rawPmParserAction.triggered.connect(self.onExecRawPmParser5g)

        #Options menu
        self.enableDebugAction = QAction('Enable Debug')
        self.enableDebugAction.setCheckable(True)
        self.enableDebugAction.setChecked(False)
        self.enableDebugAction.triggered[bool].connect(self.onEnableDebug)

        #Help menu
        self.aboutAction = QAction('About')
        self.aboutAction.triggered.connect(self.onAbout)
        self.aboutQtAction = QAction('About Qt')
        self.aboutQtAction.triggered.connect(qApp.aboutQt)

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu('File')
        self.fileMenu.addAction(self.exitAction)

        self.lteMenu = self.menuBar().addMenu('LTE')
        self.lteMenu.addAction(self.lteResGridAction)
        self.lteMenu.addAction(self.nbiotResGridAction)

        self.nrMenu = self.menuBar().addMenu('NR')
        self.nrMenu.addAction(self.nrResGridAction)

        self.miscMenu = self.menuBar().addMenu('Misc')
        self.miscMenu.addAction(self.chkSqlAction)
        self.miscMenu.addAction(self.xmlParserAction)
        self.miscMenu.addAction(self.sqlQueryAction)
        self.miscMenu.addAction(self.sshSftpAction)
        self.miscMenu.addAction(self.rawPmParserAction)

        self.optionsMenu = self.menuBar().addMenu('Options')
        self.optionsMenu.addAction(self.enableDebugAction)

        self.helpMenu = self.menuBar().addMenu('Help')
        self.helpMenu.addAction(self.aboutAction)
        self.helpMenu.addAction(self.aboutQtAction)
Esempio n. 45
0
class Game(QMainWindow):
    def __init__(self,host="localhost",port=9999,nickname="wa"):
        super(Game, self).__init__()
        #常量
        self.BLACK = 'images/black.png'
        self.WHITE = 'images/white.png'
        self.ME ="me"
        self.YOU = "you"
        self.ADMIN = "admin"
        #是否正在进行游戏
        self.nickname = nickname
        self.opponent = {
            'nickname':'',
            'client_id':'',
            'role':'',
        }
        self.host = str(host)
        self.port = int(port)
        self.playing = False
        # 设置标题、图标等
        self.setWindowTitle('黑白棋')
        self.setWindowIcon(QIcon('images/icon.jpg'))
        # 创建布局
        self.createGrid()
        # 创建菜单
        self.createMenu()
        #导入样式表
        self.createStyleQss()
        # 初始化类
        self.initGame()
        # 网络连接,并且为网络连接单独建立一个线程
        self.createConnection()

    def __str__(self):
        return "<p style='text-align:center'>网络编程黑白棋作业</p>" \
            "<p style='text-align:left'>学号:13300240008</p>" \
            "<p style='text-align:left'>姓名:代杰</p>" \
            "<p style='text-align:left'>专业:保密管理</p>"

    def initGame(self):
        self.statusBar().showMessage("准备就绪")
        self.setTurnImage(self.BLACK)
        self.displayScores(2,2)
        self.edit.clear()
        self.messages.clear()
        self.move_record.setText("游戏未开始")
        self.playing = False

    def restartGame(self):
        #重新开始游戏,初始化 Game、Othello、Board、Controller
        self.initGame()
        self.othello.initOthello()
        self.board.initBoard(self.othello)

    def createStyleQss(self):
        file = open('style.css','r')
        style = file.read()
        qApp.setStyleSheet(style)
        file.close()

    def createConnection(self):
        self.connect = True
        self.client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        self.client.connect((self.host,self.port))
        self.packAndSend({
            'action':'login',
            'value': self.nickname,
            'to':'admin'
        })

    def createGrid(self):
        def btn_restart_game():
            if self.playing:
                self.packAndSend({
                    'to':self.opponent['client_id'],
                    'action':'restart',
                    'value': 'apply'
                })
            else:
                QMessageBox.information(self,'系统消息',"没有加入任何游戏")
                self.restartGame()
        def btn_leave_game():
            if self.playing:
                self.packAndSend({
                    'to':self.opponent['client_id'],
                    'action':'leave',
                    'value': ''
                })
                self.restartGame()
            else:
                QMessageBox.information(self,'系统消息',"没有加入任何游戏")
        #设置主窗口的大小与位置
        screen = QDesktopWidget().screenGeometry()
        self.setGeometry( (screen.width() - UI_WIDTH)/2 ,( screen.height() - UI_HEIGHT )/2,UI_WIDTH,UI_HEIGHT)
        self.setFixedSize(UI_WIDTH,UI_HEIGHT)
        #创建布局
        main = QWidget(self)
        main.setObjectName('main')
        self.setCentralWidget(main)
        self.othello = Othello()
        self.board = Board(main,self.othello)
        self.hall = Hall(self)

        #创建应该下子的图片标志,初始化为黑子
        pic = QLabel(self)
        pic.setGeometry(UI_WIDTH*0.212,UI_HEIGHT*0.12,50,50)
        pic.setObjectName('label_for_turn_image')

        #创建功能按钮
        buttons = QWidget(self)
        buttons.setGeometry(UI_WIDTH*0.77,UI_HEIGHT*0.4,UI_WIDTH*0.2,UI_HEIGHT*0.12)
        buttons.setObjectName('buttons')
        btn_restart = QPushButton('重新开始',self)
        btn_list = QPushButton('玩家列表',self)
        btn_leave = QPushButton('离开',self)
        btn_hall = QPushButton('大厅',self)
        grid = QGridLayout()
        grid.addWidget(btn_restart,0,0)
        grid.addWidget(btn_list,0,1)
        grid.addWidget(btn_leave,1,0)
        grid.addWidget(btn_hall,1,1)
        buttons.setLayout(grid)
        btn_restart.clicked.connect(btn_restart_game)
        btn_list.clicked.connect(lambda:self.packAndSend({'to':'admin','action':'list','value': '玩家列表'}))
        btn_hall.clicked.connect(lambda:self.packAndSend({'to':'admin','action':'games','value': '列出大厅'}))
        btn_leave.clicked.connect(btn_leave_game)
        #创建分数显示屏,包括黑棋得分,黑棋昵称,白棋得分,白棋昵称
        self.score_black = QLabel(self)
        self.score_black.setObjectName('score_black')
        self.score_black.setGeometry(UI_WIDTH*0.08,UI_HEIGHT*0.25,100,60)
        self.nickname_black = QLabel("<p style='text-align:center'>黑棋</p>",self)
        self.nickname_black.setObjectName('nickname_black')
        self.nickname_black.setGeometry(UI_WIDTH*0.03,UI_HEIGHT*0.36,120,60)

        self.score_white = QLabel(self)
        self.score_white.setObjectName('score_white')
        self.score_white.setGeometry(UI_WIDTH*0.08,UI_HEIGHT*0.57,100,60)
        self.nickname_white = QLabel("<p style='text-align:center'>白棋</p>",self)
        self.nickname_white.setObjectName('nickname_white')
        self.nickname_white.setGeometry(UI_WIDTH*0.03,UI_HEIGHT*0.68,120,60)
        self.move_record =  QTextEdit("当前下子情况",self)
        self.move_record.setReadOnly(True)
        #显示走棋的位置
        self.move_record =  QTextEdit("下子情况",self)
        self.move_record.setObjectName("move_record")
        self.move_record.setReadOnly(True)
        self.move_record.setGeometry(UI_WIDTH*0.765,UI_HEIGHT*0.24,UI_WIDTH*0.215,UI_HEIGHT*0.15)

        #创建输入框
        chat = QWidget(self)
        chat.setObjectName('chat')
        chat.setGeometry(UI_WIDTH*0.755,UI_HEIGHT*0.54,UI_WIDTH*0.235,UI_HEIGHT*0.45)
        grid = QGridLayout()
        chat.setLayout(grid)
        # 聊天窗口
        self.messages = QTextEdit("欢饮来到呆尐兔兔五子棋,撒花~~~",self)
        self.messages.setReadOnly(True)
        self.edit = QLineEdit(self)
        btn_send_msg = QPushButton("Enter/发送",self)
        btn_send_msg.clicked.connect(self.chat)
        grid.addWidget(self.messages,0,0,10,10)
        grid.addWidget(self.edit,10,0,2,8)
        grid.addWidget(btn_send_msg,10,8,2,2)

    def createMenu(self):
        def quitGame():
            #退出信号槽函数
            reply = QMessageBox.question(self,'问题','想要退出吗',QMessageBox.Yes,QMessageBox.No)
            if reply == QMessageBox.Yes:
                qApp.quit()

        def aboutUs():
            QMessageBox.about(self,'关于作者',str(self))

        menubar = self.menuBar()
        #主菜单
        main_menu = menubar.addMenu('&主菜单')
        main_menu.addAction(QAction(QIcon('images/icon.jpg'),'退出',
                                 self, statusTip="退出黑白棋游戏", triggered=quitGame))
        #关于菜单
        about_menu = menubar.addMenu('&关于')
        about_menu.addAction(QAction(QIcon('images/icon.jpg'),'作者',
                                 self, statusTip="作者信息", triggered=aboutUs))

    def setTurnImage(self,turn_image=None):
        if turn_image:
            pic_l = 30
            pic = self.findChild(QLabel,'label_for_turn_image')
            pic.setPixmap(QPixmap(turn_image).scaled(pic_l,pic_l))
        else:
            game_othello.setWhoFirst()
            QMessageBox.information(self,"提示","已选择" + ("黑棋" if game_othello.isBlack() else "白棋") + "优先")
            if game_othello.isBlack():
                self.setTurnImage(self.BLACK)
            else:
                self.setTurnImage(self.WHITE)

    def displayScores(self,black=0,white=0):
        #显示分数
        if not ( black and white):
            n = game_othello.N
            black = white = 0
            for x in range(n):
                for y in range(n):
                    if game_othello.isBlack(x,y):
                        black += 1
                    elif game_othello.isWhite(x,y):
                        white += 1
        self.score_white.setText(str('%02d' % white))
        self.score_black.setText(str('%02d' % black))
        return black,white

    def getBoard(self):
        #返回棋局
        return self.board

    def getOthello(self):
        #返回逻辑五子棋
        return self.othello

    def keyPressEvent(self,event):
        key = event.key()
        if key == Qt.Key_Enter or key == Qt.Key_Return:
            self.chat()

    def isTurnMe(self):
        return (game_othello.isBlack() and self.opponent['role'] == "white" ) \
               or (game.othello.isWhite() and self.opponent['role'] == "black")

    def chat(self, src = None, nickname=None, msg = None):
        def packMsg(src,name,msg):
            color = {
                self.ADMIN : "blue",
                self.ME: "white",
                self.YOU: "wheat"
            }
            packed = "<span style='color: %s '> %s : %s</span>" % ( color[src], name , msg )
            return packed

        if not src:
            send_msg = self.edit.text()
            if send_msg and len(send_msg):
                self.edit.clear()
                self.messages.append(packMsg(self.ME ,self.nickname,send_msg ))
                if self.playing:
                    self.packAndSend({
                        'to':self.opponent['client_id'],
                        'action' : 'message',
                        'value': send_msg
                    })
        else:
            self.messages.append(packMsg(src, nickname, msg))

    def parseMsg(self,msg_str):
        data = json.JSONDecoder().decode(msg_str)
        action = data['action']
        value = data['value']
        nickname = data['nickname']

        if data['from'] == "admin":
            if action == "message":
                self.chat(self.ADMIN , nickname , value)
            elif action == "kickout":
                QMessageBox.information(self,"系统消息","你已经被踢出棋局,原因是" + value,QMessageBox.Yes)
                self.restartGame()
            elif action == "leave":
                QMessageBox.question(self,"系统消息","对方玩家请求离开,是否同意?",QMessageBox.Yes)
            elif action == "join":
                if value == "fail":
                    QMessageBox.information(self,'系统消息',"该棋局已满,请选择其他棋局")
                elif value == "success":
                    self.hall.hide()
                    QMessageBox.information(self,'系统消息',"你已经加入棋局,等待其他玩家进入棋局")
                else:
                    self.restartGame()
                    name,client_id,role = value.split(':')
                    self.opponent['role'] = role
                    self.opponent['client_id']= client_id
                    self.opponent['nickname'] = name
                    self.playing = True
                    self.hall.hide()
                    #根据系统分配的角色,显示双方昵称,初始化棋子
                    if role == "black" :
                        self.move_record.setText("游戏开始,我方白棋后手")
                        QMessageBox.information(self,'提示','您是白棋\r\n白棋后手')
                        self.nickname_black.setText("<p style='text-align:center'>%s</p>" % name)
                        self.nickname_white.setText("<p style='text-align:center'>%s</p>" % self.nickname)
                    elif role == "white" :
                        self.move_record.setText("游戏开始,我方黑棋先手")
                        QMessageBox.information(self,'提示','您是黑棋\r\n黑棋先手')
                        self.nickname_black.setText("<p style='text-align:center'>%s</p>" % self.nickname)
                        self.nickname_white.setText("<p style='text-align:center'>%s</p>" % name)
            elif action == "games":
                self.hall.showHall(value)
            elif action == "list":
                res = ""
                print(value)
                for i in value:
                    res += i + '\r\n'
                QMessageBox.information(self,"玩家列表",res)
            elif action == "closegame":
                QMessageBox.information(self,"系统消息",value)
                self.restartGame()
            elif action == "win":
                QMessageBox.information(self,"系统消息",value)
                self.restartGame()
            elif action == "watch":
                self.packAndSend({
                    'to':'admin',
                    'action':'watch',
                    'value': self.othello.board
                })
        else:
            if action == "move":
                x ,y  = int(value[0]) , int(value[1])
                game_board.placePiece(x,y)
            elif action == "message":
                self.chat(self.YOU, nickname, value)
            elif action == "restart":
                if value == "apply":
                    reply = QMessageBox.question(self,"系统消息","对方请求重新开始游戏,是否同意",QMessageBox.Yes,QMessageBox.No)
                    if reply == QMessageBox.Yes:
                        self.packAndSend({
                            'to':self.opponent['client_id'],
                            'action':'restart',
                            'value':'agree'
                        })
                        self.restartGame()
                        self.playing = True
                    else:
                        self.packAndSend({
                            'to':self.opponent['client_id'],
                            'action':'restart',
                            'value':'refuse'
                        })
                elif value == "agree":
                    QMessageBox.information(self,"系统消息","对方同意了您的请求")
                    self.restartGame()
                    self.playing = True
                elif value == "refuse":
                    QMessageBox.information(self,"系统消息","对方拒绝了您的请求")
            elif action == "leave":
                self.restartGame()
                QMessageBox.information(self,"系统消息","对方离开了棋局")

    def packAndSend(self, msg=None):
        '''
        :param msg: 字典,需要打包的消息,例如{'msg':'你真棒','move':'77'}
        :return: pack message and sent to
        '''
        msg = {} if not msg else msg
        msg['nickname'] = self.nickname
        pack_msg = json.JSONEncoder().encode(msg)
        self.client.sendall(pack_msg.encode('utf8'))
class ApEnWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.fileName = ".memory"
        self.initUI()

    def initUI(self):
        mLabel = QLabel('m')
        self.mEdit = QLineEdit("2")

        rLabel = QLabel("r")
        number_group = QVBoxLayout()  # Number group
        #
        cb = QCheckBox('Use threshold', self)
        cb.setChecked(True)
        cb.clicked.connect(self.toogleThresholdCheckbox)
        self.rThreshold = QLineEdit("300")
        self.isThresholdUsed = True

        self.calculateR = CalculationType.CONST
        self.rConst = QRadioButton("r=0.2*SDNN")
        self.rConst.setChecked(True)
        self.rConst.clicked.connect(self.setConstR)
        number_group.addWidget(self.rConst)
        # self.rDev = QRadioButton("r=Rmax")

        devCoefGroup = QHBoxLayout()

        self.rDev = QRadioButton('r = SDNN * ', self)
        self.rDev.clicked.connect(self.setDevR)
        self.rDevCoef = QLineEdit("0.5")
        self.rDevCoef.setEnabled(False)
        devCoefGroup.addWidget(self.rDev)
        devCoefGroup.addWidget(self.rDevCoef)
        number_group.addLayout(devCoefGroup)

        self.rComplex = QRadioButton("r=Rchon")
        self.rComplex.clicked.connect(self.setComplexR)
        number_group.addWidget(self.rComplex)

        fileNamesLabel = QLabel("Files to analyze")
        self.fileNamesEdit = QTextEdit()
        fileNamesOpen = QPushButton("Open files", self)
        fileNamesOpen.clicked.connect(self.showFileChooser)

        apEnCalculate = QPushButton("Calculate ApEn", self)
        apEnCalculate.clicked.connect(self.calculateApEn)

        grid = QGridLayout()
        self.setLayout(grid)
        # self.layout().setSpacing(10)

        grid.addWidget(mLabel,0,0)
        grid.addWidget(self.mEdit,0,1)

        grid.addWidget(cb, 1, 0)
        grid.addWidget(self.rThreshold, 1, 1)

        grid.addWidget(rLabel, 2, 0)
        grid.addLayout(number_group, 2, 1)

        grid.addWidget(fileNamesLabel, 3, 0)
        grid.addWidget(self.fileNamesEdit, 3, 1)
        grid.addWidget(fileNamesOpen, 3, 2)


        grid.addWidget(apEnCalculate, 4, 1, 3, 1)

        self.move(300, 150)
        self.setWindowTitle('Calculator')
        self.show()


    def calculateApEn(self):
        results = []
        tmp = None
        r = []
        filesList = self.fileNamesEdit.toPlainText().split('\n')
        # 1. decide whether to use threshold or not
        thresholdValue = -1
        devCoefValue = -1
        if self.isThresholdUsed:
            thresholdValue = self.rThreshold.text()
        # 2. choose the way to calculate r
        if self.calculateR == CalculationType.DEV:
            devCoefValue = self.rDevCoef.text()
        # 3. make all enthropy calculations
        for i in filesList:
            try:
                m = int(self.mEdit.text())
                tmp = ApEn(m=m)
                thresholdValue = int(thresholdValue)
                devCoefValue = float(devCoefValue)
                res = tmp.prepare_calculate_apen(m=m,
                                                          series=i,
                                                          calculationType=self.calculateR,
                                                          devCoefValue=devCoefValue,
                                                          useThreshold=self.isThresholdUsed,
                                                          thresholdValue=thresholdValue)
                results.append('{0:.10f}'.format(res))
                r.append(tmp.r)
                dialog =  QMessageBox(self)
                dialog.setWindowModality(False)
                dialog.setText("ApEn calculated for " + i)
                # information(self,"ApEn","ApEn calculated for " + i);
                # dialog.setText("MESSAGE")
                dialog.show()
            except ValueError:
                results.append("Error!")
        makeReport(filesList=filesList, apEnList=results, rList=r)


    def showFileChooser(self):
        path = ""
        try:
            with open (self.fileName,"r") as f:
                path = f.readline().strip()
        except FileNotFoundError:
            pass
        fname = QFileDialog.getOpenFileNames(self,  'Open file', path, ("DAT (*.dat, *.txt)"))
        self.fileNamesEdit.setText("")
        print(fname)
        for name in fname[0]:
            self.fileNamesEdit.append(name)
        self.memorizeLastPath()

    def memorizeLastPath(self):
        if not self.fileNamesEdit:
            return
        path = os.path.dirname(self.fileNamesEdit.toPlainText().split('\n')[0])
        with open(self.fileName,"w") as f:
            f.write(path+'/')

    def toogleThresholdCheckbox(self):
        self.isThresholdUsed = not self.isThresholdUsed
        self.rThreshold.setEnabled(self.isThresholdUsed)

    def setComplexR(self):
        self.calculateR = CalculationType.COMPLEX
        self.rDevCoef.setEnabled(False)

    def setConstR(self):
        self.calculateR = CalculationType.CONST
        self.rDevCoef.setEnabled(False)

    def setDevR(self):
        self.calculateR = CalculationType.DEV
        self.rDevCoef.setEnabled(True)