Ejemplo n.º 1
1
 def fillTableWidget(self, qtable: QTableWidget, df: pd.DataFrame = None):
     # TODO: Hacerla gfeneral {self.fromTime} {self.toTime} recibiendo el widget
     # Limpiar contenidos de tabla
     headerList = tuple(df.columns.values)
     qtable.clearContents()
     qtable.setColumnCount(len(headerList))
     qtable.setHorizontalHeaderLabels(headerList)
     # self.qtable.horizontalHeader().setStretchLastSection(True)
     qtable.horizontalHeader(
     ).setSectionResizeMode(QHeaderView.Stretch)
     rowCount = 0
     for row in df.itertuples():
         # Sets the number of rows in this table's model to rows. If this is less than rowCount(),
         # the data in the unwanted rows is discarded.
         qtable.setRowCount(rowCount+1)
         for i, columnName in enumerate(headerList):
             # val = QTableWidgetItem(row._asdict()[str(columnName)])
             val = QTableWidgetItem(str(row._asdict()[columnName]))
             qtable.setItem(rowCount, i, val)
         rowCount += 1
Ejemplo n.º 2
0
class ListaUnidades(BaseSubWindow):
    def __init__(self, parent=None):
        super().__init__("Unidades cadastrados no sistema")
        self.parent = parent
        self.setTable()
        self.setLayoutTable()
        #super().setMinimumWidth(1050)
        super().setMinimumHeight(500)

    def setTable(self):
        '''Cria os Widgets da tabela'''
        self.unidades = self.parent.unidade.getUnidades(
        )  #Pega as unidades salvas no sistema
        self.table = QTableWidget(
            len(self.unidades), 3
        )  #Cria a tabela com a quantidade de linhas conforme os unidades e 11 colunas
        header_label = """Ação-Sigla-Descrição"""  #Lista usada para formar os titulos da tabela
        self.table.setHorizontalHeaderLabels(header_label.split(
            '-'))  #Interpreta a lista de titulos e seta os titulos da tabela
        self.setValuesTable()  #Coloca os valores na tabela
        self.table.resizeColumnsToContents(
        )  #As colunas ficam com a largura do tamanho do conteudo
        self.table.setEditTriggers(
            QAbstractItemView.NoEditTriggers)  #Bloqueia o edit nos itens

    def setLayoutTable(self):
        '''Posiciona os Widgets da tabela'''
        self.conteudo = QWidget()
        self.layout_group = QVBoxLayout()
        self.layout_group.addWidget(self.table)
        self.conteudo.setLayout(self.layout_group)
        self.setWidget(self.conteudo)

    def setValuesTable(self):
        '''Preenche a tabela usando dois laços de repetição(um para linhas e outro para colunas)'''
        linha = 0
        coluna = 1
        for unidade in self.unidades:  #Separa as linhas dos unidades
            self.table.setCellWidget(
                linha, 0, ButtonGroup(self, unidade[0], linha)
            )  #Coloca os botões na celula e passa o id do unidade
            for item in unidade[
                    1:]:  #Separa cada coluna da linha(da segunda coluna em diante)
                self.table.setItem(linha, coluna, QTableWidgetItem(str(item)))
                coluna += 1
            coluna = 1
            linha += 1

    def updateTable(self):
        '''Atualiza as linhas da tabela'''
        self.unidades = self.parent.unidade.getProdutos(
        )  #Pega os unidades salvos no sistema
        self.table.clearContents()
        if (len(self.unidades) > self.table.rowCount()):
            self.table.insertRow(
                int(len(self.unidades) - self.table.rowCount()))
        elif (len(self.unidades) < self.table.rowCount()):
            self.table.removeRow(
                int(self.table.rowCount() - len(self.unidades)))
        self.setValuesTable()
Ejemplo n.º 3
0
    def out(self,
            header_titles: list,
            cursor,
            table: QTableWidget = None,
            callback=None):
        if not table:
            table: QTableWidget = self._docWindow.table

        table.clearContents()
        table.setColumnCount(len(header_titles))
        table.setHorizontalHeaderLabels(header_titles)
        row = cursor.fetchone()
        table.setRowCount(0)
        table.resizeColumnsToContents()

        if not row:
            QueryMessage(399)
            return
        elif row[0] == 0 and callback is not None:
            callback()
        elif len(row) == 1:
            QueryMessage(row[0])
        else:
            row_count = 0
            while row:
                table.setRowCount(row_count + 1)
                for x in range(len(header_titles)):
                    if str(row[x]) == 'True' or str(row[x]) == 'False':
                        table.setItem(
                            row_count, x,
                            QTableWidgetItem("Да" if row[7] else "Нет"))
                    elif str(row[x]) == 'None':
                        table.setItem(row_count, x, QTableWidgetItem("-"))
                    else:
                        table.setItem(row_count, x,
                                      QTableWidgetItem(str(row[x])))
                row_count += 1
                row = cursor.fetchone()

            table.resizeColumnsToContents()

            if table == self._docWindow.table:
                self.selected_row = -1
                self.selected_column = -1
                self._docWindow.desc_table.clearContents()
                self._docWindow.desc_table.setRowCount(0)
Ejemplo n.º 4
0
class MainApp(QWidget):
    """
    Coordinate transform program for relocating samples in different coordinate systems

    Developer:  Reto Trappitsch
    Version:    2.1.1
    Date:       May 29, 2020
    """
    def __init__(self):
        # version number:
        self.version = '2.1.1'
        self.version_date = 'May 29, 2020'

        # run in debug mode?
        self.rundebug = False
        # round digits
        self.rounddig = 3
        # which calculation mode to start in (Nittler or Admon - labels of radiobuttons)
        self.calcmode = 'Nittler'
        # initialize the thing
        super().__init__()
        self.title = 'Coordinate Transformation'
        self.left = 50
        self.top = 80
        self.width = 900
        # this is used for geometry but then also for tableheight. tableheight dominates!
        self.height = 845

        # default for header, columns
        self.default_header_rows = 1
        self.default_name_column = 1
        self.default_x_column = 2
        self.default_y_column = 3

        # my clipboard
        self.clipboard = QApplication.clipboard()

        self.setup_keyboard_shortcuts()

        # initialize the UI
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # define outermost v layout
        outervlayout = QVBoxLayout()

        # some top row buttons and layout
        toprowbutthlayout = QHBoxLayout()
        # open buttons
        openfile_butt = QPushButton('Open file')
        openfile_butt.clicked.connect(self.openfile)
        openfile_butt.setToolTip(
            'Load coordinates from a file. Please make sure you specify\n'
            'how many header rows the file has and where your x, y, and\n'
            'fiducial data is.'
            'Files that can be read are: comma separated (*.csv), tab\n'
            'separated (*.txt), or excel files.')
        toprowbutthlayout.addWidget(openfile_butt)
        # save button
        toprowbutthlayout.addStretch()
        savecsv_butt = QPushButton('Save csv')
        savecsv_butt.clicked.connect(lambda: self.savefile('csv'))
        savecsv_butt.setToolTip(
            'Save the current table, as is displayed, into a csv file. This file can also be\n'
            'imported later with the \'Open csv\' button.')
        toprowbutthlayout.addWidget(savecsv_butt)
        savetxt_butt = QPushButton('Save txt')
        savetxt_butt.clicked.connect(lambda: self.savefile('txt'))
        savecsv_butt.setToolTip(
            'Save the current table, as is displayed, into a txt file. This file can also be\n'
            'imported later with the \'Open txt\' button.')
        toprowbutthlayout.addWidget(savetxt_butt)
        # add radiobuttons for method
        toprowbutthlayout.addStretch()
        mnit_radio = QRadioButton('Nittler')
        mnit_radio.setToolTip(
            'Method from Larry Nittler\' PhD thesis, App. E. Only shift and rotation are \n'
            'considered. Strech not possible. Linear regression through all reference points\n'
            'is calculated, so mechanical slack, etc., is regressed out over time.'
        )
        madm_radio = QRadioButton('Admon')
        madm_radio.setToolTip(
            'Method from Admon et al. (2015). See \'Help\' for full reference. Only three\n'
            'fiducial marks are considered for coordinate transformation, however, the stretch\n'
            'of coordinate systems is included as well.')
        if self.calcmode == 'Nittler':
            mnit_radio.setChecked(True)
        else:
            madm_radio.setChecked(True)
        # connect buttons to the subroutine
        mnit_radio.toggled.connect(lambda: self.set_calcmode(mnit_radio))
        mnit_radio.toggled.connect(lambda: self.set_calcmode(madm_radio))
        # add to layout
        toprowbutthlayout.addWidget(mnit_radio)
        toprowbutthlayout.addWidget(madm_radio)
        # add test, help, quit
        toprowbutthlayout.addStretch()
        if self.rundebug:
            test_butt = QPushButton('Test')
            test_butt.clicked.connect(self.test)
            toprowbutthlayout.addWidget(test_butt)
        help_butt = QPushButton('Help')
        help_butt.clicked.connect(self.help)
        help_butt.setToolTip('Display a brief help message.')
        toprowbutthlayout.addWidget(help_butt)
        quit_butt = QPushButton('Quit')
        quit_butt.clicked.connect(self.close)
        quit_butt.setToolTip('Close the program')
        toprowbutthlayout.addWidget(quit_butt)
        # add buttons to layout
        outervlayout.addLayout(toprowbutthlayout)
        # outervlayout.addStretch()

        # set a second row with options, QSpinBoxes mostly
        secondrow = QHBoxLayout()
        header_label = QLabel('header rows:')
        self.header_spinbox = QSpinBox(self, minimum=0, maximum=1000)
        self.header_spinbox.setAlignment(Qt.AlignRight)
        self.header_spinbox.setValue(self.default_header_rows)
        self.header_spinbox.setToolTip(
            'Select how many rows should be skipped\n'
            'at the beginning of file. These are the\n'
            'header rows.')

        namecol_label = QLabel('name col:')
        self.namecol_spinbox = QSpinBox(self, minimum=0, maximum=1000)
        self.namecol_spinbox.setAlignment(Qt.AlignRight)
        self.namecol_spinbox.setValue(self.default_name_column)
        self.namecol_spinbox.setToolTip('Which column contains the name\n'
                                        'of the location? Select 0 for None.')

        xcol_label = QLabel('x col:')
        self.xcol_spinbox = QSpinBox(self, minimum=0, maximum=1000)
        self.xcol_spinbox.setAlignment(Qt.AlignRight)
        self.xcol_spinbox.setValue(self.default_x_column)
        self.xcol_spinbox.setToolTip('Which column contains the x coordinate\n'
                                     'of the location? Select 0 for None.')

        ycol_label = QLabel('y col:')
        self.ycol_spinbox = QSpinBox(self, minimum=0, maximum=1000)
        self.ycol_spinbox.setAlignment(Qt.AlignRight)
        self.ycol_spinbox.setValue(self.default_y_column)
        self.ycol_spinbox.setToolTip('Which column contains the y coordinate\n'
                                     'of the location? Select 0 for None.')

        fid_xcol_label = QLabel('ref x col:')
        self.fid_xcol_spinbox = QSpinBox(self, minimum=0, maximum=1000)
        self.fid_xcol_spinbox.setAlignment(Qt.AlignRight)
        self.fid_xcol_spinbox.setValue(self.default_x_column + 2)
        self.fid_xcol_spinbox.setToolTip(
            'Which column contains the x reference coordinate\n'
            'of the location? Select 0 for None.')

        fid_ycol_label = QLabel('ref y col:')
        self.fid_ycol_spinbox = QSpinBox(self, minimum=0, maximum=1000)
        self.fid_ycol_spinbox.setAlignment(Qt.AlignRight)
        self.fid_ycol_spinbox.setValue(self.default_y_column + 2)
        self.fid_xcol_spinbox.setToolTip(
            'Which column contains the y reference coordinate\n'
            'of the location? Select 0 for None.')

        secondrow.addWidget(header_label)
        secondrow.addWidget(self.header_spinbox)
        secondrow.addStretch()
        secondrow.addWidget(namecol_label)
        secondrow.addWidget(self.namecol_spinbox)
        secondrow.addStretch()
        secondrow.addWidget(xcol_label)
        secondrow.addWidget(self.xcol_spinbox)
        secondrow.addStretch()
        secondrow.addWidget(ycol_label)
        secondrow.addWidget(self.ycol_spinbox)
        secondrow.addStretch()
        secondrow.addWidget(fid_xcol_label)
        secondrow.addWidget(self.fid_xcol_spinbox)
        secondrow.addStretch()
        secondrow.addWidget(fid_ycol_label)
        secondrow.addWidget(self.fid_ycol_spinbox)
        secondrow.addStretch()

        # add to outer layout
        outervlayout.addLayout(secondrow)

        # make the table
        self.datatable = QTableWidget()
        self.datatable.setRowCount(23)
        self.datatable.setColumnCount(7)
        # implement mouse button
        self.datatable.setContextMenuPolicy(Qt.CustomContextMenu)
        self.datatable.customContextMenuRequested.connect(self.context_menu)
        # set headers
        headers = [
            QTableWidgetItem('Name'),
            QTableWidgetItem('x'),
            QTableWidgetItem('y'),
            QTableWidgetItem('x_ref'),
            QTableWidgetItem('y_ref'),
            QTableWidgetItem('x_calc'),
            QTableWidgetItem('y_calc')
        ]
        for it in range(len(headers)):
            self.datatable.setHorizontalHeaderItem(it, headers[it])
        # set up clipboard for table
        self.clip = QGuiApplication.clipboard()
        # add table to widget
        outervlayout.addWidget(self.datatable)
        # bottom button row
        bottrowbutthlayout = QHBoxLayout()
        # add Row
        addrow_butt = QPushButton('+ Row')
        addrow_butt.clicked.connect(self.addrow)
        addrow_butt.setToolTip(
            'Add an empty row to the data table. You can then manually enter new values into this\n'
            'empty row.')
        bottrowbutthlayout.addWidget(addrow_butt)
        # clear table
        clear_butt = QPushButton('Clear all')
        clear_butt.clicked.connect(self.cleartable)
        clear_butt.setToolTip(
            'Clear all data in the table. A confirmation will be required, but after that, there\n'
            'is no undoing this action. Make sure you have the data, assuming you need it, saved.'
        )
        bottrowbutthlayout.addWidget(clear_butt)

        bottrowbutthlayout.addStretch()
        # information on Fit
        self.infolbl = QLabel('')
        bottrowbutthlayout.addWidget(self.infolbl)
        bottrowbutthlayout.addStretch()
        # calculate button
        calc_butt = QPushButton('Calculate')
        calc_butt.clicked.connect(self.calculate)
        calc_butt.setToolTip(
            'Calculate the regression. An \'Average distance error\' will be provided. This is a\n'
            'number that is good to compare from fit to fit. If weird, non-numeric values show up\n'
            'make sure that you have entered proper numbers.')
        bottrowbutthlayout.addWidget(calc_butt)
        # add to outer layout
        # outervlayout.addStretch()
        outervlayout.addLayout(bottrowbutthlayout)

        # set layout to app
        self.setLayout(outervlayout)

        # show the UI
        self.show()

    def setup_keyboard_shortcuts(self):
        # Keyboard shortcuts
        copy_shortcut = QShortcut(QKeySequence("Ctrl+C"), self)
        copy_shortcut.activated.connect(self.copy)
        paste_shortcut = QShortcut(QKeySequence("Ctrl+V"), self)
        paste_shortcut.activated.connect(self.paste)
        open_shortcut = QShortcut(QKeySequence("Ctrl+O"), self)
        open_shortcut.activated.connect(self.openfile)
        del_shortcut = QShortcut(QKeySequence("Del"), self)
        del_shortcut.activated.connect(self.delete)

    def context_menu(self, position):
        menu = QMenu()
        copyAction = menu.addAction("Copy")
        pasteAction = menu.addAction("Paste")
        delAction = menu.addAction("Delete")
        action = menu.exec_(self.datatable.mapToGlobal(position))
        if action == copyAction:
            self.copy()
        elif action == pasteAction:
            self.paste()
        elif action == delAction:
            self.delete()

    def set_calcmode(self, rb):
        if rb.isChecked():
            self.calcmode = rb.text()
            if self.rundebug:
                print(self.calcmode)

    def openfile(self):
        # file dialog
        options = QFileDialog.Options()
        # options |= QFileDialog.DontUseNativeDialog
        filename, _ = QFileDialog.getOpenFileName(
            self,
            'QFileDialog.getOpenFileName()',
            '',
            'Supported Files (*.csv *.txt *.xls *.xlsx);;All Files (*)',
            options=options)

        if filename == '':
            return

        sep = filename[-4:len(filename)]

        headerrows = int(self.header_spinbox.value())
        namecol = int(self.namecol_spinbox.value())
        xdatcol = int(self.xcol_spinbox.value())
        ydatcol = int(self.ycol_spinbox.value())
        xfidcol = int(self.fid_xcol_spinbox.value())
        yfidcol = int(self.fid_ycol_spinbox.value())

        # columns to use
        usecol = []
        if namecol > 0:
            usecol.append(namecol - 1)
        usecol.append(xdatcol - 1)
        usecol.append(ydatcol - 1)
        usecol.append(xfidcol - 1)
        usecol.append(yfidcol - 1)

        datain = None
        # csv and txt read in:
        try:
            if sep == '.csv':
                datain = pd.read_csv(filename,
                                     header=None,
                                     skiprows=headerrows,
                                     usecols=usecol)[usecol]
            # separator:
            elif sep == '.txt':
                datain = pd.read_csv(filename,
                                     delimiter='\t',
                                     header=None,
                                     skiprows=headerrows,
                                     usecols=usecol)[usecol]
            elif sep == '.xls' or sep == 'xlsx':
                datain = pd.read_excel(filename,
                                       header=None,
                                       skiprows=headerrows,
                                       usecols=usecol)[usecol]
        except KeyError or ValueError:
            self.show_data_error()
            return

        # first set the length of the table to be the length of the data
        self.datatable.setRowCount(0)
        # name column present
        namecolpresent = False
        if namecol > 0:
            namecolpresent = True

        # now add data rows
        for it in range(datain.shape[0]):
            row = []
            if not namecolpresent:
                row.append('')
            for jt in range(datain.shape[1]):
                row.append(datain.iloc[it, jt])
            # add the row to the table
            self.addTableRow(row)

        # adjust table size
        self.datatable.resizeColumnsToContents()

    def show_data_error(self):
        QMessageBox.warning(
            self, 'Requested data not found',
            'Could not find the data you requested. Please ensure'
            'that the data exists in the respective columns.')

    def addTableRow(self, row_data):
        row = self.datatable.rowCount()
        self.datatable.setRowCount(row + 1)
        col = 0
        for item in row_data:
            itemstr = str(item)
            if itemstr == 'nan':
                itemstr = ''
            cell = QTableWidgetItem(itemstr)
            self.datatable.setItem(row, col, cell)
            col += 1

    def savefile(self, sep):
        # get file name from dialog
        if sep == 'txt':
            filename, _ = QFileDialog.getSaveFileName(
                self, 'Save File As', '', 'Text Files (*.txt);;All Files (*)')
        else:
            filename, _ = QFileDialog.getSaveFileName(
                self, 'Save File As', '',
                'Comma Separated Files (*.csv);;All Files (*)')

        # if filename is empty
        if filename is '':
            return

        # open the file
        f = open(filename, 'w')

        # separator
        if sep == 'csv':
            ss = ','
        else:
            ss = '\t'

        # write header
        f.writelines('Name' + ss + 'x_old' + ss + 'y_old' + ss + 'x_ref' + ss +
                     'y_ref' + ss + 'x_calc' + ss + 'y_calc' + '\n')
        # write the data out

        for it in range(self.datatable.rowCount()):
            for jt in range(7):
                if self.datatable.item(it, jt) is not None:
                    savestring = self.datatable.item(
                        it, jt).text().strip().rstrip().replace('\n',
                                                                '').replace(
                                                                    '\r', '')
                    f.writelines(savestring)
                # separator if not last
                if jt < 6:
                    f.writelines(ss)
            f.writelines('\n')

        # flush and close
        f.flush()
        f.close()

    def test(self):
        print(self.calcmode)

    def help(self):
        msgBox = QMessageBox()
        msgBox.setIcon(QMessageBox.Information)
        msgBox.setWindowTitle('Help')
        msgBox.setInformativeText(
            'Help is implemented with tooltips, hover over the buttons in question\n'
            'and you should receive some information.\n\n'
            'Routines:\n'
            'Nittler: (PhD Thesis Larry Nittler, Appendix F)\n'
            'Linear regression to as many reference points that are given. Only \n'
            'Rotation and shift are included in this method. No stretch of the data.\n'
            'Make sure that the reference systems are in the same unit system!\n\n'
            'Admon: (Admon et al. (2005) Microsc. Microanal. 11, 354–362)\n'
            'Only three fiducial marks can be selected, however, stretch of the\n'
            'coordinate system is also calculated. Ideal when switching between\n'
            'different units from one coordinate system to the next.\n\n'
            'Author: Reto Trappitsch\n'
            'Version: ' + self.version + '\n'
            'Date: ' + self.version_date + '\n\n')
        msgBox.setStandardButtons(QMessageBox.Ok)
        msgBox.exec()

    def calculate(self):
        # admon or nittler
        if self.calcmode == 'Nittler':
            self.calculate_nittler()
        else:
            self.calculate_admon()

    def calculate_admon(self):
        # stop editing
        self.datatable.setCurrentItem(None)

        # fake z coordinate
        zcoord = 1.

        # initialize data input array as nan
        tabold = np.full((self.datatable.rowCount(), 3), np.nan)
        tabref = np.full((self.datatable.rowCount(), 2), np.nan)
        for it in range(self.datatable.rowCount()):
            # append data
            if self.datatable.item(it, 1) is not None and self.datatable.item(
                    it, 2) is not None:
                try:
                    if self.datatable.item(
                            it, 1).text() is not '' and self.datatable.item(
                                it, 2).text() is not '':
                        tabold[it][0] = float(
                            self.datatable.item(it, 1).text())
                        tabold[it][1] = float(
                            self.datatable.item(it, 2).text())
                        tabold[it][2] = zcoord
                except ValueError:
                    QMessageBox.warning(
                        self, 'Table error',
                        'There is an error in your data table. Please make sure '
                        'all numbers are floats.')
                    return
                except AttributeError:
                    QMessageBox.warning(
                        self, 'Table error',
                        'There is an error in the data table. Did you finish all '
                        'editing?')

            # append reference
            if self.datatable.item(it, 3) is not None and self.datatable.item(
                    it, 4) is not None:
                try:
                    if self.datatable.item(
                            it, 3).text() is not '' and self.datatable.item(
                                it, 4).text() is not '':
                        tabref[it][0] = float(
                            self.datatable.item(it, 3).text())
                        tabref[it][1] = float(
                            self.datatable.item(it, 4).text())
                except ValueError:
                    QMessageBox.warning(
                        self, 'Table error',
                        'There is an error in your data table. Please fix.')
                    return
                except AttributeError:
                    QMessageBox.warning(
                        self, 'Table error',
                        'There is an error in the data table. Did you finish all '
                        'editing?')

        # make sure at least two reference points are given
        # now find crefold and crefnew for calculation of parameters
        crefold = []
        crefnew = []
        for it in range(len(tabold)):
            if not np.isnan(tabold[it][0]) and not np.isnan(tabref[it][0]):
                crefold.append([tabold[it][0], tabold[it][1],
                                zcoord])  # artificially add a z coordinate
                crefnew.append([tabref[it][0], tabref[it][1],
                                zcoord])  # artificially add a z coordinate

        if len(crefnew) < 3:
            QMessageBox.warning(
                self, 'Reference error',
                'Need three reference points to transform into the '
                'new coordinates.')
            return
        if len(crefnew) > 3:
            QMessageBox.information(
                self, 'Too many reference points',
                'Only the first three reference values are '
                'taken for the transformation.')

        # transform to np.arrays, only take the first three entries
        crefold = np.array(crefold[0:3])
        crefnew = np.array(crefnew[0:3])
        crefoldt = np.array(crefold).transpose()
        crefnewt = np.array(crefnew).transpose()

        tabnew = np.zeros((len(tabold), 2))
        for it in range(len(tabold)):
            tmpnew = np.matmul(crefnewt,
                               np.matmul(np.linalg.inv(crefoldt), tabold[it]))
            tabnew[it][0] = np.round(tmpnew[0], self.rounddig)
            tabnew[it][1] = np.round(tmpnew[1], self.rounddig)

        # write the calc and the new into the table
        for it in range(len(tabold)):
            self.datatable.setItem(it, 5, QTableWidgetItem(str(tabnew[it][0])))
            self.datatable.setItem(it, 6, QTableWidgetItem(str(tabnew[it][1])))

        # resize columns to contents
        self.datatable.resizeColumnsToContents()

    def calculate_nittler(self):
        # stop editing
        self.datatable.setCurrentItem(None)

        # initialize data input array as nan
        tabold = np.full((self.datatable.rowCount(), 2), np.nan)
        tabref = np.full((self.datatable.rowCount(), 2), np.nan)
        for it in range(self.datatable.rowCount()):
            # append data
            if self.datatable.item(it, 1) is not None and self.datatable.item(
                    it, 2) is not None:
                try:
                    if self.datatable.item(
                            it, 1).text() is not '' and self.datatable.item(
                                it, 2).text() is not '':
                        tabold[it][0] = float(
                            self.datatable.item(it, 1).text())
                        tabold[it][1] = float(
                            self.datatable.item(it, 2).text())
                except ValueError:
                    QMessageBox.warning(
                        self, 'Table error',
                        'There is an error in your data table. Please make sure all '
                        'numbers are floats.')
                    return
                except AttributeError:
                    QMessageBox.warning(
                        self, 'Table error',
                        'There is an error in the data table. Did you finish all '
                        'editing?')

            # append reference
            if self.datatable.item(it, 3) is not None and self.datatable.item(
                    it, 4) is not None:
                try:
                    if self.datatable.item(
                            it, 3).text() is not '' and self.datatable.item(
                                it, 4).text() is not '':
                        tabref[it][0] = float(
                            self.datatable.item(it, 3).text())
                        tabref[it][1] = float(
                            self.datatable.item(it, 4).text())
                except ValueError:
                    QMessageBox.warning(
                        self, 'Table error',
                        'There is an error in your data table. Please fix.')
                    return
                except AttributeError:
                    QMessageBox.warning(
                        self, 'Table error',
                        'There is an error in the data table. Did you finish all '
                        'editing?')

        # make sure at least two reference points are given
        # now find crefold and crefnew for calculation of parameters
        crefold = []
        crefnew = []
        for it in range(len(tabold)):
            if not np.isnan(tabold[it][0]) and not np.isnan(tabref[it][0]):
                crefold.append([tabold[it][0], tabold[it][1]])
                crefnew.append([tabref[it][0], tabref[it][1]])

        if len(crefnew) < 2:
            QMessageBox.warning(
                self, 'Reference error',
                'Need at least two reference points to transform into the '
                'new coordinates.')
            return

        # transform to np.arrays
        crefold = np.array(crefold)
        crefnew = np.array(crefnew)

        # now calculate what i need to calculate with all the reference values, all variables start with var
        vara = 0.
        varb = 0.
        varc = 0.
        vard = float(len(crefold))
        vare = 0.
        varf = 0.
        varg = 0.
        varh = 0.
        # run the sums
        for it in range(len(crefold)):
            vara += (crefold[it][0]**2. + crefold[it][1]**2.)
            varb += crefold[it][0]
            varc += crefold[it][1]
            vare += (crefold[it][0] * crefnew[it][0] +
                     crefold[it][1] * crefnew[it][1])
            varf += (crefold[it][1] * crefnew[it][0] -
                     crefold[it][0] * crefnew[it][1])
            varg += crefnew[it][0]
            varh += crefnew[it][1]
        # calculate parameters
        params = (1. / (varb**2. + varc**2 - vara * vard)) * np.array([
            -vard * vare + varb * varg + varc * varh, -vard * varf +
            varc * varg - varb * varh, varb * vare + varc * varf - vara * varg,
            varc * vare - varb * varf - vara * varh
        ])

        tabnew = np.zeros((len(tabold), 2))
        for it in range(len(tabnew)):
            if not np.isnan(tabold[it][0]):
                tabnew[it][0] = np.round(
                    tabold[it][0] * params[0] + tabold[it][1] * params[1] +
                    params[2], self.rounddig)
                tabnew[it][1] = np.round(
                    -tabold[it][0] * params[1] + tabold[it][1] * params[0] +
                    params[3], self.rounddig)

        # calculate the reference
        crefcalc = []
        for it in range(len(crefold)):
            crefcalc.append([
                crefold[it][0] * params[0] + crefold[it][1] * params[1] +
                params[2], -crefold[it][0] * params[1] +
                crefold[it][1] * params[0] + params[3]
            ])

        # calculate shortest distance
        dsane = 0.
        for it in range(len(crefnew)):
            # add the delta between the points in the actual points
            dsane += np.sqrt((crefcalc[it][0] - crefnew[it][0])**2. +
                             (crefcalc[it][1] - crefnew[it][1])**2.)
            # now divide by total number of points to get average deviation
        dsane /= len(crefnew)

        # set text in info label
        self.infolbl.setText('Average distance error: ' +
                             str(np.round(dsane, self.rounddig)))

        # write the calc and the new into the table
        for it in range(len(tabold)):
            self.datatable.setItem(it, 5, QTableWidgetItem(str(tabnew[it][0])))
            self.datatable.setItem(it, 6, QTableWidgetItem(str(tabnew[it][1])))

        # resize columns to contents
        self.datatable.resizeColumnsToContents()

    def addrow(self):
        self.datatable.insertRow(self.datatable.rowCount())

    # def keyPressEvent(self, event):
    #     """
    #     Implement copy, paste
    #     """
    #     if type(event) == QKeyEvent:
    #         if event.key() == Qt.Key_Space:
    #             print('spacer')
    #
    def copy(self):
        inds = []
        for idx in self.datatable.selectedIndexes():
            inds.append([idx.row(), idx.column()])
        # now start string to copy
        str2cpy = ''
        try:
            oldrow = inds[0][0]
        except IndexError:  # nothing selected, then just do nothing
            return
        for it in range(len(inds)):
            # easier handling
            row = inds[it][0]
            col = inds[it][1]
            datfield = self.datatable.item(row, col)
            # check if the first
            if it == 0:
                if datfield is None:
                    str2cpy = ''
                else:
                    str2cpy = datfield.text()
            else:
                # add separator
                if oldrow == row:
                    str2cpy += '\t'
                else:
                    str2cpy += '\n'
                # now add the entry
                if datfield is None:
                    str2cpy += ''
                else:
                    str2cpy += datfield.text()
            # set new row
            oldrow = row

        # now copy the string to the clipboard
        self.clipboard.clear()
        self.clipboard.setText(str2cpy)

    def paste(self):
        # get the current index
        try:
            tmp = self.datatable.selectedIndexes()[0]
        except IndexError:  # nothing selected
            QMessageBox.warning(self, 'Selection error',
                                'Select a cell where to paste into')
            return
        currind = [tmp.row(), tmp.column()]
        # read in clipboard
        datain = self.clipboard.text().split('\n')

        # check for empty input
        if datain is '':
            QMessageBox.warning(self, 'Paste error',
                                'Nothing in clipboard to paste.')
            return

        data = []
        for line in datain:
            data.append(line.replace('\r', '').split())

        # check if outside of range in horizontal
        if currind[1] + len(data[0]) > 7:
            QMessageBox.warning(
                self, 'Paste error',
                'Too many columns in clipboard to fit. Wrong selection where to '
                'paste into?')
            return

        # add rows in the end until we have enough to paste into
        while currind[0] + len(data) > self.datatable.rowCount():
            self.datatable.insertRow(self.datatable.rowCount())

        # now fill the cells with the pasted stuff
        for row in range(len(data)):
            for col in range(len(data[row])):
                self.datatable.setItem(row + currind[0], col + currind[1],
                                       QTableWidgetItem(data[row][col]))

    def delete(self):
        # get the current index
        inds = []
        try:
            for idx in self.datatable.selectedIndexes():
                inds.append([idx.row(), idx.column()])
        except IndexError:  # nothing selected
            return

        # selected indeces
        print(inds)

        # now fill the cells with the pasted stuff
        for row, col in inds:
            self.datatable.setItem(row, col, QTableWidgetItem(''))

    def cleartable(self):
        # clear the table
        msgbox = QMessageBox.question(
            self, 'Clear table?', 'Are you sure you want to clear the table?',
            QMessageBox.Yes, QMessageBox.No)

        if msgbox == QMessageBox.Yes:
            self.datatable.clearContents()
            self.datatable.setRowCount(23)
Ejemplo n.º 5
0
class DisplayLayout(QDialog):

	def __init__(self, main, object):
		QDialog.__init__(self)

		self.main = main
		self.tmp = main.tmpDirectory
		self.object = object
		self.folderpath = ""
		self.layoutList = []
		self.closed = False
		self.setWindowTitle('Layout')
		self.setWindowFlags(Qt.Window)
		
		self.resize(650, 500)
		self.setMinimumSize(QSize(0, 500))
		self.setMaximumSize(QSize(16777215, 500))

		horizontalLayout = QHBoxLayout(self)

		formLayout = QFormLayout()
		formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
		formLayout.setFormAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)

		
		addLabel = QLabel(self)
		addLabel.setMinimumSize(QSize(23, 23))
		addLabel.setMaximumSize(QSize(23, 23))
		addLabel.setPixmap(QPixmap(self.main.pluginDirectory+"/icons/addLayout.png"))

		removeLabel = QLabel(self)
		removeLabel.setMinimumSize(QSize(23, 23))
		removeLabel.setMaximumSize(QSize(23, 23))
		removeLabel.setPixmap(QPixmap(self.main.pluginDirectory+"/icons/removeLayout.png"))
		
		addLayout = QHBoxLayout()
		addLayout.setSizeConstraint(QLayout.SetFixedSize)
		addLayout.addWidget(addLabel)
		addLayout.addWidget(removeLabel)
		formLayout.setLayout(0, QFormLayout.LabelRole, addLayout)
		
		
		self.layoutFoldersList = QTableWidget(0, 1, self)
		self.layoutFoldersList.setMinimumSize(QSize(300, 400))
		self.layoutFoldersList.setColumnWidth(0, 300)
		self.layoutFoldersList.setHorizontalHeaderLabels(["Layout-Ordner"])
		self.layoutFoldersList.setEditTriggers(QAbstractItemView.NoEditTriggers)
		self.layoutFoldersList.setSelectionMode(QAbstractItemView.SingleSelection)
		self.layoutsList = QTableWidget(0, 1, self)
		self.layoutsList.setMinimumSize(QSize(300, 400))
		self.layoutsList.setColumnWidth(0, 300)
		self.layoutsList.setHorizontalHeaderLabels(["Layouts"])
		self.layoutsList.setSelectionMode(QAbstractItemView.SingleSelection)
		self.layoutsList.setEditTriggers(QAbstractItemView.NoEditTriggers)

		layoutLayout = QHBoxLayout()
		layoutLayout.setSizeConstraint(QLayout.SetMaximumSize)		
		layoutLayout.addWidget(self.layoutFoldersList)
		layoutLayout.addWidget(self.layoutsList)
		formLayout.setLayout(1, QFormLayout.SpanningRole, layoutLayout)
		buttonBox = QDialogButtonBox(self)
		buttonBox.setStandardButtons(QDialogButtonBox.Close|QDialogButtonBox.Apply)
		formLayout.setWidget(2, QFormLayout.FieldRole, buttonBox)
		
		horizontalLayout.addLayout(formLayout)

		buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.showLayout)
		buttonBox.button(QDialogButtonBox.Close).clicked.connect(self.cancel)
		self.layoutFoldersList.itemClicked.connect(self.getLayouts)
		addLabel.mouseReleaseEvent = self.newFolder
		removeLabel.mouseReleaseEvent = self.delFolder
		
		self.layoutFoldersList.keyPressEvent = self.keyPress
		
		for layout in self.main.config.options('Layouts'):
			l = self.main.config.get('Layouts', layout)
			self.layoutList.append(layout)
			self.layoutFoldersList.setRowCount(self.layoutFoldersList.rowCount()+1)
			self.layoutFoldersList.setItem(self.layoutFoldersList.rowCount()-1, 0, QTableWidgetItem(l))
			
		#self.exec_()
		self.show()

	def show(self):
		super(DisplayLayout, self).show()
		self.closed = False
		
	def closeEvent(self, evnt):
		super(DisplayLayout, self).closeEvent(evnt)
		self.closed = True
		
	def showLayout(self):
		QApplication.setOverrideCursor(Qt.WaitCursor)
		selected = self.layoutsList.selectedItems()
		
		if not len(self.folderpath) or not len(selected):
			return
	
		now = datetime.datetime.now()
		a = str(now.year) + str(now.strftime('%m')) + str(now.strftime('%d'))

		GeODin = win32com.client.Dispatch("GeODin.GeODinApplication")
		info = GeODin.LicenceInfo.split('\r\n')
		#dongle = [t for t in info if 'dongle' in t.lower()]
		#print info
		if not len(info) or not len(info):
			return
			
		#print "Licence Info: ", info
		
		licence = info[1].split(': ')[1]
		m = hashlib.md5.new()
		m.update(a+'-'+licence)
		new_hash = m.hexdigest()
		
		#layout = self.folderpath + '\\' + str(selected[0].text())
		layout = self.folderpath + '\\' + selected[0].text()
		database = self.object.parent.parent
		invid = self.object.invid
		image = 41
		#image = 12
		
		Params = "[Params]\n"
		exe = "EXECUTE=ProducePortalImage\n"
		Layout = "LAYOUT="
		pagenumber = "\nPageNumber=20\n"
		scale = "Scale=0\n"
		version = "VersionName=\n"
		ArcGeODin = "ArcGeODin="
		dbName = "\n[Database]\n"
		name = "Name="
		username = "******"
		password = "******"
		objects = "[Objects]\n"
		objectID = "ObjectID1="
		Image = "\n[Image]\n"
		imageType = "ImageType="
		resolution = "\nResolution=3000"
		
		
		params = Params + exe + Layout + layout + pagenumber + scale + version + ArcGeODin + new_hash + dbName + name + str(database) + username + password + objects + objectID + invid + Image + imageType + str(image) + resolution

		pic = GeODin.ProduceData(params)

		if GeODin.ExceptionValue != 0: 
			print("Error ID: "+ str(GeODin.ExceptionValue))
			print("Error Message: "+GeODin.ExceptionMsg.encode('utf-8'))
			
		f = open(self.tmp + "\\out.pdf", 'wb')
		f.write("<!DOCTYPE html><html><head><meta charset='utf-8'/></head><body>\r\n" + pic[0].replace("\r\n","</br>").encode('utf-8')+"\r\n</body></html>")
		f.close()

		GeODin = None
		
		self.layoutDialog = ImageLayout(self.tmp + "/out.pdf", selected[0].text())
		
		
	def cancel(self):
		self.closed = True
		self.accept()
		#self.main = None
		#self.object = None
		#self.layoutFoldersList = None
		#self.accept()
		
	def newFolder(self, event):
		# get path for GeODin data
		path_data = str(self.main.config.get('Options', 'programdata'))
		# get layout directory
		directory = QFileDialog.getExistingDirectory(self, "Select Directory", path_data)
		#print type(directory)
		#print directory
#		directory = directory.encode('utf-8')
		
		# if layout directory has been specified
		if directory:
			i=0
			# map over layout folders
			self.layoutFoldersList.setRowCount(self.layoutFoldersList.rowCount() + 1)
			self.layoutFoldersList.setItem(self.layoutFoldersList.rowCount()-1, 0, QTableWidgetItem(directory))
			
			# write layout folder to config file
			while self.main.config.has_option('Layouts','L' + str(i)):
				i  =1
			self.main.config.set('Layouts', 'L'+str(i), directory)
			self.main.saveConfig()
			
			# append layouts to tableview
			self.layoutList.append('L' + str(i))
			
	def delFolder(self, event):
		# delete layout folder from list
		selected = self.layoutFoldersList.selectedItems()
		if selected:
			for s in reversed(selected):
				pos = self.layoutFoldersList.row(s)
				self.main.config.remove_option('Layouts', self.layoutList[pos])
				self.main.saveConfig()
				self.layoutList.pop(pos)
				self.layoutFoldersList.removeRow(pos)
	
	def reloadLayouts(self):
		selected = self.layoutFoldersList.selectedItems()
		if selected:
			self.getLayouts(selected[0])
	
	def getLayouts(self, item):
		path = item.text()
		self.folderpath = path
		layouts = [ l for l in os.listdir(path) if os.path.isfile(os.path.join(path,l)) and l.lower().endswith(".glo")]
		self.layoutsList.clearContents()
		self.layoutsList.setRowCount(0)
		if layouts:
			for l in layouts:
				self.layoutsList.setRowCount(self.layoutsList.rowCount()+1)
				self.layoutsList.setItem(self.layoutsList.rowCount()-1, 0, QTableWidgetItem(l))

	def keyPress(self, event):
		pass
Ejemplo n.º 6
0
class Labels(QWidget):
    """
    Attributes
    ----------
    chan_name : list of str
        list of all the labels (with the user-defined changes)
    """
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.filename = None
        self.chan_name = None  # None when dataset is not loaded

        self.create()

    def create(self):

        self.idx_load = QPushButton('Load')
        self.idx_load.clicked.connect(self.load_labels)
        self.idx_load.setToolTip('Load file with a list of channels (separated by , or ; or tabs or spaces).')
        self.idx_save = QPushButton('Save')
        self.idx_save.clicked.connect(self.save_labels)
        self.idx_save.setEnabled(False)

        # cancel is equal to setting labels to what they were
        self.idx_cancel = QPushButton('Cancel')
        self.idx_cancel.clicked.connect(self.update)
        self.idx_apply = QPushButton('Apply')
        self.idx_apply.clicked.connect(self.apply)
        self.idx_apply.setToolTip('Changes will take effect. This will reset the channel groups and traces.')

        layout_0 = QHBoxLayout()
        layout_0.addWidget(self.idx_load)
        layout_0.addWidget(self.idx_save)

        layout_1 = QHBoxLayout()
        layout_1.addWidget(self.idx_cancel)
        layout_1.addWidget(self.idx_apply)

        self.table = QTableWidget()

        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(['Current Labels', 'New Labels'])

        self.table.cellChanged.connect(self.check_labels)

        layout = QVBoxLayout()
        layout.addLayout(layout_0)
        layout.addWidget(self.table)
        layout.addLayout(layout_1)

        self.setLayout(layout)

        self.setEnabled(False)

    def update(self, checked=False, labels=None, custom_labels=None):
        """Use this function when we make changes to the list of labels or when
        we load a new dataset.

        Parameters
        ----------
        checked : bool
            argument from clicked.connect
        labels : list of str
            list of labels in the dataset (default)
        custom_labels : list of str
            list of labels from a file
        """
        if labels is not None:
            self.setEnabled(True)
            self.chan_name = labels

        self.table.blockSignals(True)
        self.table.clearContents()
        self.table.setRowCount(len(self.chan_name))

        for i, label in enumerate(self.chan_name):
            old_label = QTableWidgetItem(label)
            old_label.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

            if custom_labels is not None and i < len(custom_labels) and custom_labels[i]:  # it's not empty string or None
                label_txt = custom_labels[i]
            else:
                label_txt = label
            new_label = QTableWidgetItem(label_txt)

            self.table.setItem(i, 0, old_label)
            self.table.setItem(i, 1, new_label)

        self.table.blockSignals(False)

    def check_labels(self):

        # read new labels first
        labels = self._read_labels()

        # disable apply, if there are duplicates
        if len(labels) == len(set(labels)):
            self.idx_apply.setEnabled(True)
        else:
            self.idx_apply.setEnabled(False)

        # mark duplicates in red
        self.table.blockSignals(True)
        for i, label in enumerate(labels):
            if labels.count(label) > 1:
                self.table.item(i, 1).setBackground(QColor('red'))
            else:
                self.table.item(i, 1).setBackground(QColor('white'))
        self.table.blockSignals(False)

    def load_labels(self, checked=False, test_name=None):
        if self.filename is not None:
            filename = self.filename
        elif self.parent.info.filename is not None:
            filename = Path(self.parent.info.filename)
        else:
            filename = None

        if test_name:
            filename = test_name
        else:
            filename, _ = QFileDialog.getOpenFileName(self,
                                                      'Open Labels',
                                                      str(filename.parent),
                                                      'Comma-separated values (*.csv);; Text file (*.txt);; All Files(*.*)')
        if filename == '':
            return

        self.filename = Path(filename)

        with self.filename.open() as f:
            text = f.read()

        labels = split(', |,|; |;|\t|\n| ', text)
        labels = [label.strip() for label in labels]
        self.update(custom_labels=labels)

    def save_labels(self):
        """Save labels modified by the user.

        TODO
        ----
        Save labels modified by the user
        """
        pass

    def apply(self):

        self.chan_name = self._read_labels()
        self.parent.info.dataset.header['chan_name'] = self.chan_name

        self.parent.channels.reset()
        self.parent.channels.update()
        self.parent.traces.reset()

    def reset(self):
        self.table.blockSignals(True)
        self.table.clearContents()
        self.table.blockSignals(False)

        self.setEnabled(False)

    def _read_labels(self):

        labels = []
        for i in range(self.table.rowCount()):
            labels.append(self.table.item(i, 1).text())

        return labels
Ejemplo n.º 7
0
class MyMainWindow(QWidget):

    type = False
    type_sig = pyqtSignal(bool)

    def __init__(self):
        super().__init__()
        self.row = 0
        self.col = 10

        self.initUI()
        self.link()
        self.js = '/home/pi/pyqt/mp3/js.mp3'
        self.hs = '/home/pi/pyqt/mp3/hs.mp3'
        self.tx = '/home/pi/pyqt/mp3/tx.mp3'

    def initUI(self):
        # self.setupUi(self)

        # self.player = QMediaPlayer()
        # self.player.setVolume(100)

        bgHbox = QHBoxLayout()
        bgrid = QGridLayout()
        bgrid.setSpacing(10)
        leftVbox = QVBoxLayout()

        idHbox = QHBoxLayout()
        idLabel = QLabel("学号:")
        self.idLabelval = QLabel("20151110048")
        idHbox.addWidget(idLabel)
        idHbox.addWidget(self.idLabelval)

        nameHbox = QHBoxLayout()
        nameLable = QLabel("姓名:")
        self.nameLableval = QLabel("三胖")
        nameHbox.addWidget(nameLable)
        nameHbox.addWidget(self.nameLableval)

        classHbox = QHBoxLayout()
        classLabel = QLabel("班级:")
        self.classLabelval = QLabel("物联网1502  ")
        classHbox.addWidget(classLabel)
        classHbox.addWidget(self.classLabelval)

        self.retbtn = QPushButton("退出")
        self.retbtn.clicked.connect(self.ret)

        # self.insertbtn = QPushButton("插入")
        # self.insertbtn.clicked.connect(self.insertClick)

        line = QFrame()
        line.setFrameShape(QFrame.VLine)
        line.setFrameShadow(QFrame.Sunken)

        rightVbox = QVBoxLayout()
        self.table = QTableWidget()
        self.table.setColumnCount(self.col)
        self.table.setRowCount(100)
        self.table.setHorizontalHeaderLabels(
            ['图书名', '图书ID', '归还时间', '', '', '', '', '', '', ''])
        for i in range(self.col):
            self.table.setColumnWidth(i, 150)

        rightVbox.addWidget(self.table)
        # self.printBrowser = QTextBrowser()
        # rightVbox.addWidget(self.printBrowser)

        leftVbox.addStretch(20)
        leftVbox.addLayout(idHbox)
        leftVbox.addStretch(1)
        leftVbox.addLayout(nameHbox)
        leftVbox.addStretch(1)
        leftVbox.addLayout(classHbox)
        leftVbox.addStretch(1)
        leftVbox.addWidget(self.retbtn)
        # leftVbox.addWidget(self.insertbtn)
        leftVbox.addStretch(20)

        bgHbox.addLayout(leftVbox)
        bgHbox.addWidget(line)
        bgHbox.addLayout(rightVbox)

        self.setLayout(bgHbox)
        self.setWindowTitle("Main")
        self.setGeometry(300, 300, 1000, 1000 * 0.618)
        self.setWindowIcon(QIcon('/home/enheng/Pictures/Icon/music.png'))
        self.center()

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

    # def insertClick(self, item):
    #     self.addItem(["这是书名", "这是ID"])

    # 载入Main窗口
    def ok(self, type, id):
        self.type = type
        self.type_sig.emit(type)
        if type:
            self.setWindowTitle("借阅信息")
        else:
            self.setWindowTitle("归还信息")
            self.player.setMedia(QUrl.fromLocalFile(self.tx))
            self.player.play()

        self.idLabelval.setText(id)
        ret = self.dbcmd(
            "select Name, Class from stu where Id = '{0}'".format(id))
        # print(ret)
        if len(ret) != 0:
            self.nameLableval.setText(ret[0][0])
            self.classLabelval.setText(ret[0][1] + "  ")
        self.show()

    # 连接数据库
    def link(self):
        try:
            self.db = pymysql.connect('localhost',
                                      'enheng',
                                      '123456',
                                      'sorting',
                                      charset='utf8')
        except pymysql.err.Error:
            print("db Link error")
            self.close()
        else:
            self.cursor = self.db.cursor()
            self.c = comm(self.db, self.cursor)
            self.type_sig.connect(self.c.settype)
            self.c.book_sig.connect(self.addItem)
            self.c.start()

    # 数据库查询
    def dbcmd(self, cmd):
        try:
            self.cursor.execute(cmd)
            self.db.commit()
            return self.cursor.fetchall()
        except:
            self.db.rollback()
            print("db Select error")

    # 添加数据项
    def addItem(self, v):
        j = 0
        for i in range(len(v)):
            item = QTableWidgetItem(v[i])
            self.table.setItem(self.row, j, item)
            j += 1
        item = QTableWidgetItem(
            time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        self.table.setItem(self.row, j, item)
        self.row += 1

        if self.type:
            self.player.setMedia(QUrl.fromLocalFile(self.js))
        else:
            self.player.setMedia(QUrl.fromLocalFile(self.hs))
        self.player.play()

    # 退出时
    def ret(self):
        self.table.clearContents()
        self.row = 0
        self.hide()

    def closeEvent(self, a0: QtGui.QCloseEvent):
        if hasattr(self, 'db'):
            self.c.quit()
            self.cursor.close()
            self.db.close()
Ejemplo n.º 8
0
class SettingsDialog(QDialog):
    """
    The dialog allowing an user to configure the plugin. It has multiple tabs
    used to group the settings by category (general, network, etc.).
    """
    def __init__(self, plugin):
        super(SettingsDialog, self).__init__()
        self._plugin = plugin

        # General setup of the dialog
        self._plugin.logger.debug("Showing settings dialog")
        self.setWindowTitle("Settings")
        icon_path = self._plugin.plugin_resource("settings.png")
        self.setWindowIcon(QIcon(icon_path))
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint)

        window_widget = QWidget(self)
        window_layout = QVBoxLayout(window_widget)
        tabs = QTabWidget(window_widget)
        window_layout.addWidget(tabs)

        # "General Settings" tab
        tab = QWidget(tabs)
        layout = QFormLayout(tab)
        layout.setFormAlignment(Qt.AlignVCenter)
        tabs.addTab(tab, "General Settings")

        user_widget = QWidget(tab)
        user_layout = QHBoxLayout(user_widget)
        layout.addRow(user_widget)

        # User color
        self._color_button = QPushButton("")
        self._color_button.setFixedSize(50, 30)

        def color_button_activated(_):
            self._set_color(qt_color=QColorDialog.getColor().rgb())

        self._color = self._plugin.config["user"]["color"]
        self._set_color(ida_color=self._color)
        self._color_button.clicked.connect(color_button_activated)
        user_layout.addWidget(self._color_button)

        # User name
        self._name_line_edit = QLineEdit()
        name = self._plugin.config["user"]["name"]
        self._name_line_edit.setText(name)
        user_layout.addWidget(self._name_line_edit)

        text = "Disable all user cursors"
        self._disable_all_cursors_checkbox = QCheckBox(text)
        layout.addRow(self._disable_all_cursors_checkbox)
        navbar_checked = not self._plugin.config["cursors"]["navbar"]
        funcs_checked = not self._plugin.config["cursors"]["funcs"]
        disasm_checked = not self._plugin.config["cursors"]["disasm"]
        all_checked = navbar_checked and funcs_checked and disasm_checked
        self._disable_all_cursors_checkbox.setChecked(all_checked)

        def state_changed(state):
            enabled = state == Qt.Unchecked
            self._disable_navbar_cursors_checkbox.setChecked(not enabled)
            self._disable_navbar_cursors_checkbox.setEnabled(enabled)
            self._disable_funcs_cursors_checkbox.setChecked(not enabled)
            self._disable_funcs_cursors_checkbox.setEnabled(enabled)
            self._disable_disasm_cursors_checkbox.setChecked(not enabled)
            self._disable_disasm_cursors_checkbox.setEnabled(enabled)

        self._disable_all_cursors_checkbox.stateChanged.connect(state_changed)

        style_sheet = """QCheckBox{ margin-left: 20px; }"""

        text = "Disable navigation bar user cursors"
        self._disable_navbar_cursors_checkbox = QCheckBox(text)
        layout.addRow(self._disable_navbar_cursors_checkbox)
        self._disable_navbar_cursors_checkbox.setChecked(navbar_checked)
        self._disable_navbar_cursors_checkbox.setEnabled(not all_checked)
        self._disable_navbar_cursors_checkbox.setStyleSheet(style_sheet)

        text = "Disable functions window user cursors"
        self._disable_funcs_cursors_checkbox = QCheckBox(text)
        layout.addRow(self._disable_funcs_cursors_checkbox)
        self._disable_funcs_cursors_checkbox.setChecked(funcs_checked)
        self._disable_funcs_cursors_checkbox.setEnabled(not all_checked)
        self._disable_funcs_cursors_checkbox.setStyleSheet(style_sheet)

        text = "Disable disassembly view user cursors"
        self._disable_disasm_cursors_checkbox = QCheckBox(text)
        layout.addRow(self._disable_disasm_cursors_checkbox)
        self._disable_disasm_cursors_checkbox.setChecked(disasm_checked)
        self._disable_disasm_cursors_checkbox.setEnabled(not all_checked)
        self._disable_disasm_cursors_checkbox.setStyleSheet(style_sheet)

        text = "Allow other users to send notifications"
        self._notifications_checkbox = QCheckBox(text)
        layout.addRow(self._notifications_checkbox)
        checked = self._plugin.config["user"]["notifications"]
        self._notifications_checkbox.setChecked(checked)

        # Log level
        debug_level_label = QLabel("Logging level: ")
        self._debug_level_combo_box = QComboBox()
        self._debug_level_combo_box.addItem("CRITICAL", logging.CRITICAL)
        self._debug_level_combo_box.addItem("ERROR", logging.ERROR)
        self._debug_level_combo_box.addItem("WARNING", logging.WARNING)
        self._debug_level_combo_box.addItem("INFO", logging.INFO)
        self._debug_level_combo_box.addItem("DEBUG", logging.DEBUG)
        self._debug_level_combo_box.addItem("TRACE", logging.TRACE)
        level = self._plugin.config["level"]
        index = self._debug_level_combo_box.findData(level)
        self._debug_level_combo_box.setCurrentIndex(index)
        layout.addRow(debug_level_label, self._debug_level_combo_box)

        # "Network Settings" tab
        tab = QWidget(tabs)
        layout = QVBoxLayout(tab)
        tab.setLayout(layout)
        tabs.addTab(tab, "Network Settings")

        top_widget = QWidget(tab)
        layout.addWidget(top_widget)
        top_layout = QHBoxLayout(top_widget)

        self._servers = list(self._plugin.config["servers"])
        self._servers_table = QTableWidget(len(self._servers), 3, self)
        top_layout.addWidget(self._servers_table)
        for i, server in enumerate(self._servers):
            # Server host and port
            item = QTableWidgetItem("%s:%d" % (server["host"], server["port"]))
            item.setData(Qt.UserRole, server)
            item.setFlags(item.flags() & ~Qt.ItemIsEditable)
            # XXX - This prevented editing a server entry for your current
            # server because the row cannot be selected properly with
            # SingleSelection option selected
            #if self._plugin.network.server == server:
            #    item.setFlags((item.flags() & ~Qt.ItemIsSelectable))
            self._servers_table.setItem(i, 0, item)

            # Server has SSL enabled?
            ssl_checkbox = QTableWidgetItem()
            state = Qt.Unchecked if server["no_ssl"] else Qt.Checked
            ssl_checkbox.setCheckState(state)
            ssl_checkbox.setFlags((ssl_checkbox.flags() & ~Qt.ItemIsEditable))
            ssl_checkbox.setFlags(
                (ssl_checkbox.flags() & ~Qt.ItemIsUserCheckable))
            self._servers_table.setItem(i, 1, ssl_checkbox)

            # Auto-connect enabled?
            auto_checkbox = QTableWidgetItem()
            state = Qt.Unchecked if not server["auto_connect"] else Qt.Checked
            auto_checkbox.setCheckState(state)
            auto_checkbox.setFlags(
                (auto_checkbox.flags() & ~Qt.ItemIsEditable))
            auto_checkbox.setFlags(
                (auto_checkbox.flags() & ~Qt.ItemIsUserCheckable))
            self._servers_table.setItem(i, 2, auto_checkbox)

        self._servers_table.setHorizontalHeaderLabels(
            ("Servers", "SSL", "Auto"))
        horizontal_header = self._servers_table.horizontalHeader()
        horizontal_header.setSectionsClickable(False)
        horizontal_header.setSectionResizeMode(0, QHeaderView.Stretch)
        horizontal_header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        horizontal_header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        self._servers_table.verticalHeader().setVisible(False)
        self._servers_table.setSelectionBehavior(QTableWidget.SelectRows)
        self._servers_table.setSelectionMode(QTableWidget.SingleSelection)
        self._servers_table.itemClicked.connect(self._server_clicked)
        self._servers_table.itemDoubleClicked.connect(
            self._server_double_clicked)
        self._servers_table.setMaximumHeight(100)

        buttons_widget = QWidget(top_widget)
        buttons_layout = QVBoxLayout(buttons_widget)
        top_layout.addWidget(buttons_widget)

        # Add server button
        self._add_button = QPushButton("Add Server")
        self._add_button.clicked.connect(self._add_button_clicked)
        buttons_layout.addWidget(self._add_button)

        # Edit server button
        self._edit_button = QPushButton("Edit Server")
        self._edit_button.setEnabled(False)
        self._edit_button.clicked.connect(self._edit_button_clicked)
        buttons_layout.addWidget(self._edit_button)

        # Delete server button
        self._delete_button = QPushButton("Delete Server")
        self._delete_button.setEnabled(False)
        self._delete_button.clicked.connect(self._delete_button_clicked)
        buttons_layout.addWidget(self._delete_button)

        bottom_widget = QWidget(tab)
        bottom_layout = QFormLayout(bottom_widget)
        layout.addWidget(bottom_widget)

        # TCP Keep-Alive settings
        keep_cnt_label = QLabel("Keep-Alive Count: ")
        self._keep_cnt_spin_box = QSpinBox(bottom_widget)
        self._keep_cnt_spin_box.setRange(0, 86400)
        self._keep_cnt_spin_box.setValue(self._plugin.config["keep"]["cnt"])
        self._keep_cnt_spin_box.setSuffix(" packets")
        bottom_layout.addRow(keep_cnt_label, self._keep_cnt_spin_box)

        keep_intvl_label = QLabel("Keep-Alive Interval: ")
        self._keep_intvl_spin_box = QSpinBox(bottom_widget)
        self._keep_intvl_spin_box.setRange(0, 86400)
        self._keep_intvl_spin_box.setValue(
            self._plugin.config["keep"]["intvl"])
        self._keep_intvl_spin_box.setSuffix(" seconds")
        bottom_layout.addRow(keep_intvl_label, self._keep_intvl_spin_box)

        keep_idle_label = QLabel("Keep-Alive Idle: ")
        self._keep_idle_spin_box = QSpinBox(bottom_widget)
        self._keep_idle_spin_box.setRange(0, 86400)
        self._keep_idle_spin_box.setValue(self._plugin.config["keep"]["idle"])
        self._keep_idle_spin_box.setSuffix(" seconds")
        bottom_layout.addRow(keep_idle_label, self._keep_idle_spin_box)

        # Buttons commons to all tabs
        actions_widget = QWidget(self)
        actions_layout = QHBoxLayout(actions_widget)

        # Cancel = do not save the changes and close the dialog
        def cancel(_):
            self.reject()

        cancel_button = QPushButton("Cancel")
        cancel_button.clicked.connect(cancel)
        actions_layout.addWidget(cancel_button)

        # Reset = reset all settings from all tabs to default values
        reset_button = QPushButton("Reset")
        reset_button.clicked.connect(self._reset)
        actions_layout.addWidget(reset_button)

        # Save = save the changes and close the dialog
        def save(_):
            self._commit()
            self.accept()

        save_button = QPushButton("Save")
        save_button.clicked.connect(save)
        actions_layout.addWidget(save_button)
        window_layout.addWidget(actions_widget)

        # Do not allow the user to resize the dialog
        self.setFixedSize(window_widget.sizeHint().width(),
                          window_widget.sizeHint().height())

    def _set_color(self, ida_color=None, qt_color=None):
        """Sets the color of the user color button."""
        # IDA represents colors as 0xBBGGRR
        if ida_color is not None:
            r = ida_color & 255
            g = (ida_color >> 8) & 255
            b = (ida_color >> 16) & 255

        # Qt represents colors as 0xRRGGBB
        if qt_color is not None:
            r = (qt_color >> 16) & 255
            g = (qt_color >> 8) & 255
            b = qt_color & 255

        ida_color = r | g << 8 | b << 16
        qt_color = r << 16 | g << 8 | b

        # Set the stylesheet of the button
        css = "QPushButton {background-color: #%06x; color: #%06x;}"
        self._color_button.setStyleSheet(css % (qt_color, qt_color))
        self._color = ida_color

    def _server_clicked(self, _):
        self._edit_button.setEnabled(True)
        self._delete_button.setEnabled(True)

    def _server_double_clicked(self, _):
        item = self._servers_table.selectedItems()[0]
        server = item.data(Qt.UserRole)
        # If not the current server, connect to it
        if (not self._plugin.network.connected
                or self._plugin.network.server != server):
            self._plugin.network.stop_server()
            self._plugin.network.connect(server)
        self.accept()

    def _add_button_clicked(self, _):
        dialog = ServerInfoDialog(self._plugin, "Add server")
        dialog.accepted.connect(partial(self._add_dialog_accepted, dialog))
        dialog.exec_()

    def _edit_button_clicked(self, _):
        selected = self._servers_table.selectedItems()
        if len(selected) == 0:
            self._plugin.logger.warning("No server selected")
            return
        item = selected[0]
        server = item.data(Qt.UserRole)
        dialog = ServerInfoDialog(self._plugin, "Edit server", server)
        dialog.accepted.connect(partial(self._edit_dialog_accepted, dialog))
        dialog.exec_()

    def _delete_button_clicked(self, _):
        item = self._servers_table.selectedItems()[0]
        server = item.data(Qt.UserRole)
        self._servers.remove(server)
        self._plugin.save_config()
        self._servers_table.removeRow(item.row())
        self.update()

    def _add_dialog_accepted(self, dialog):
        """Called when the dialog to add a server is accepted."""
        server = dialog.get_result()
        self._servers.append(server)
        row_count = self._servers_table.rowCount()
        self._servers_table.insertRow(row_count)

        new_server = QTableWidgetItem("%s:%d" %
                                      (server["host"], server["port"]))
        new_server.setData(Qt.UserRole, server)
        new_server.setFlags(new_server.flags() & ~Qt.ItemIsEditable)
        self._servers_table.setItem(row_count, 0, new_server)

        new_checkbox = QTableWidgetItem()
        state = Qt.Unchecked if server["no_ssl"] else Qt.Checked
        new_checkbox.setCheckState(state)
        new_checkbox.setFlags((new_checkbox.flags() & ~Qt.ItemIsEditable))
        new_checkbox.setFlags(new_checkbox.flags() & ~Qt.ItemIsUserCheckable)
        self._servers_table.setItem(row_count, 1, new_checkbox)
        self.update()

    def _edit_dialog_accepted(self, dialog):
        """Called when the dialog to edit a server is accepted."""
        server = dialog.get_result()
        item = self._servers_table.selectedItems()[0]
        self._servers[item.row()] = server

        item.setText("%s:%d" % (server["host"], server["port"]))
        item.setData(Qt.UserRole, server)
        item.setFlags(item.flags() & ~Qt.ItemIsEditable)

        checkbox = self._servers_table.item(item.row(), 1)
        state = Qt.Unchecked if server["no_ssl"] else Qt.Checked
        checkbox.setCheckState(state)
        self.update()

    def _reset(self, _):
        """Resets all the form elements to their default value."""
        config = self._plugin.default_config()

        self._name_line_edit.setText(config["user"]["name"])
        self._set_color(ida_color=config["user"]["color"])

        navbar_checked = not config["cursors"]["navbar"]
        funcs_checked = not config["cursors"]["funcs"]
        disasm_checked = not config["cursors"]["disasm"]
        all_checked = navbar_checked and funcs_checked and disasm_checked
        self._disable_all_cursors_checkbox.setChecked(all_checked)

        self._disable_navbar_cursors_checkbox.setChecked(navbar_checked)
        self._disable_navbar_cursors_checkbox.setEnabled(not all_checked)
        self._disable_funcs_cursors_checkbox.setChecked(funcs_checked)
        self._disable_funcs_cursors_checkbox.setEnabled(not all_checked)
        self._disable_disasm_cursors_checkbox.setChecked(disasm_checked)
        self._disable_disasm_cursors_checkbox.setEnabled(not all_checked)

        checked = config["user"]["notifications"]
        self._notifications_checkbox.setChecked(checked)

        index = self._debug_level_combo_box.findData(config["level"])
        self._debug_level_combo_box.setCurrentIndex(index)

        del self._servers[:]
        self._servers_table.clearContents()
        self._keep_cnt_spin_box.setValue(config["keep"]["cnt"])
        self._keep_intvl_spin_box.setValue(config["keep"]["intvl"])
        self._keep_idle_spin_box.setValue(config["keep"]["idle"])

    def _commit(self):
        """Commits all the changes made to the form elements."""
        name = self._name_line_edit.text()
        if self._plugin.config["user"]["name"] != name:
            old_name = self._plugin.config["user"]["name"]
            self._plugin.network.send_packet(UpdateUserName(old_name, name))
            self._plugin.config["user"]["name"] = name

        if self._plugin.config["user"]["color"] != self._color:
            name = self._plugin.config["user"]["name"]
            old_color = self._plugin.config["user"]["color"]
            packet = UpdateUserColor(name, old_color, self._color)
            self._plugin.network.send_packet(packet)
            self._plugin.config["user"]["color"] = self._color
            self._plugin.interface.widget.refresh()

        all_ = self._disable_all_cursors_checkbox.isChecked()
        checked = self._disable_navbar_cursors_checkbox.isChecked()
        self._plugin.config["cursors"]["navbar"] = not all_ and not checked
        checked = self._disable_funcs_cursors_checkbox.isChecked()
        self._plugin.config["cursors"]["funcs"] = not all_ and not checked
        checked = self._disable_disasm_cursors_checkbox.isChecked()
        self._plugin.config["cursors"]["disasm"] = not all_ and not checked

        checked = self._notifications_checkbox.isChecked()
        self._plugin.config["user"]["notifications"] = checked

        index = self._debug_level_combo_box.currentIndex()
        level = self._debug_level_combo_box.itemData(index)
        self._plugin.logger.setLevel(level)
        self._plugin.config["level"] = level

        self._plugin.config["servers"] = self._servers
        cnt = self._keep_cnt_spin_box.value()
        self._plugin.config["keep"]["cnt"] = cnt
        intvl = self._keep_intvl_spin_box.value()
        self._plugin.config["keep"]["intvl"] = intvl
        idle = self._keep_idle_spin_box.value()
        self._plugin.config["keep"]["idle"] = idle
        if self._plugin.network.client:
            self._plugin.network.client.set_keep_alive(cnt, intvl, idle)

        self._plugin.save_config()
Ejemplo n.º 9
0
class SecondTab(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        grid = QGridLayout()

        grid.addWidget(self.create_choice_groupbox(), 0, 0)
        grid.addWidget(self.create_view_groupbox(), 0, 1)

        self.setLayout(grid)

    # Groupbox: 주문결제내역
    def create_choice_groupbox(self):
        gbox = QGroupBox()
        gbox.setTitle('주문결제내역')
        vbox = QVBoxLayout()

        # widget
        btn_update = QPushButton('새로고침', self)
        btn_update.clicked.connect(self.set_item_in_order_history_table)
        vbox.addWidget(btn_update)
        self.order_history_table = QTableWidget()
        self.create_order_history_table()
        vbox.addWidget(self.order_history_table)

        gbox.setLayout(vbox)

        return gbox

    # Groupbox: 조회
    def create_view_groupbox(self):
        gbox = QGroupBox()
        gbox.setTitle('조회')
        vbox = QVBoxLayout()

        # widget
        self.order_details_table = QTableWidget()
        self.create_order_details_table()
        vbox.addWidget(self.order_details_table)

        gbox.setLayout(vbox)

        return gbox

    # Table Widget: 조회할 주문 선택
    def create_order_history_table(self):
        self.order_history_table.setColumnCount(len(rec.summary_cols_list))
        self.order_history_table.setHorizontalHeaderLabels(
            rec.summary_cols_list)

        self.order_history_table.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.order_history_table.setSelectionBehavior(
            QAbstractItemView.SelectRows)

    # Table Widget: 상세조회
    def create_order_details_table(self):
        self.order_details_table.setColumnCount(len(rec.details_cols_list))
        self.order_details_table.setHorizontalHeaderLabels(
            rec.details_cols_list)
        self.order_details_table.setRowCount(4)

        self.order_details_table.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

    def set_item_in_order_history_table(self):
        self.order_history_table.clearContents()
        self.order_history_table.setRowCount(rec.summary_ws.max_row - 1)

        order_history_list = []
        for row in rec.summary_ws.iter_rows(min_row=2, values_only=True):
            order_history_list.append(row)

        for i in range(rec.summary_ws.max_row - 1):
            self.order_history_table.setItem(
                i, 0, QTableWidgetItem(order_history_list[i][0]))
            self.order_history_table.setItem(
                i, 1, QTableWidgetItem(str(order_history_list[i][1])))
        # Signal
        self.order_history_table.cellClicked.connect(
            self.set_item_in_order_details_table)

    @pyqtSlot(int, int)
    def set_item_in_order_details_table(self, row_int, col):
        self.order_details_table.clearContents()

        order_datetime_list = []
        order_details_list = []
        for row in rec.details_ws.iter_rows(min_row=2, values_only=True):
            order_datetime_list.append(row[0])
            order_details_list.append(row)

        order_datetime = rec.summary_ws['A'][row_int + 1].value
        order_index = order_datetime_list.index(order_datetime)
        order_count = order_datetime_list.count(order_datetime)
        self.order_details_table.setRowCount(order_count)
        order_details_2_list = order_details_list[order_index:order_index +
                                                  order_count]

        for i in range(order_count):
            self.order_details_table.setItem(
                i, 0, QTableWidgetItem(order_details_2_list[i][0]))
            self.order_details_table.setItem(
                i, 1, QTableWidgetItem(order_details_2_list[i][1]))
            self.order_details_table.setItem(
                i, 2, QTableWidgetItem(str(order_details_2_list[i][2])))
            self.order_details_table.setItem(
                i, 3, QTableWidgetItem(str(order_details_2_list[i][3])))
            self.order_details_table.setItem(
                i, 4, QTableWidgetItem(str(order_details_2_list[i][4])))
            self.order_details_table.setItem(
                i, 5, QTableWidgetItem(order_details_2_list[i][5]))
Ejemplo n.º 10
0
class Viewer(QMainWindow):
    """The main window for the application."""

    def __init__(self, stats, mode, difficulties, theme):
        """Initializes basic information about the Viewer class."""
        super().__init__()

        ### Initialize parameters passed from smtracker.py
        self.stats = stats                 # XML tree
        self.mode = mode                   # Gamemode
        self.difficulties = difficulties   # Tracked difficulties

        ### Initialize interface options
        self.icons_enabled = True          # Icons

        ### Create an empty table
        if self.stats is not None:
            song_count = len(self.stats.find("SongScores"))
            self.table = QTableWidget(song_count, len(self.difficulties) + 2)
        else:
            self.table = QTableWidget(0, len(self.difficulties) + 2)

        # Set some basic table attributes
        self.table.setIconSize(QSize(32, 32))
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.table.setSelectionMode(QAbstractItemView.NoSelection)

        table_header = ["Group", "Title"]
        table_header.extend(self.difficulties)

        # Sets the header cells
        for head in table_header:
            where = table_header.index(head)
            headeritem = QTableWidgetItem()
            headeritem.setText(head)
            self.table.setHorizontalHeaderItem(where, headeritem)

        self.theme = theme
        self.init_ui()


    def init_table(self):
        """Generates a table with the song scores."""

        # Prepare table for inserting items
        self.table.clearContents()
        self.table.setSortingEnabled(False)

        # Current table row
        current_row = 0
        for song in self.stats.find("SongScores"):
            # Current table row
            current_column = 0

            # Get the song's group and title
            # location[0] should always be "Songs"
            location = song.attrib['Dir'].split('/')

            # Create group cell
            group = QTableWidgetItem(location[1])
            self.table.setItem(current_row, current_column, group)
            current_column = current_column + 1

            # Create title cell
            title = QTableWidgetItem(location[2])
            self.table.setItem(current_row, current_column, title)
            current_column = current_column + 1

            # step_counter will be used for traversing the scores in a song
            step_counter = 0
            for diff in self.difficulties:
                try:
                    if (song[step_counter].attrib['Difficulty'] == diff and
                        song[step_counter].attrib['StepsType'] == self.mode):
                        try:
                            grade = smformat.highscore_grade(song[step_counter], self.theme)
                            percent = float(parse.highscore_stat(song[step_counter], "PercentDP")) * 100
                            if self.theme == "sm5" and self.icons_enabled is True:
                                cell = QTableWidgetItem('{:.2f}%'.format(percent))
                                cell.setIcon(QIcon(smtracker.__path__[0] + '/images/' + grade + '.png'))
                            else:
                                cell = QTableWidgetItem('{} ({:.2f}%)'.format(grade, percent))

                            # Get the timings for our song
                            timings = parse.highscore_timings(song[step_counter])

                            # TODO: Figure out if there's a cleaner way of
                            # doing this
                            tooltip = """Marvelous: {}
Perfect: {}
Great: {}
Good: {}
Boo: {}
Miss: {}
-----
Modifiers: {}
-----
SN2 Score: {}
DDRA Score: {}
IIDX EX Score: {}""".format(timings['W1'], timings['W2'], timings['W3'], timings['W4'],
                   timings['W5'], timings['Miss'],
                   parse.highscore_stat(song[step_counter], "Modifiers"),
                   parse.calculate_score_supernova2(song[step_counter]),
                   parse.calculate_score_ddra(song[step_counter]),
                   parse.calculate_score_iidx(song[step_counter]))
                            cell.setToolTip(tooltip)
                            self.table.setItem(current_row, current_column, cell)
                        # This exception is reached if a Song was played, but
                        # has no score (AutoPlay, PlayerAutoPlay)
                        except AttributeError:
                            cell = QTableWidgetItem()
                            self.table.setItem(current_row, current_column, cell)
                        step_counter = step_counter + 1
                    # If there are no scores for the current difficulty,
                    # add an empty cell instead
                    else:
                        cell = QTableWidgetItem()
                        self.table.setItem(current_row, current_column, cell)
                # This exception is reached if we already reached the last
                # score on a song (using step_counter)
                except IndexError:
                    cell = QTableWidgetItem()
                    self.table.setItem(current_row, current_column, cell)
                current_column = current_column + 1
            current_row = current_row + 1

        # Final table adjustments
        self.table.resizeColumnsToContents()
        self.table.setSortingEnabled(True)
        self.table.sortByColumn(0, Qt.AscendingOrder)


    def combobox_activated(self, combobox):
        """Sets the current game mode and regenerates the table."""
        self.mode = combobox.currentText()
        self.init_table()


    def themebox_activated(self, combobox):
        """Sets the current grading system and regenerates the table."""
        self.theme = combobox.currentText()
        self.init_table()


    def about_box(self):
        """Shows an about box with information about smtracker."""

        text = ("<p>{desc} (version {vers})</p>"
                "<p>Released under the terms of the <a href=\"http://www.gnu.org"
                "/licenses/gpl-3.0.html\">GNU General Public License"
                ", version 3 or later</a></p>"
                "<p>Icons provided by <a href=\"http://stepmania.com\">"
                "StepMania</a> under the <a href=\"https://github.com/stepmania"
                "/stepmania/blob/master/Docs/Licenses.txt\">MIT license</a></p>"
                "<p><a href=\"{url}\">{url}</a></p>").format(
                    desc=smtracker.__description__,
                    vers=smtracker.__version__,
                    url=smtracker.__url__)
        QMessageBox.information(self, "About smtracker", text)


    def export_html(self):
        """Saves an HTML report using QFileDialog to set a location."""
        filetuple = QFileDialog.getSaveFileName(self, "Save HTML report as",
                                                None, "HTML file (*.html)")

        if filetuple[0]:
            if filetuple[0].endswith(".html"):
                filename = filetuple[0]
            else:
                filename = filetuple[0] + ".html"

            html.save(self.stats, self.mode, self.difficulties, self.theme,
                      filename)


    def set_statusbar(self):
        """Resets the application statusbar."""
        displayname = parse.get_profile_name(self.stats)
        lastplayed = parse.get_last_played(self.stats)
        status = 'Profile: {} // Last played: {}'.format(displayname,
                                                         lastplayed)
        self.setStatusTip(status)


    def set_stats(self, stats):
        """Sets a new Stats.xml file and regenerates the UI."""
        self.stats = stats
        self.table.setRowCount(len(self.stats.find("SongScores")))
        self.init_table()
        self.set_statusbar()


    def open_file(self):
        """Opens a QFileDialog to set a new Stats.xml file."""
        filetuple = QFileDialog.getOpenFileName(self, "Select Stats.xml file "
                                                "to open", None, "StepMania stats "
                                                "files (*.xml)")
        if filetuple[0]:
            tempstats = etree.parse(filetuple[0]).getroot()
            if tempstats.find("SongScores") is None:
                QMessageBox.critical(self, "Error parsing file", "The selected "
                                     "file is not a valid StepMania Stats.xml "
                                     "file.")
            else:
                self.set_stats(tempstats)


    def toggle_icons(self, state):
        """Sets icons_enabled and regenerates the table."""
        self.icons_enabled = state
        self.init_table()

    def init_menubar(self):
        """Generates the main window menu bar."""

        # Creates the actions for the main menu
        ### 'File' menu
        exit_action = QAction('E&xit', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.setStatusTip('Exit smtracker')
        exit_action.triggered.connect(qApp.exit)

        export_action = QAction('&Export...', self)
        export_action.setShortcut('Ctrl+E')
        export_action.setStatusTip('Export table as HTML file')
        export_action.triggered.connect(self.export_html)

        open_action = QAction('&Open...', self)
        open_action.setShortcut('Ctrl+O')
        open_action.setStatusTip('Open a Stats.xml file')
        open_action.triggered.connect(self.open_file)

        ### 'Options' menu
        icons_action = QAction('Enable &icons', self)
        icons_action.setCheckable(True)
        icons_action.setChecked(self.icons_enabled)
        icons_action.triggered.connect(lambda: self.toggle_icons(icons_action.isChecked()))

        ### 'About' menu
        about_action = QAction('&About smtracker...', self)
        about_action.triggered.connect(self.about_box)

        qt_action = QAction('About &Qt...', self)
        qt_action.triggered.connect(QApplication.aboutQt)

        # Creates the menu bar and starts adding items to it
        menubar = self.menuBar()
        file_menu = menubar.addMenu('&File')
        file_menu.addAction(open_action)

        # Create the profile submenu and add the machine profile item
        profile_menu = file_menu.addMenu('Open &profile')
        mp_action = profile_menu.addAction('Machine Profile')

        # Define the location for profiles
        profile_folder, mp_folder = parse.get_profile_location()

        # Check if the machine profile exists
        if os.path.isfile(mp_folder + "Stats.xml") is True:
            no_mp = False
            mp_action.setStatusTip('Open this machine\'s profile')
            machine_profile = etree.parse(mp_folder + "Stats.xml").getroot()
            mp_action.triggered.connect(lambda: self.set_stats(machine_profile))
        else:
            no_mp = True
            mp_action.setEnabled(False)

        # Check if there's any local profiles
        if os.path.isdir(profile_folder) is True:
            no_lp = False
            profile_menu.addSeparator()
            for profile in os.listdir(profile_folder):
                tempstats = etree.parse(profile_folder + profile + "/Stats.xml").getroot()
                tempname = parse.get_profile_name(tempstats)
                action = profile_menu.addAction(tempname)
                function = functools.partial(self.set_stats, tempstats)
                action.triggered.connect(function)
        else:
            no_lp = True

        # If there are no profiles at all, disable profile menu
        if no_mp is True and no_lp is True:
            profile_menu.setEnabled(False)

        # Add the rest of the actions to the menubar
        file_menu.addAction(export_action)
        file_menu.addAction(exit_action)

        options_menu = menubar.addMenu('&Options')
        options_menu.addAction(icons_action)

        about_menu = menubar.addMenu('&About')
        about_menu.addAction(about_action)
        about_menu.addAction(qt_action)

    def init_ui(self):
        """Initializes the user interface."""
        modes = ("dance-single", "dance-double", "pump-single", "pump-double",
                 "pump-halfdouble", "bm-single7", "bm-double7")
        themes = ("sm5", "itg", "supernova2", "ddra", "iidx")

        # Combobox for game modes
        combobox = QComboBox()
        combobox.addItems(modes)
        combobox.setCurrentText(self.mode)
        combolabel = QLabel("Game mode:")
        combobox.activated.connect(lambda: self.combobox_activated(combobox))

        themebox = QComboBox()
        themebox.addItems(themes)
        themebox.setCurrentText(self.theme)
        themelabel = QLabel("Grading system:")
        themebox.activated.connect(lambda: self.themebox_activated(themebox))

        self.init_menubar()

        if self.stats is not None:
            self.init_table()

        hbox = QHBoxLayout()
        hbox.addWidget(combolabel)
        hbox.addWidget(combobox, 1)
        hbox.addWidget(themelabel)
        hbox.addWidget(themebox, 1)
        vbox = QVBoxLayout()
        vbox.addLayout(hbox)
        vbox.addWidget(self.table)

        container = QWidget()
        container.setLayout(vbox)
        self.setCentralWidget(container)

        self.statusBar()
        if self.stats is not None:
            self.set_statusbar()
        else:
            self.setStatusTip("No Stats.xml file loaded")
        self.setWindowTitle('smtracker - StepMania Score Tracker')
        self.resize(1200, 700)
        self.show()
Ejemplo n.º 11
0
class MetadataWidget(QWidget):

    def __init__(self, mainWindow):

        # exécuter le constructeur de la classe de base :
        QWidget.__init__(self, mainWindow)

        '''Le constructeur de la classe MetadataWidget reçoit une référence
           sur l'application principale, affectée à l'attribut 'mw'. Cette
           référence est utile pour accéder aux différents onglets de l'appli-
           cation et les données associées (listes, dictionnaires...).'''

        self.mw              = mainWindow

        # Le tableau des noms de fichiers et des paramètres usinages déduits
        # des noms :
        self.table           = QTableWidget(self)
        self.__listMateriaux = []   # materiaux trouvés dans les noms fichiers

        # Le bouton pour lancer le scan du répertoire choisi:
        self.btn_scanFiles   = QPushButton("Scan Fichiers", self)

        # Les widgets pour choisir et afficher le répertoire à scanner :
        self.labelUsinage    = QLabel("Dossier usinage", self)
        self.dossierUsinage  = QLineEdit(self.mw.usinage_dir, self)
        self.choisirDossierU = QPushButton("...", self)

        # La liste des fichiers *.txt de perçage/tournage  trouvés dans le
        # répertoire renvoyé par 'dossierUsin' :
        self.listeFichiers   = []

        # connecter le clic des widgets aux méthodes de la classe :
        self.ConnectWidgetsToMethods()

    @property
    def listMateriaux(self) : return self.__listMateriaux.copy()

    def set_listMateriaux(self,new_list) :
        self.__listMateriaux = new_list

    @property
    def dossierUsin(self):
        '''Le répertoire dans lequel sont cherchés les fichiers de mesure
           *.txt'''
        return self.dossierUsinage.text()

    @dossierUsin.setter
    def dossierUsin(self, dir_name):
        self.dossierUsinage.setText(dir_name)

    def ChoixDossier(self, currDir, operation):
        '''Lance un navigateur pour choisir l\'emplacement du dossier
           contenant les fichiers d'acquisition *.txt.'''

        mess = 'Choix du dossier <usinage> ' + operation
        dir_name = QFileDialog.getExistingDirectory(None,
                                                    mess,
                                                    currDir)
        if dir_name != '' :
            # un répertoire valide a été choisi :
            self.dossierUsin = dir_name  # MAJ du label
            self.ClearTable()         # effacer le tableau


    def ListerTxt(self, dossierU):
        '''Affecte à l'attribut 'listeFichiers' la liste triée des
           fichiers *.txt contenus dans le répertoire dossierU passé en
           argument.'''
        ####################################################################
        ######## <Méthode ListerTxt à écrire> ##############################
        ####################################################################






        ####################################################################

    def ResizeTableColums(self):
        '''Met à jour la largeur des colonnes du tableau des fichiers en
           fonction des contenus des colonnes.'''
        for c in range(self.table.columnCount()):
            self.table.resizeColumnToContents(c)

    def ClearTable(self):
        '''Efface les données du tableau des fichiers.'''
        self.table.clearContents()

    def ListerFichiers(self):
        '''Scanne le répertoire choisi pour trouver les fichiers *.txt, efface
           le tableau et le remplit avec les nouvelles informations obtenues
           avec les noms des fichiers.'''
        self.ClearTable()
        self.ListerTxt(self.dossierUsin)
        self.RemplirTable()
        self.ResizeTableColums()

    def ConnectWidgetsToMethods(self):
        '''Connecte les actions des widgets (QPushButton, QTableWidget...)
           aux méthodes appropriées.'''

        mess  = 'Liste les fichiers *.txt de perçage'
        mess += 'contenus dans le dossier choisi.'
        self.btn_scanFiles.setToolTip(mess)
        self.btn_scanFiles.clicked.connect(self.ListerFichiers)

        mess  = 'Lance un navigateur pour choisir l\'emplacement du dossier'
        mess += ' de travail.'
        self.choisirDossierU.setToolTip(mess)
        self.choisirDossierU.clicked.connect(self.ChoixDossier)

        self.table.setSortingEnabled(True)
class TournamentOrganizerWidget(QWidget):
	def __init__(self, parent):
		super(TournamentOrganizerWidget, self).__init__(parent)
		self.parent = parent

		# Default Players (for quick testing)
		player_names = [
			'Frodo',
			'Sam',
			'Merry',
			'Pippin',
			'Gandalf',
			'Aragorn',
			'Legolas',
			'Gimli',
			'Boromir'
		]
		# for name in player_names:
		# 	to.add_player(name, None)

		self.sort_order = 'by_name'

		view.notifier.observers.append(self)

		self.header_label = QLabel('Players')

		self.header_widget = QWidget(self)
		header_layout = QBoxLayout(QBoxLayout.LeftToRight)
		header_layout.addWidget(self.header_label)
		self.header_widget.setLayout(header_layout)

		self.sort_by_name_btn = QPushButton('Sort by Name', self)
		self.sort_by_name_btn.clicked.connect(self.sort_by_name)
		self.sort_by_rank_btn = QPushButton('Sort by Rank', self)
		self.sort_by_rank_btn.clicked.connect(self.sort_by_rank)

		self.sort_btns_widget = QWidget(self)
		sort_btns_layout = QBoxLayout(QBoxLayout.LeftToRight)
		sort_btns_layout.addWidget(self.sort_by_name_btn)
		sort_btns_layout.addSpacing(10)
		sort_btns_layout.addWidget(self.sort_by_rank_btn)
		self.sort_btns_widget.setLayout(sort_btns_layout)

		self.player_list = QTableWidget(style.style_loader.TABLE_INITIAL_LENGTH, 2, self)
		self.player_list.setHorizontalHeaderLabels(['Name', 'Record'])
		self.player_list.setFixedHeight(300)
		self.player_list.setFixedWidth(400)
		self.player_list.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
		self.player_list.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
		self.player_list.horizontalHeader().setVisible(True)

		self.player_list_widget = QWidget(self)
		player_list_layout = QBoxLayout(QBoxLayout.LeftToRight)
		player_list_layout.addWidget(self.player_list)
		self.player_list_widget.setLayout(player_list_layout)

		self.add_player_btn = QPushButton('Add Player', self)
		self.add_player_btn.clicked.connect(self.parent.show_add_player_widget)
		self.remove_player_btn = QPushButton('Remove Player', self)
		self.remove_player_btn.clicked.connect(self.parent.show_remove_player_widget)

		self.player_btns_widget = QWidget(self)
		player_btn_layout = QBoxLayout(QBoxLayout.LeftToRight)
		player_btn_layout.addWidget(self.add_player_btn)
		player_btn_layout.addSpacing(10)
		player_btn_layout.addWidget(self.remove_player_btn)
		self.player_btns_widget.setLayout(player_btn_layout)

		self.error = None

		layout = QFormLayout()
		layout.addRow(self.header_widget)
		layout.addRow(self.sort_btns_widget)
		layout.addRow(self.player_list_widget)
		layout.addRow(self.player_btns_widget)
		self.setLayout(layout)

		self.update()

	def update(self):
		self.player_list.clearContents()

		players = [to.players[player] for player in to.sorted_players(self.sort_order)]

		index = 0
		for player in players:
			if index == self.player_list.rowCount():
				self.player_list.insertRow(index)
			name_item = QTableWidgetItem(player.name)
			name_item.setFlags(name_item.flags() & ~Qt.ItemIsEditable)
			self.player_list.setItem(index, 0, name_item)
			record_item = QTableWidgetItem(player.record_str())
			record_item.setFlags(record_item.flags() & ~Qt.ItemIsEditable)
			self.player_list.setItem(index, 1, record_item)
			index += 1
		self.player_list.show()

	def sort_by_name(self):
		self.sort_order = 'by_name'
		self.update()

	def sort_by_rank(self):
		self.sort_order = 'by_rank'
		self.update()

	def player_added(self, player, user):
		try:
			to.add_player(player, user)
		except TournamentException as ex:
			self.error = ErrorMessage(str(ex), '')
			self.error.setStyleSheet(style.style_loader.stylesheet)
			self.error.show()
		self.update()

	def player_removed(self, player):
		try:
			to.remove_player(player)
		except TournamentException as ex:
			self.error = ErrorMessage(str(ex), '')
			self.error.setStyleSheet(style.style_loader.stylesheet)
			self.error.show()
		self.update()

	def report_result(self, player, record, win_or_draw):
		pass

	def result_reported(self):
		self.update()

	def pairings_created(self):
		self.update()

	def reset(self):
		self.update()
Ejemplo n.º 13
0
class HyperLprWindow(QMainWindow):

    start_init_signal = pyqtSignal()

    def __init__(self):

        super().__init__()

        self.initUI()

    def initUI(self):

        self.statusBar().showMessage('Ready')

        self.left_action = QAction('上一个', self)
        self.left_action.setShortcut(QKeySequence.MoveToPreviousChar)
        self.left_action.triggered.connect(self.analyze_last_one_image)

        self.right_action = QAction('下一个', self)
        self.right_action.setShortcut(QKeySequence.MoveToNextChar)
        self.right_action.triggered.connect(self.analyze_next_one_image)

        self.rename_image_action = QAction('保存e2e文件名', self)
        self.rename_image_action.setShortcut(QKeySequence.MoveToPreviousLine)
        self.rename_image_action.triggered.connect(self.rename_current_image_with_info)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&Function')
        fileMenu.addAction(self.left_action)
        fileMenu.addAction(self.right_action)
        fileMenu.addAction(self.rename_image_action)

        self.image_window_view = HyperLprImageView()

        table_widget_header_labels = [
            "文件名",
            "分割识别",
            "置信度",
            "颜色",
            "E2E识别",
            "E2E置信度"]

        self.hyperlpr_tableview = QTableWidget(
            0, len(table_widget_header_labels))
        self.hyperlpr_tableview.setHorizontalHeaderLabels(
            table_widget_header_labels)

        self.hyperlpr_tableview.setSelectionBehavior(
            QAbstractItemView.SelectItems)
        self.hyperlpr_tableview.setSelectionMode(
            QAbstractItemView.SingleSelection)
        self.hyperlpr_tableview.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.hyperlpr_tableview.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.hyperlpr_tableview.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

        self.hyperlpr_tableview.cellClicked.connect(
            self.recognize_one_license_plate)

        self.left_button = QPushButton("<")
        self.left_button.setFixedWidth(60)
        self.right_button = QPushButton(">")
        self.right_button.setFixedWidth(60)
        self.left_button.setEnabled(False)
        self.right_button.setEnabled(False)
        self.left_button.clicked.connect(self.analyze_last_one_image)
        self.right_button.clicked.connect(self.analyze_next_one_image)
        left_right_layout = QHBoxLayout()
        left_right_layout.addStretch()
        left_right_layout.addWidget(self.left_button)
        left_right_layout.addStretch()
        left_right_layout.addWidget(self.right_button)
        left_right_layout.addStretch()

        self.location_label = QLabel("车牌目录", self)
        self.location_text = QLineEdit(self)
        self.location_text.setEnabled(False)
        #self.location_text.setFixedWidth(300)
        self.location_button = QPushButton("...")
        self.location_button.clicked.connect(self.select_new_dir)

        self.location_layout = QHBoxLayout()
        self.location_layout.addWidget(self.location_label)
        self.location_layout.addWidget(self.location_text)
        self.location_layout.addWidget(self.location_button)
        self.location_layout.addStretch()

        self.check_box = QCheckBox("与文件名比较车牌")
        self.check_box.setChecked(True)

        self.update_file_path_button = QPushButton('批量识别')
        self.update_file_path_button.clicked.connect(
            self.batch_recognize_all_images)

        self.update_file_path_layout = QHBoxLayout()
        self.update_file_path_layout.addWidget(self.check_box)
        self.update_file_path_layout.addWidget(self.update_file_path_button)
        self.update_file_path_layout.addStretch()

        self.save_as_e2e_filename_button = QPushButton("保存e2e文件名")
        self.save_as_e2e_filename_button.setEnabled(False)
        self.save_as_e2e_filename_button.clicked.connect(self.rename_current_image_with_info)
        self.save_layout = QHBoxLayout()
        self.save_layout.addWidget(self.save_as_e2e_filename_button)
        self.save_layout.addStretch()

        self.top_layout = QVBoxLayout()
        self.top_layout.addLayout(left_right_layout)
        self.top_layout.addLayout(self.location_layout)
        self.top_layout.addLayout(self.update_file_path_layout)
        self.top_layout.addLayout(self.save_layout)

        function_groupbox = QGroupBox("功能区")
        function_groupbox.setLayout(self.top_layout)

        license_plate_image_label = QLabel("车牌图")
        self.license_plate_widget = QLabel("")

        block_image_label = QLabel("分割图")
        self.block_plate_widget = QLabel("")

        filename_label = QLabel("文件名:")
        self.filename_edit = QLineEdit()

        segmentation_recognition_label = QLabel("分割识别:")
        self.segmentation_recognition_edit = QLineEdit()
        self.segmentation_recognition_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.segmentation_recognition_edit.setStyleSheet("color:red")

        confidence_label = QLabel("分割识别\n置信度")
        self.confidence_edit = QLineEdit()
        #self.confidence_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.confidence_edit.setStyleSheet("color:red")

        plate_color_label = QLabel("车牌颜色")
        self.plate_color_edit = QLineEdit()
        self.plate_color_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.plate_color_edit.setStyleSheet("color:red")

        e2e_recognization_label = QLabel("e2e识别:")
        self.e2e_recognization_edit = QLineEdit()
        self.e2e_recognization_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.e2e_recognization_edit.setStyleSheet("color:red")

        e2e_confidence_label = QLabel("e2e置信度")
        self.e2e_confidence_edit = QLineEdit()
        #self.e2e_confidence_edit.setFont(QFont("黑体", 24, QFont.Bold))
        # self.e2e_confidence_edit.setStyleSheet("color:red")

        info_gridlayout = QGridLayout()
        line_index = 0
        info_gridlayout.addWidget(filename_label, line_index, 0)
        info_gridlayout.addWidget(self.filename_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(license_plate_image_label, line_index, 0)
        info_gridlayout.addWidget(self.license_plate_widget, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(e2e_recognization_label, line_index, 0)
        info_gridlayout.addWidget(self.e2e_recognization_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(
            segmentation_recognition_label, line_index, 0)
        info_gridlayout.addWidget(
            self.segmentation_recognition_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(plate_color_label, line_index, 0)
        info_gridlayout.addWidget(self.plate_color_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(block_image_label, line_index, 0)
        info_gridlayout.addWidget(self.block_plate_widget, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(confidence_label, line_index, 0)
        info_gridlayout.addWidget(self.confidence_edit, line_index, 1)
        line_index += 1
        info_gridlayout.addWidget(e2e_confidence_label, line_index, 0)
        info_gridlayout.addWidget(self.e2e_confidence_edit, line_index, 1)

        info_widget = QGroupBox("分割识别&e2e")

        info_widget.setLayout(info_gridlayout)

        right_splitter = QSplitter(Qt.Vertical)
        right_splitter.addWidget(self.hyperlpr_tableview)
        right_splitter.addWidget(function_groupbox)
        right_splitter.addWidget(info_widget)
        right_splitter.setStretchFactor(0, 2)
        right_splitter.setStretchFactor(2, 1)

        main_splitter = QSplitter(Qt.Horizontal)
        main_splitter.addWidget(self.image_window_view)
        main_splitter.addWidget(right_splitter)
        main_splitter.setStretchFactor(0, 1)

        self.image_filename_list = []
        self.hyperlpr_dir_path = ""
        self.segmentation_recognition_correct_number = 0
        self.color_correct_number = 0
        self.e2e_recognization_correct_number = 0
        self.current_row = 0

        self.batch_recognization_thread = LicenseRecognizationThread()
        self.batch_recognization_thread.recognization_done_signal.connect(
            self.recognization_done_slot)
        self.batch_recognization_thread.start()

        self.start_init_signal.connect(self.read_path_and_show_one_image)

        self.setCentralWidget(main_splitter)

        self.setWindowTitle("HyperLPR车牌识别软件v1.0")

        self.start_init_signal.emit()

    def read_path_and_show_one_image(self):

        hyperlpr_dir_info_filepath = QDir.homePath() + "/hyperlpr_dir_file"
        if os.path.exists(hyperlpr_dir_info_filepath):
            with open(hyperlpr_dir_info_filepath, 'r') as f:
                self.hyperlpr_dir_path = f.read()

        if len(self.hyperlpr_dir_path) > 0:
            self.reset_info_gui()

        if len(self.image_filename_list) > 0:
            self.recognize_and_show_one_image(self.image_filename_list[0], 0)

    def select_new_dir(self):

        self.hyperlpr_dir_path = QFileDialog.getExistingDirectory(
            self, "读取文件夹", QDir.currentPath())

        if len(self.hyperlpr_dir_path) > 0:
            hyperlpr_dir_info_filepath = QDir.homePath() + "/hyperlpr_dir_file"
            with open(hyperlpr_dir_info_filepath, 'w') as f:
                f.write(self.hyperlpr_dir_path)
            self.reset_info_gui()

    def rename_current_image_with_info(self):
        if len(self.hyperlpr_dir_path) > 0:
            target_dir_path = self.hyperlpr_dir_path + "/result"
            if not os.path.exists(target_dir_path):
                os.makedirs(target_dir_path)
            if len(self.plate_color_edit.text())>0 and len(self.e2e_recognization_edit.text())>0:
                orign_path = os.path.join(self.hyperlpr_dir_path, self.filename_edit.text())
                target_path = os.path.join(target_dir_path,self.plate_color_edit.text()+"-"+self.e2e_recognization_edit.text()+".jpg")
                shutil.copyfile(orign_path, target_path)

    def reset_info_gui(self):

        self.location_text.setText(self.hyperlpr_dir_path)
        self.scan_files_with_new_dir(self.hyperlpr_dir_path)
        self.fill_table_with_new_info()

    def scan_files_with_new_dir(self, path):

        name_list = os.listdir(path)  # 列出文件夹下所有的目录与文件
        self.image_filename_list.clear()
        for i in range(0, len(name_list)):
            if name_list[i].endswith(
                    ".jpg") or name_list[i].endswith(".png"):
                self.image_filename_list.append(name_list[i])

    def fill_table_with_new_info(self):
        self.hyperlpr_tableview.clearContents()
        row_count = self.hyperlpr_tableview.rowCount()
        for i in range(row_count, -1, -1):
            self.hyperlpr_tableview.removeRow(i)

        for i in range(0, len(self.image_filename_list)):
            row = self.hyperlpr_tableview.rowCount()
            self.hyperlpr_tableview.insertRow(row)

            item0 = QTableWidgetItem()
            item0.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 0, item0)
            self.hyperlpr_tableview.item(
                row, 0).setText(
                self.image_filename_list[i])

            item1 = QTableWidgetItem()
            item1.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 1, item1)

            item2 = QTableWidgetItem()
            item2.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 2, item2)

            item3 = QTableWidgetItem()
            item3.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 3, item3)

            item4 = QTableWidgetItem()
            item4.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 4, item4)

            item5 = QTableWidgetItem()
            item5.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 5, item5)

        if len(self.image_filename_list) > 0:
            self.left_button.setEnabled(True)
            self.right_button.setEnabled(True)
            self.save_as_e2e_filename_button.setEnabled(True)

    def analyze_last_one_image(self):
        if self.current_row > 0:
            self.recognize_one_license_plate(self.current_row-1, 0)

    def analyze_next_one_image(self):
        if self.current_row < (len(self.image_filename_list)-1):
            self.recognize_one_license_plate(self.current_row + 1, 0)

    def recognize_one_license_plate(self, row, col):
        if col == 0 and row < len(self.image_filename_list):
            self.current_row = row
            self.recognize_and_show_one_image(
                self.image_filename_list[row], row)

    def recognize_and_show_one_image(self, image_filename_text, row):

        if image_filename_text.endswith(".jpg"):

            print(image_filename_text)
            path = os.path.join(self.hyperlpr_dir_path, image_filename_text)
            image = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)
            image, res_set = SimpleRecognizePlateWithGui(image)
            img = QImage(
                image.data,
                image.shape[1],
                image.shape[0],
                image.shape[1] * image.shape[2],
                QImage.Format_RGB888)
            self.image_window_view.resetPixmap(img.rgbSwapped())
            self.image_window_view.resetRectText(res_set)

            if len(res_set) > 0:
                curr_rect = res_set[0][2]
                image_crop = image[int(curr_rect[1]):int(
                    curr_rect[1] + curr_rect[3]), int(curr_rect[0]):int(curr_rect[0] + curr_rect[2])]
                curr_plate = cv2.resize(image_crop, (204, 108))
                plate_img = QImage(
                    curr_plate.data,
                    curr_plate.shape[1],
                    curr_plate.shape[0],
                    curr_plate.shape[1] *
                    curr_plate.shape[2],
                    QImage.Format_RGB888)
                self.license_plate_widget.setPixmap(
                    QPixmap.fromImage(plate_img.rgbSwapped()))

                # print(res_set[0][6])
                block_crop = image[0:24, 0:(24 * int(res_set[0][6]))]
                curr_block = cv2.resize(
                    block_crop, (24 * int(res_set[0][6]), 24))
                block_image = QImage(
                    curr_block.data,
                    curr_block.shape[1],
                    curr_block.shape[0],
                    curr_block.shape[1] *
                    curr_block.shape[2],
                    QImage.Format_RGB888)
                self.block_plate_widget.setPixmap(
                    QPixmap.fromImage(block_image.rgbSwapped()))

                self.segmentation_recognition_edit.setText(res_set[0][0])
                if res_set[0][0] in image_filename_text:
                    self.segmentation_recognition_edit.setStyleSheet("color:black")
                else:
                    self.segmentation_recognition_edit.setStyleSheet("color:red")


                self.filename_edit.setText(image_filename_text)
                self.confidence_edit.setText("%.3f" % (float(res_set[0][1])))

                self.plate_color_edit.setText(res_set[0][3])
                if res_set[0][3] in image_filename_text:
                    self.plate_color_edit.setStyleSheet("color:black")
                else:
                    self.plate_color_edit.setStyleSheet("color:red")

                self.e2e_recognization_edit.setText(res_set[0][4])
                if res_set[0][4] in image_filename_text:
                    self.e2e_recognization_edit.setStyleSheet("color:black")
                else:
                    self.e2e_recognization_edit.setStyleSheet("color:red")

                self.e2e_confidence_edit.setText(
                    "%.3f" % (float(res_set[0][5])))
            else:
                self.license_plate_widget.clear()
                self.block_plate_widget.clear()
                self.segmentation_recognition_edit.setText("")
                self.filename_edit.setText(image_filename_text)
                self.confidence_edit.setText("")
                self.plate_color_edit.setText("")
                self.e2e_recognization_edit.setText("")
                self.e2e_confidence_edit.setText("")

            self.fill_table_widget_with_res_info(res_set, row)

    def batch_recognize_all_images(self):
        self.segmentation_recognition_correct_number = 0
        self.color_correct_number = 0
        self.e2e_recognization_correct_number = 0
        self.batch_recognization_thread.set_parameter(
            self.image_filename_list, self.hyperlpr_dir_path)

    def recognization_done_slot(self, result_list):
        row = result_list[0]
        res_set = result_list[1]
        self.fill_table_widget_with_res_info(res_set, row)

        if row == len(self.image_filename_list) - 1:
            total_number = len(self.image_filename_list)

            row_count = self.hyperlpr_tableview.rowCount()
            if row_count > total_number:
                self.hyperlpr_tableview.removeRow(total_number)

            self.hyperlpr_tableview.insertRow(total_number)

            item0 = QTableWidgetItem()
            item0.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 0, item0)
            self.hyperlpr_tableview.item(
                total_number, 0).setText(
                "统计结果")

            item1 = QTableWidgetItem()
            item1.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 1, item1)
            self.hyperlpr_tableview.item(
                total_number,
                1).setText(
                "{0} / {1} = {2: .3f}".format(
                    self.segmentation_recognition_correct_number,
                    total_number,
                    self.segmentation_recognition_correct_number /
                    total_number))

            item2 = QTableWidgetItem()
            item2.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 2, item2)

            item3 = QTableWidgetItem()
            item3.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 3, item3)
            self.hyperlpr_tableview.item(
                total_number, 3).setText(
                "{0} / {1} = {2: .3f}".format(self.e2e_recognization_correct_number, total_number,
                                              self.e2e_recognization_correct_number / total_number))

            item4 = QTableWidgetItem()
            item4.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 4, item4)
            self.hyperlpr_tableview.item(
                total_number, 4).setText(
                "{0} / {1} = {2: .3f}".format(self.color_correct_number, total_number,
                                              self.color_correct_number / total_number))

            item5 = QTableWidgetItem()
            item5.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 5, item5)

    def fill_table_widget_with_res_info(self, res_set, row):
        image_filename_text = self.image_filename_list[row]
        if len(res_set) > 0:

            self.hyperlpr_tableview.item(row, 1).setText(res_set[0][0])
            if res_set[0][0] in image_filename_text:
                self.hyperlpr_tableview.item(
                    row, 1).setForeground(
                    QBrush(
                        QColor(
                            0, 0, 255)))
                self.segmentation_recognition_correct_number += 1
            else:
                self.hyperlpr_tableview.item(
                    row, 1).setForeground(
                    QBrush(
                        QColor(
                            255, 0, 0)))

            self.hyperlpr_tableview.item(
                row, 2).setText(
                "%.3f" %
                (float(
                    res_set[0][1])))

            self.hyperlpr_tableview.item(row, 3).setText(res_set[0][3])
            if res_set[0][3] in image_filename_text:
                self.hyperlpr_tableview.item(
                    row, 3).setForeground(
                    QBrush(
                        QColor(
                            0, 0, 255)))
                self.color_correct_number += 1
            else:
                self.hyperlpr_tableview.item(
                    row, 3).setForeground(
                    QBrush(
                        QColor(
                            255, 0, 0)))

            self.hyperlpr_tableview.item(row, 4).setText(res_set[0][4])
            if res_set[0][4] in image_filename_text:
                self.hyperlpr_tableview.item(
                    row, 4).setForeground(
                    QBrush(
                        QColor(
                            0, 0, 255)))
                self.e2e_recognization_correct_number += 1
            else:
                self.hyperlpr_tableview.item(
                    row, 4).setForeground(
                    QBrush(
                        QColor(
                            255, 0, 0)))

            self.hyperlpr_tableview.item(
                row, 5).setText(
                "%.3f" %
                (float(
                    res_set[0][5])))
Ejemplo n.º 14
0
class Labels(QWidget):
    """
    Attributes
    ----------
    chan_name : list of str
        list of all the labels (with the user-defined changes)
    """
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.filename = None
        self.chan_name = None  # None when dataset is not loaded

        self.create()

    def create(self):

        self.idx_load = QPushButton('Load')
        self.idx_load.clicked.connect(self.load_labels)
        self.idx_load.setToolTip('Load file with a list of channels (separated by , or ; or tabs or spaces).')
        self.idx_save = QPushButton('Save')
        self.idx_save.clicked.connect(self.save_labels)
        self.idx_save.setEnabled(False)

        # cancel is equal to setting labels to what they were
        self.idx_cancel = QPushButton('Cancel')
        self.idx_cancel.clicked.connect(self.update)
        self.idx_apply = QPushButton('Apply')
        self.idx_apply.clicked.connect(self.apply)
        self.idx_apply.setToolTip('Changes will take effect. This will reset the channel groups and traces.')

        layout_0 = QHBoxLayout()
        layout_0.addWidget(self.idx_load)
        layout_0.addWidget(self.idx_save)

        layout_1 = QHBoxLayout()
        layout_1.addWidget(self.idx_cancel)
        layout_1.addWidget(self.idx_apply)

        self.table = QTableWidget()

        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setColumnCount(2)
        self.table.setHorizontalHeaderLabels(['Current Labels', 'New Labels'])

        self.table.cellChanged.connect(self.check_labels)

        layout = QVBoxLayout()
        layout.addLayout(layout_0)
        layout.addWidget(self.table)
        layout.addLayout(layout_1)

        self.setLayout(layout)

        self.setEnabled(False)

    def update(self, checked=False, labels=None, custom_labels=None):
        """Use this function when we make changes to the list of labels or when
        we load a new dataset.

        Parameters
        ----------
        checked : bool
            argument from clicked.connect
        labels : list of str
            list of labels in the dataset (default)
        custom_labels : list of str
            list of labels from a file
        """
        if labels is not None:
            self.setEnabled(True)
            self.chan_name = labels

        self.table.blockSignals(True)
        self.table.clearContents()
        self.table.setRowCount(len(self.chan_name))

        for i, label in enumerate(self.chan_name):
            old_label = QTableWidgetItem(label)
            old_label.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)

            if custom_labels is not None and i < len(custom_labels) and custom_labels[i]:  # it's not empty string or None
                label_txt = custom_labels[i]
            else:
                label_txt = label
            new_label = QTableWidgetItem(label_txt)

            self.table.setItem(i, 0, old_label)
            self.table.setItem(i, 1, new_label)

        self.table.blockSignals(False)

    def check_labels(self):

        # read new labels first
        labels = self._read_labels()

        # disable apply, if there are duplicates
        if len(labels) == len(set(labels)):
            self.idx_apply.setEnabled(True)
        else:
            self.idx_apply.setEnabled(False)

        # mark duplicates in red
        self.table.blockSignals(True)
        for i, label in enumerate(labels):
            if labels.count(label) > 1:
                 self.table.item(i, 1).setBackground(QColor('red'))
            else:
                 self.table.item(i, 1).setBackground(QColor('white'))
        self.table.blockSignals(False)

    def load_labels(self, checked=False, test_name=None):
        if self.filename is not None:
            filename = self.filename
        elif self.parent.info.filename is not None:
            filename = Path(self.parent.info.filename)
        else:
            filename = None

        if test_name:
            filename = test_name
        else:
            filename, _ = QFileDialog.getOpenFileName(self,
                                                      'Open Labels',
                                                      str(filename.parent),
                                                      'Comma-separated values (*.csv);; Text file (*.txt);; All Files(*.*)')
        if filename == '':
            return

        self.filename = Path(filename)

        with self.filename.open() as f:
            text = f.read()

        labels = split(', |,|; |;|\t|\n| ',text)
        labels  = [label.strip() for label in labels]
        self.update(custom_labels=labels)

    def save_labels(self):
        """Save labels modified by the user.

        TODO
        ----
        Save labels modified by the user
        """
        pass

    def apply(self):

        self.chan_name = self._read_labels()
        self.parent.info.dataset.header['chan_name'] = self.chan_name

        self.parent.channels.reset()
        self.parent.traces.reset()

    def reset(self):
        self.table.blockSignals(True)
        self.table.clearContents()
        self.table.blockSignals(False)

        self.setEnabled(False)

    def _read_labels(self):

        labels = []
        for i in range(self.table.rowCount()):
            labels.append(self.table.item(i, 1).text())

        return labels
Ejemplo n.º 15
0
class PairingsWidget(QWidget):
	def __init__(self, parent):
		super(PairingsWidget, self).__init__(parent)
		self.parent = parent

		view.notifier.observers.append(self)

		self.header_label = QLabel('Pairings')

		self.header_widget = QWidget(self)
		header_layout = QBoxLayout(QBoxLayout.TopToBottom)
		header_layout.addWidget(self.header_label)
		self.header_widget.setLayout(header_layout)

		self.pairings_list = QTableWidget(style.style_loader.TABLE_INITIAL_LENGTH, 2, self)
		self.pairings_list.setFixedHeight(300)
		self.pairings_list.setFixedWidth(400)
		self.pairings_list.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
		self.pairings_list.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)

		self.pairings_list_widget = QWidget(self)
		pairings_list_layout = QBoxLayout(QBoxLayout.LeftToRight)
		pairings_list_layout.addWidget(self.pairings_list)
		self.pairings_list_widget.setLayout(pairings_list_layout)

		self.report_btn = QPushButton('Report Results', self)
		self.report_btn.clicked.connect(parent.show_report_result_widget)

		self.report_btn_widget = QWidget(self)
		report_btn_layout = QBoxLayout(QBoxLayout.LeftToRight)
		report_btn_layout.addWidget(self.report_btn)
		self.report_btn_widget.setLayout(report_btn_layout)

		layout = QFormLayout()
		layout.addRow(self.header_widget)
		layout.addRow(self.pairings_list_widget)
		layout.addRow(self.report_btn_widget)
		self.setLayout(layout)

		self.update()

	def update(self):
		self.pairings_list.clearContents()

		index = 0
		for p1, p2 in to.pairings.items():
			if index == self.pairings_list.rowCount():
				self.pairings_list.insertRow(index)
			p1_item = QTableWidgetItem(p1)
			p1_item.setFlags(p1_item.flags() & ~Qt.ItemIsEditable)
			self.pairings_list.setItem(index, 0, p1_item)
			if p2 == None:
				p2_str = '--BYE--'
			else:
				p2_str = p2
			p2_item = QTableWidgetItem(p2_str)
			p2_item.setFlags(p2_item.flags() & ~Qt.ItemIsEditable)
			self.pairings_list.setItem(index, 1, p2_item)
			index += 1
		self.pairings_list.show()

	def player_added(self, player, user):
		pass

	def player_removed(self, player):
		pass

	def pairings_created(self):
		self.update()
		self.parent.show()

	def report_result(self, player, record, win_loss_draw):
		try:
			if win_loss_draw == 'win':
				to.record_win(player, record)
			elif win_loss_draw == 'loss':
				to.record_loss(player, record)
			elif win_loss_draw == 'draw':
				to.record_draw(player, record)
			view.notifier.result_reported()
		except TournamentException as ex:
			self.error = ErrorMessage(str(ex), '')
			self.error.setStyleSheet(style.style_loader.stylesheet)
			self.error.show()

	def result_reported(self):
		self.update()
		self.parent.show()

	def reset(self):
		self.update()
		self.parent.show()
Ejemplo n.º 16
0
class ModeTabWidget(QWidget):
    """
    This class describes the placement of widgets in the Mode 1 tab
    """
    def __init__(self, globalData):
        super().__init__()
        
        self.tVec = []
        self.kVec = []
        self.globalData = globalData

        #self.layout = QHBoxLayout(self)
        layout = QGridLayout(self)
        layout.setColumnStretch(1, 2)
        layout.setColumnStretch(2, 2)
        self.tableWidget = QTableWidget()
        self.tableWidget.setRowCount(4)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setHorizontalHeaderLabels(['Dummy','Dummy'])
        self.tableWidget.horizontalHeader().setSectionResizeMode(1, QHeaderView.Stretch)
        
        layout.addWidget(self.tableWidget,1,1)

        self.buttonPanel = QVBoxLayout()
        self.buttonPanel.addWidget(self.addDataButtons())
        #self.buttonPanel.addWidget(self.addExternalDataButtons())
        self.buttonPanel.addWidget(self.addComputationButtons())
        layout.addLayout(self.buttonPanel,1,2)

        
    
    def addExternalDataButtons(self):
        buttonGroupBox = QGroupBox("Import/Export data", self)
        buttonLayout = QVBoxLayout()
        buttons = []

        self.importDataButton = QPushButton('Import Data')
        self.importDataButton.setToolTip('Imports failure data')
        self.importDataButton.clicked.connect(self.importData)
        buttons.append(self.importDataButton)

        self.saveDataButton = QPushButton('Save Data')
        self.saveDataButton.setToolTip('Saves data in the table failure data')
        self.saveDataButton.clicked.connect(self.saveData)
        buttons.append(self.saveDataButton)

        for button in buttons:
            buttonLayout.addWidget(button)
            #buttonLayout.setAlignment(button, Qt.AlignTop)
        buttonLayout.addStretch(1)
        buttonGroupBox.setLayout(buttonLayout)
        return buttonGroupBox

    def addComputationButtons(self):
        buttonGroupBox = QGroupBox("Computation", self)
        buttonLayout = QVBoxLayout()
        buttons = []
        
        self.computeButton = QPushButton('Compute')
        self.computeButton.setToolTip('Starts the computation')
        self.computeButton.clicked.connect(self.compute)
        buttons.append(self.computeButton)
        
        for button in buttons:
            buttonLayout.addWidget(button)
        
        buttonLayout.addStretch(1)
        buttonGroupBox.setLayout(buttonLayout)
        return buttonGroupBox


    def addDataButtons(self):
        
        buttonGroupBox = QGroupBox("Data Manipulation", self)
        buttonLayout = QVBoxLayout()
        buttons = []
        self.addRowButton = QPushButton('Add Row')
        self.addRowButton.setToolTip('Adds a row to the end of the table')
        self.addRowButton.clicked.connect(self.addRow)
        buttons.append(self.addRowButton)

        self.insertRowButton = QPushButton('Insert Row')
        self.insertRowButton.setToolTip('Inserts Row above the selected row')
        self.insertRowButton.clicked.connect(self.insertRow)
        buttons.append(self.insertRowButton)

        self.deleteRowsButton = QPushButton('Delete Row')
        self.deleteRowsButton.setToolTip('Deletes selected row')
        self.deleteRowsButton.clicked.connect(self.deleteRows)
        buttons.append(self.deleteRowsButton)

        self.clearRowsButton = QPushButton('Clear All')
        self.clearRowsButton.setToolTip('Clears all rows')
        self.clearRowsButton.clicked.connect(self.clearRows)
        buttons.append(self.clearRowsButton)

        for button in buttons:
            buttonLayout.addWidget(button)
            #buttonLayout.setAlignment(button, Qt.AlignTop)
        buttonLayout.addStretch(1)
        buttonGroupBox.setLayout(buttonLayout)
        return buttonGroupBox
        
    def compute(self):
        """
        This function is run when the compute button is clicked
        #Verify data and start computation
        """
        print("Compute!")
        data = self.getTableData()


    def saveAndDisplayResults(self, weibull):
        print("Save and display results")


    def importData(self):
        fileName = QFileDialog.getOpenFileName(self, 'Open File','.')
        data = utils.import_data(fileName)
        self.setGlobalData(data)
        self.populateTable(data)
        

    def setGlobalData(self, data):
        print("Please override this function to set the global data for the particular mode")
        self.globalData.input[self.modex] = data

    
    def clearRows(self):
        d = QDialog()
        buttons = QDialogButtonBox(
                        QDialogButtonBox.Ok | QDialogButtonBox.Cancel,
                        Qt.Horizontal, self)
        buttons.accepted.connect(d.accept)
        buttons.rejected.connect(d.reject)

        msgLabel = QLabel("Warning: Data from all rows will be cleared. This cannot be undone. Proceed?")
        d.layout = QVBoxLayout(d)
        d.layout.addWidget(msgLabel)
        d.layout.addWidget(buttons)
        d.setWindowTitle("Clear All Rows")

        if d.exec_() == QDialog.Accepted:
            self.tableWidget.clearContents()

    
    def deleteRows(self):
        self.tableWidget.removeRow(self.tableWidget.currentRow())
        self.tableChanged(0, 0)

    def addRow(self):
        self.tableWidget.insertRow(self.tableWidget.rowCount())
        self.tableChanged(0, 0)

    def insertRow(self):
        self.tableWidget.insertRow(self.tableWidget.currentRow())
        self.tableChanged(0, 0)

    def saveData(self):
        fileName = QFileDialog.getSaveFileName(self, 'Save Data', '.', initialFilter='*.csv')
        data = self.getTableData()
        if fileName:
            utils.export_data(data, fileName)

    def getTableData(self):
        data = []
        for i in range(self.tableWidget.rowCount()):
            try:
                if self.tableWidget.item(i,0) != None:
                    data.append((self.tableWidget.item(i,0).text(), float(self.tableWidget.item(i,1).text())))
            except:
                print("Unexpected error:", sys.exc_info()[0])
                raise
        print(data)
        return data
Ejemplo n.º 17
0
class VentanaAreas(QtWidgets.QDialog):
    def __init__(self, pluginDFS, parent=iface.mainWindow()):
        super(VentanaAreas, self).__init__(parent)

        #self.parent = iface.mainWindow()
        self.contenedor = QVBoxLayout()
        self.setLayout(self.contenedor)
        self.tablaAreas = QTableWidget()
        self.tablaAreas.setColumnCount(1)
        self.pluginDFS = pluginDFS
        self.contenedor.addWidget(self.tablaAreas)

        #self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)

        estilo = """
QWidget{
background : rgb(250,238,224)
}
QPushButton{
background : rgb(174, 116, 0);
color : rgb(255, 255, 255);
border-radius : 4px;
}
QPushButton::hover{
background : rgb(104, 69, 13);
color : rgb(255, 255, 255);
border-radius : 2px;
}
QTableWidget{
background : rgb(255,255,255);
}
"""

        self.setStyleSheet(estilo)

#----------------------------------------------------------------

    def mostrarAreas(self):
        self.limpiarTabla()

        rango = len(self.pluginDFS.geomsAreas) - 1

        for x in range(0, rango):

            self.tablaAreas.insertRow(x)
            area = "%.2f" % self.pluginDFS.geomsAreas[x].area()

            string = str(area) + ' m2'
            item = QtWidgets.QTableWidgetItem(string)
            self.tablaAreas.setItem(
                x, 0, item)  #self.capaActual.getFeatures().attributes()[x])
            item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
            color = self.pluginDFS.listaColores[x]
            self.tablaAreas.item(x, 0).setBackground(color)

        header = self.tablaAreas.horizontalHeader()
        header.setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
        self.tablaAreas.setHorizontalHeaderItem(
            0, QTableWidgetItem('Area (Metros cuadrados)'))
        self.show()

#--------------------------------------------------------

    def limpiarTabla(self):
        self.tablaAreas.clearContents()
        self.tablaAreas.setRowCount(0)

        for row in range(0, self.tablaAreas.rowCount()):
            self.tablaAreas.removeRow(row)

#---------------------------------------------------

    def closeEvent(self, evnt):
        self.pluginDFS.quitarAreas()
class BarcodeTable(QGroupBox):
    """ GUI component. Displays a list of barcodes for the currently selected puck.
    """
    def __init__(self, options):
        super(BarcodeTable, self).__init__()

        self._options = options

        self.setTitle("Plate Barcodes")
        self.setMaximumWidth(160)
        self.setMinimumWidth(260)
        self._init_ui()
        self.clear()

    def _init_ui(self):
        # Plate being displayed
        self._plate_lbl = QLabel()

        # Create barcode table - lists all the barcodes in a record
        self._table = QTableWidget()
        self._table.setMinimumWidth(70)
        self._table.setMinimumHeight(600)
        self._table.setColumnCount(1)
        self._table.setRowCount(10)
        self._table.setHorizontalHeaderLabels(['Barcode'])
        self._table.setMinimumWidth(200)

        # Clipboard button - copy the selected barcodes to the clipboard
        self._btn_clipboard = QPushButton('Copy To Clipboard')
        self._btn_clipboard.setToolTip(
            'Copy barcodes for the selected record to the clipboard')
        self._btn_clipboard.resize(self._btn_clipboard.sizeHint())
        self._btn_clipboard.clicked.connect(self.copy_to_clipboard)

        hbox = QHBoxLayout()
        hbox.setSpacing(10)
        hbox.addWidget(self._btn_clipboard)
        hbox.addStretch(1)

        vbox = QVBoxLayout()
        vbox.addWidget(self._plate_lbl)
        vbox.addWidget(self._table)
        vbox.addLayout(hbox)

        self.setLayout(vbox)

    def populate(self, holder_barcode, barcodes):
        """ Called when a new row is selected on the record table.
        """
        self._holder_barcode = holder_barcode
        self._barcodes = barcodes[:]
        self._update_state()

    def clear(self):
        self._holder_barcode = None
        self._barcodes = []
        self._update_state()

    def _update_state(self):
        self._populate_table()
        self._update_button_state()
        self._update_plate_label()

    def _populate_table(self):
        """Displays all of the barcodes from the selected record in the barcode table. By default, valid barcodes are
        highlighted green, invalid barcodes are highlighted red, and empty slots are grey.
        """
        self._table.clearContents()
        self._table.setRowCount(len(self._barcodes))

        for index, barcode in enumerate(self._barcodes):
            if barcode == NOT_FOUND_SLOT_SYMBOL:
                cell_color = self._options.col_bad()
            elif barcode == EMPTY_SLOT_SYMBOL:
                cell_color = self._options.col_empty()
            else:
                cell_color = self._options.col_ok()

            cell_color.a = 192

            # Set table item
            barcode = QTableWidgetItem(barcode)
            barcode.setBackground(cell_color.to_qt())
            barcode.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self._table.setItem(index, 0, barcode)

    def _update_button_state(self):
        self._btn_clipboard.setEnabled(self._has_barcodes())

    def copy_to_clipboard(self):
        """ Called when the copy to clipboard button is pressed. Copies the list/s of
        barcodes for the currently selected records to the clipboard so that the user
        can paste it elsewhere.
        """
        if self._holder_barcode is None:
            self._holder_barcode = NOT_FOUND_SLOT_SYMBOL
        clipboard_barcodes = [self._holder_barcode] + self._barcodes[:]
        for i, barcode in enumerate(clipboard_barcodes):
            if barcode in [NOT_FOUND_SLOT_SYMBOL, EMPTY_SLOT_SYMBOL]:
                clipboard_barcodes[i] = ""

        sep = os.linesep
        if clipboard_barcodes:
            import pyperclip
            pyperclip.copy(sep.join(clipboard_barcodes))

    def _update_plate_label(self):
        barcode_holder = str(self._holder_barcode)
        text = "Plate : " + barcode_holder if self._has_barcodes(
        ) else "Plate:"
        myFont = QtGui.QFont()
        myFont.setBold(True)
        self._plate_lbl.setFont(myFont)
        self._plate_lbl.setText(text)

    def _has_barcodes(self):
        return self._barcodes is not None and len(self._barcodes) > 0
class UserManagerWidget(QWidget):
	def __init__(self, parent):
		super(UserManagerWidget, self).__init__(parent)
		self.parent = parent

		self.sort_order = 'by_name'

		view.notifier.observers.append(self)

		self.header_label = QLabel('Users')

		self.header_widget = QWidget(self)
		header_layout = QBoxLayout(QBoxLayout.LeftToRight)
		header_layout.addWidget(self.header_label)
		self.header_widget.setLayout(header_layout)

		self.sort_by_name_btn = QPushButton('Sort by Name', self)
		self.sort_by_name_btn.clicked.connect(self.sort_by_name)
		self.sort_by_rank_btn = QPushButton('Sort by Rank', self)
		self.sort_by_rank_btn.clicked.connect(self.sort_by_rank)

		self.sort_btns_widget = QWidget(self)
		sort_btns_layout = QBoxLayout(QBoxLayout.LeftToRight)
		sort_btns_layout.addWidget(self.sort_by_name_btn)
		sort_btns_layout.addSpacing(10)
		sort_btns_layout.addWidget(self.sort_by_rank_btn)
		self.sort_btns_widget.setLayout(sort_btns_layout)

		self.user_list = QTableWidget(style.style_loader.TABLE_INITIAL_LENGTH, 3, self)
		self.user_list.setFixedHeight(300)
		self.user_list.setFixedWidth(400)
		self.user_list.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
		self.user_list.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)

		self.user_list_widget = QWidget(self)
		user_list_layout = QBoxLayout(QBoxLayout.LeftToRight)
		user_list_layout.addWidget(self.user_list)
		self.user_list_widget.setLayout(user_list_layout)

		self.add_player_btn = QPushButton('Add User', self)
		self.add_player_btn.clicked.connect(self.parent.show_add_user_widget)
		self.remove_player_btn = QPushButton('Remove User', self)
		self.remove_player_btn.clicked.connect(self.parent.show_remove_user_widget)

		self.player_btns_widget = QWidget(self)
		player_btn_layout = QBoxLayout(QBoxLayout.LeftToRight)
		player_btn_layout.addWidget(self.add_player_btn)
		player_btn_layout.addSpacing(10)
		player_btn_layout.addWidget(self.remove_player_btn)
		self.player_btns_widget.setLayout(player_btn_layout)

		self.error = None

		layout = QFormLayout()
		layout.addRow(self.header_widget)
		layout.addRow(self.sort_btns_widget)
		layout.addRow(self.user_list_widget)
		layout.addRow(self.player_btns_widget)
		self.setLayout(layout)

		self.update()

	def update(self):
		self.user_list.clearContents()
		# TODO: get the most recent user list
		users = um.users()

		index = 0
		for user in users:
			if index == self.user_list.rowCount():
				self.user_list.insertRow(index)
			name_item = QTableWidgetItem(user.name)
			name_item.setFlags(name_item.flags() & ~Qt.ItemIsEditable)
			self.user_list.setItem(index, 0, name_item)
			id_item = QTableWidgetItem(str(user.id))
			id_item.setFlags(id_item.flags() & ~Qt.ItemIsEditable)
			self.user_list.setItem(index, 1, id_item)
			record_item = QTableWidgetItem(user.record_str())
			record_item.setFlags(record_item.flags() & ~Qt.ItemIsEditable)
			self.user_list.setItem(index, 2, record_item)
			index += 1
		self.user_list.show()

	def sort_by_name(self):
		self.sort_order = 'by_name'
		self.update()

	def sort_by_rank(self):
		self.sort_order = 'by_rank'
		self.update()

	def player_added(self, player, user):
		self.update()

	def player_removed(self, player):
		self.update()

	def report_result(self, player, record, win_or_draw):
		pass

	def result_reported(self):
		self.update()

	def pairings_created(self):
		self.update()

	def reset(self):
		self.update()
Ejemplo n.º 20
0
class ObjectSelector(QWidget):
    def __init__(self, *args):
        super().__init__(*args)

        # Set size & position.
        screen = QtWidgets.QDesktopWidget().screenGeometry(0)
        self.resize(int(screen.width() * 0.7), int(screen.height() * 0.7))
        self.move(int(screen.width() * 0.15), int(screen.height() * 0.15))

        # Set window type.
        flags = QtCore.Qt.WindowFlags(QtCore.Qt.WindowStaysOnTopHint
                                      | QtCore.Qt.FramelessWindowHint)
        self.setWindowFlags(flags)

        self.layout = QVBoxLayout()
        self.layout.setContentsMargins(50, 50, 50, 50)

        self.omnibox = QHBoxLayout()
        self.omnibox.setContentsMargins(20, 20, 20, 20)
        self.omnitext = QLineEdit()
        self.omnitext.setStyleSheet(
            "QLineEdit { font-size: 20px; padding: 12px; border: none; border-radius: 10px; }"
        )
        self.omnitext.setFrame(False)  # Doesn't seem to do anything'
        self.omnitext.setAttribute(QtCore.Qt.WA_MacShowFocusRect, False)
        self.omnitext.setPlaceholderText("Search ...")
        self.omnitext.setClearButtonEnabled(True)
        self.omnitext.setTextMargins(20, 20, 20, 20)
        self.omnibox.addWidget(self.omnitext)
        self.layout.addLayout(self.omnibox)

        # Here I'm going to start with the list of objects from
        # the history service.  This will need to be completely
        # rejigged in future.

        # So, a table ... date/time, event, type, details of object.
        #
        # The object details will be the tricky bit: objects don't
        # have to have a name or anything.  Perhaps it'd be good for
        # the type implementation to have a method to get a description
        # of the object in a type-specific way?

        self.object_table = QTableWidget(10, 4, self)
        self.object_table.setHorizontalHeaderLabels(
            ("Date / Time", "Type", "Event", "Object"))
        self.object_table.verticalHeader().setVisible(False)
        self.object_table.setContentsMargins(20, 20, 20, 20)
        for r in range(10):
            for c in (0, 1, 2, 3):
                item = QTableWidgetItem()
                item.setText(
                    ["datetime", "type", "event", "description of object"][c])
                self.object_table.setItem(r, c, item)
        self.layout.addWidget(self.object_table)

        self.setLayout(self.layout)
        self.hide()

        self.history = History.api()
        return

    def show(self):

        # FIXME: needs a lot more work here ...
        # Populate history list
        self.object_table.clearContents()

        now = datetime.utcnow()
        history = self.history.get_events(now, 100, True)

        r = 0
        for event in history:
            for c in range(4):
                item = QTableWidgetItem()
                item.setText([event[0], "type", event[2], event[1]][c])
                self.object_table.setItem(r, c, item)
            r += 1

        super().show()
        return

    def hide(self):
        super().hide()
        return

    def toggle_visibility(self):
        """Show if hidden; hide if shown"""
        if self.isVisible():
            self.hide()
        else:
            self.show()
        return
Ejemplo n.º 21
0
class LabelAssistDialog(QDialog):
    """
    A simple UI for showing bookmarks and navigating to them.

    FIXME: For now, this window is tied to a particular lane.
           If your project has more than one lane, then each one
           will have it's own bookmark window, which is kinda dumb.
    """
    def __init__(self, parent, topLevelOperatorView):
        super(LabelAssistDialog, self).__init__(parent)
        
        # Create thread router to populate table on main thread
        self.threadRouter = ThreadRouter(self)
        
        # Set object classification operator view
        self.topLevelOperatorView = topLevelOperatorView
        
        self.setWindowTitle("Label Assist")
        self.setMinimumWidth(500)
        self.setMinimumHeight(700)

        layout = QGridLayout() 
        layout.setContentsMargins(10, 10, 10, 10)
                       
        # Show variable importance table
        rows = 0
        columns = 4
        self.table = QTableWidget(rows, columns)   
        self.table.setHorizontalHeaderLabels(['Frame', 'Max Area', 'Min Area', 'Labels'])
        self.table.verticalHeader().setVisible(False)     
        
        # Select full row on-click and call capture double click
        self.table.setSelectionBehavior(QTableView.SelectRows);
        self.table.doubleClicked.connect(self._captureDoubleClick)
                
        layout.addWidget(self.table, 1, 0, 3, 2) 

        # Create progress bar
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(0)
        self.progressBar.hide()
        layout.addWidget(self.progressBar, 4, 0, 1, 2)

        # Create button to populate table
        self.computeButton = QPushButton('Compute object info')
        self.computeButton.clicked.connect(self._triggerTableUpdate)
        layout.addWidget(self.computeButton, 5, 0)
        
        # Create close button
        closeButton = QPushButton('Close')
        closeButton.clicked.connect(self.close)
        layout.addWidget(closeButton, 5, 1)
        
        # Set dialog layout
        self.setLayout(layout)       


    def _triggerTableUpdate(self):
        # Check that object area is included in selected features
        featureNames = self.topLevelOperatorView.SelectedFeatures.value
        
        if 'Standard Object Features' not in featureNames or 'Count' not in featureNames['Standard Object Features']:
            box = QMessageBox(QMessageBox.Warning,
                  'Warning',
                  'Object area is not a selected feature. Please select this feature on: \"Standard Object Features > Shape > Size in pixels\"',
                  QMessageBox.NoButton,
                  self)
            box.show()
            return 
        
        # Clear table
        self.table.clearContents()
        self.table.setRowCount(0)
        self.table.setSortingEnabled(False)
        self.progressBar.show()
        self.computeButton.setEnabled(False)

        def compute_features_for_frame(tIndex, t, features): 
            # Compute features and labels (called in parallel from request pool)
            roi = [slice(None) for i in range(len(self.topLevelOperatorView.LabelImages.meta.shape))]
            roi[tIndex] = slice(t, t+1)
            roi = tuple(roi)

            frame = self.topLevelOperatorView.SegmentationImages(roi).wait()           
            frame = frame.squeeze().astype(numpy.uint32, copy=False)
            
            # Dirty trick: We don't care what we're passing here for the 'image' parameter,
            # but vigra insists that we pass *something*, so we'll cast the label image as float32.
            features[t] = vigra.analysis.extractRegionFeatures(frame.view(numpy.float32),
                                                               frame,
                                                               ['Count'],
                                                               ignoreLabel=0)
            
        tIndex = self.topLevelOperatorView.SegmentationImages.meta.axistags.index('t')
        tMax = self.topLevelOperatorView.SegmentationImages.meta.shape[tIndex]     
        
        features = {}
        labels = {}

        def compute_all_features():
            # Compute features in parallel
            pool = RequestPool()
            for t in range(tMax):
                pool.add( Request( partial(compute_features_for_frame, tIndex, t, features) ) )
            pool.wait()
            
        # Compute labels
        labels = self.topLevelOperatorView.LabelInputs([]).wait()
            
        req = Request(compute_all_features)
        req.notify_finished( partial(self._populateTable, features, labels) )
        req.submit()

    @threadRouted
    def _populateTable(self, features, labels, *args):
        self.progressBar.hide()
        self.computeButton.setEnabled(True)
                
        for time, feature in features.items():
            # Insert row
            rowNum = self.table.rowCount()
            self.table.insertRow(self.table.rowCount())
            
            # Get max and min object areas
            areas = feature['Count']#objectFeatures['Standard Object Features']['Count']
            maxObjArea = numpy.max(areas[numpy.nonzero(areas)])
            minObjArea = numpy.min(areas[numpy.nonzero(areas)])
            
            # Get number of labeled objects
            labelNum = numpy.count_nonzero(labels[time])
            
            # Load fram number
            item = QTableWidgetItem(str(time))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 0, item) 

            # Load max object areas
            item = QTableWidgetItemWithFloatSorting(str("{: .02f}".format(maxObjArea)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 1, item)
                
            # Load min object areas
            item = QTableWidgetItemWithFloatSorting(str("{: .02f}".format(minObjArea)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 2, item)
            
            # Load label numbers
            item = QTableWidgetItemWithFloatSorting(str("{: .01f}".format(labelNum)))
            item.setFlags( Qt.ItemIsSelectable |  Qt.ItemIsEnabled )
            self.table.setItem(rowNum, 3, item)
        
        # Resize column size to fit dialog size
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)   
        
        # Sort by max object area
        self.table.setSortingEnabled(True)                         
        self.table.sortByColumn(1, Qt.DescendingOrder)
        

    def _captureDoubleClick(self):
        # Navigate to selected frame
        index = self.table.selectedIndexes()[0]
        frameStr = self.table.model().data(index).toString()
        
        if frameStr:
            frameNum = int(frameStr)
            self.parent().editor.posModel.time = frameNum
Ejemplo n.º 22
0
class iCareNewQueryWidget(QWidget):
    def __init__(self):
        super(QWidget, self).__init__()
        self._setup_widget()

    def _setup_widget(self):
        self.query = QTextEdit(self)
        self.label1 = QLabel("Query:")
        self.label2 = QLabel("Output:")
        self.submit1 = QPushButton("Execute Query")
        self.submit1.clicked.connect(self.run_query)
        self.export1 = QPushButton("Export Data")
        self.export1.clicked.connect(self.export_data)

        self.table1 = QTableWidget()

        # set layouts
        self.layout = QGridLayout(self)
        self.layout.setColumnStretch(0, 3)

        # add widgets
        self.layout.addWidget(self.label1, 0, 0)
        self.layout.addWidget(self.query, 1, 0)
        self.layout.addWidget(self.submit1, 1, 1)
        self.layout.addWidget(self.label2, 2, 0)
        self.layout.addWidget(self.table1, 3, 0)
        self.layout.addWidget(self.export1, 3, 1)
        self.setLayout(self.layout)

    @pyqtSlot()
    def run_query(self):
        query = self.query.toPlainText()
        if (len(query) == 0):
            prompt_error("Please enter a query")
            return
        try:
            dict_values = database.execute_query_result(query)
            if (dict_values):
                self.populateTable(dict_values)
            gui_helper.prompt_information("query executed successfully")
        except Exception as e:
            gui_helper.prompt_error(str(e))

    def populateTable(self, column_values):
        self.table1.clearContents()

        self.table1.setColumnCount(len(column_values))
        for key in column_values:
            self.table1.setRowCount(len(column_values[key]))
            break
        for i, key in enumerate(column_values):
            self.table1.setHorizontalHeaderItem(i, QTableWidgetItem(key))
            col_vals = column_values[key]
            for j, val in enumerate(col_vals):
                self.table1.setItem(j, i, QTableWidgetItem(str(val)))

    @pyqtSlot()
    def export_data(self):
        query_text = self.query.toPlainText()
        if (len(query_text) == 0):
            prompt_error("Please enter a query")
            return

        try:
            conn = database.get_db_connection()
            dataframe = query.manual_sql_query(conn, query_text)
            dialog = QFileDialog()
            dialog.setFileMode(QFileDialog.AnyFile)

            if dialog.exec_():
                filepaths = dialog.selectedFiles()
                self.file_save(filepaths[0], dataframe)
        except Exception as e:
            gui_helper.prompt_error(str(e))

    @pyqtSlot()
    def file_save(self, file_path, dataframe):
        if (exportFile.exportCSV(file_path, dataframe)):
            gui_helper.prompt_information("File has been succesfully saved!")
        else:
            gui_helper.prompt_error("Failed to save file")
Ejemplo n.º 23
0
class HyperLprWindow(QMainWindow):

    start_init_signal = pyqtSignal()

    def __init__(self):

        super().__init__()

        self.initUI()

    def initUI(self):

        self.statusBar().showMessage('Ready')

        self.image_window_view = HyperLprImageView()

        table_widget_header_labels = [
            "文件名", "分割识别", "置信度", "颜色", "E2E识别", "E2E置信度"
        ]

        self.hyperlpr_tableview = QTableWidget(0,
                                               len(table_widget_header_labels))
        self.hyperlpr_tableview.setHorizontalHeaderLabels(
            table_widget_header_labels)

        self.hyperlpr_tableview.setSelectionBehavior(
            QAbstractItemView.SelectItems)
        self.hyperlpr_tableview.setSelectionMode(
            QAbstractItemView.SingleSelection)
        self.hyperlpr_tableview.setEditTriggers(
            QAbstractItemView.NoEditTriggers)
        self.hyperlpr_tableview.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        self.hyperlpr_tableview.setEditTriggers(
            QAbstractItemView.NoEditTriggers)

        self.hyperlpr_tableview.cellClicked.connect(
            self.recognize_one_license_plate)

        self.location_label = QLabel("车牌目录", self)
        self.location_text = QLineEdit(self)
        self.location_text.setEnabled(False)
        self.location_text.setFixedWidth(300)
        self.location_button = QPushButton("...")
        self.location_button.clicked.connect(self.select_new_dir)

        self.location_layout = QHBoxLayout()
        self.location_layout.addWidget(self.location_label)
        self.location_layout.addWidget(self.location_text)
        self.location_layout.addWidget(self.location_button)
        self.location_layout.addStretch()

        self.check_box = QCheckBox("与文件名比较车牌")
        self.check_box.setChecked(True)

        self.update_file_path_button = QPushButton('批量识别')
        self.update_file_path_button.clicked.connect(
            self.batch_recognize_all_images)

        self.update_file_path_layout = QHBoxLayout()
        self.update_file_path_layout.addWidget(self.check_box)
        self.update_file_path_layout.addWidget(self.update_file_path_button)
        self.update_file_path_layout.addStretch()

        self.bottom_layout = QVBoxLayout()
        self.bottom_layout.addLayout(self.location_layout)
        self.bottom_layout.addLayout(self.update_file_path_layout)
        bottom_widget = QWidget()
        bottom_widget.setLayout(self.bottom_layout)

        license_plate_iamge_label = QLabel("车牌图")
        self.license_plate_widget = QLabel("")

        block_image_label = QLabel("分割图")
        self.block_plate_widget = QLabel("")

        filename_label = QLabel("文件名:")
        self.filename_edit = QLineEdit()

        segmentation_recognition_label = QLabel("分割识别:")
        self.segmentation_recognition_edit = QLineEdit()
        self.segmentation_recognition_edit.setFont(QFont("黑体", 24, QFont.Bold))
        self.segmentation_recognition_edit.setStyleSheet("color:red")

        confidence_label = QLabel("置信度")
        self.confidence_edit = QLineEdit()
        self.confidence_edit.setFont(QFont("黑体", 24, QFont.Bold))
        self.confidence_edit.setStyleSheet("color:red")

        plate_color_label = QLabel("车牌颜色")
        self.plate_color_edit = QLineEdit()
        self.plate_color_edit.setFont(QFont("黑体", 24, QFont.Bold))
        self.plate_color_edit.setStyleSheet("color:red")

        e2e_recognization_label = QLabel("e2e识别:")
        self.e2e_recognization_edit = QLineEdit()
        self.e2e_recognization_edit.setFont(QFont("黑体", 24, QFont.Bold))
        self.e2e_recognization_edit.setStyleSheet("color:red")

        e2e_confidence_label = QLabel("e2e置信度")
        self.e2e_confidence_edit = QLineEdit()
        self.e2e_confidence_edit.setFont(QFont("黑体", 24, QFont.Bold))
        self.e2e_confidence_edit.setStyleSheet("color:red")

        info_gridlayout = QGridLayout()
        info_gridlayout.addWidget(filename_label, 0, 0)
        info_gridlayout.addWidget(self.filename_edit, 0, 1)
        info_gridlayout.addWidget(license_plate_iamge_label, 1, 0)
        info_gridlayout.addWidget(self.license_plate_widget, 1, 1)
        info_gridlayout.addWidget(block_image_label, 2, 0)
        info_gridlayout.addWidget(self.block_plate_widget, 2, 1)
        info_gridlayout.addWidget(segmentation_recognition_label, 3, 0)
        info_gridlayout.addWidget(self.segmentation_recognition_edit, 3, 1)
        info_gridlayout.addWidget(confidence_label, 4, 0)
        info_gridlayout.addWidget(self.confidence_edit, 4, 1)
        info_gridlayout.addWidget(plate_color_label, 5, 0)
        info_gridlayout.addWidget(self.plate_color_edit, 5, 1)
        info_gridlayout.addWidget(e2e_recognization_label, 6, 0)
        info_gridlayout.addWidget(self.e2e_recognization_edit, 6, 1)
        info_gridlayout.addWidget(e2e_confidence_label, 7, 0)
        info_gridlayout.addWidget(self.e2e_confidence_edit, 7, 1)

        info_widget = QWidget()

        info_widget.setLayout(info_gridlayout)

        right_splitter = QSplitter(Qt.Vertical)
        right_splitter.addWidget(bottom_widget)
        right_splitter.addWidget(self.hyperlpr_tableview)
        right_splitter.addWidget(info_widget)
        right_splitter.setStretchFactor(1, 3)
        right_splitter.setStretchFactor(2, 2)

        main_splitter = QSplitter(Qt.Horizontal)
        main_splitter.addWidget(self.image_window_view)
        main_splitter.addWidget(right_splitter)
        main_splitter.setStretchFactor(0, 1)

        self.image_filename_list = []
        self.hyperlpr_dir_path = ""
        self.segmentation_recognition_correct_number = 0
        self.color_correct_number = 0
        self.e2e_recognization_correct_number = 0

        self.batch_recognization_thread = LicenseRecognizationThread()
        self.batch_recognization_thread.recognization_done_signal.connect(
            self.recognization_done_slot)
        self.batch_recognization_thread.start()

        self.start_init_signal.connect(self.read_path_and_show_one_image)

        self.setCentralWidget(main_splitter)

        self.setWindowTitle("HyperLPR车牌识别软件v1.0")

        self.start_init_signal.emit()

    def read_path_and_show_one_image(self):

        hyperlpr_dir_info_filepath = QDir.homePath() + "/hyperlpr_dir_file"
        if os.path.exists(hyperlpr_dir_info_filepath):
            with open(hyperlpr_dir_info_filepath, 'r') as f:
                self.hyperlpr_dir_path = f.read()

        if len(self.hyperlpr_dir_path) > 0:
            self.reset_info_gui()

        if len(self.image_filename_list) > 0:
            self.recognize_and_show_one_image(self.image_filename_list[0], 0)

    def select_new_dir(self):

        self.hyperlpr_dir_path = QFileDialog.getExistingDirectory(
            self, "读取文件夹", QDir.currentPath())

        if len(self.hyperlpr_dir_path) > 0:
            hyperlpr_dir_info_filepath = QDir.homePath() + "/hyperlpr_dir_file"
            with open(hyperlpr_dir_info_filepath, 'w') as f:
                f.write(self.hyperlpr_dir_path)
            self.reset_info_gui()

    def reset_info_gui(self):

        self.location_text.setText(self.hyperlpr_dir_path)
        self.scan_files_with_new_dir(self.hyperlpr_dir_path)
        self.fill_table_with_new_info()

    def scan_files_with_new_dir(self, path):

        name_list = os.listdir(path)  # 列出文件夹下所有的目录与文件
        self.image_filename_list.clear()
        for i in range(0, len(name_list)):
            if name_list[i].endswith(".jpg") or name_list[i].endswith(".png"):
                self.image_filename_list.append(name_list[i])

    def fill_table_with_new_info(self):
        self.hyperlpr_tableview.clearContents()
        row_count = self.hyperlpr_tableview.rowCount()
        for i in range(row_count, -1, -1):
            self.hyperlpr_tableview.removeRow(i)

        for i in range(0, len(self.image_filename_list)):
            row = self.hyperlpr_tableview.rowCount()
            self.hyperlpr_tableview.insertRow(row)

            item0 = QTableWidgetItem()
            item0.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 0, item0)
            self.hyperlpr_tableview.item(row, 0).setText(
                self.image_filename_list[i])

            item1 = QTableWidgetItem()
            item1.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 1, item1)

            item2 = QTableWidgetItem()
            item2.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 2, item2)

            item3 = QTableWidgetItem()
            item3.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 3, item3)

            item4 = QTableWidgetItem()
            item4.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 4, item4)

            item5 = QTableWidgetItem()
            item5.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(row, 5, item5)

    def recognize_one_license_plate(self, row, col):
        if col == 0 and row < len(self.image_filename_list):
            self.recognize_and_show_one_image(self.image_filename_list[row],
                                              row)

    def recognize_and_show_one_image(self, image_filename_text, row):

        if image_filename_text.endswith(".jpg"):

            path = os.path.join(self.hyperlpr_dir_path, image_filename_text)
            image = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)
            image, res_set = SimpleRecognizePlateWithGui(image)
            img = QImage(image.data, image.shape[1], image.shape[0],
                         image.shape[1] * image.shape[2], QImage.Format_RGB888)
            self.image_window_view.resetPixmap(img.rgbSwapped())
            self.image_window_view.resetRectText(res_set)

            if len(res_set) > 0:
                curr_rect = res_set[0][2]
                image_crop = image[int(curr_rect[1]):int(curr_rect[1] +
                                                         curr_rect[3]),
                                   int(curr_rect[0]):int(curr_rect[0] +
                                                         curr_rect[2])]
                curr_plate = cv2.resize(image_crop, (136, 72))
                plate_img = QImage(curr_plate.data, curr_plate.shape[1],
                                   curr_plate.shape[0],
                                   curr_plate.shape[1] * curr_plate.shape[2],
                                   QImage.Format_RGB888)
                self.license_plate_widget.setPixmap(
                    QPixmap.fromImage(plate_img.rgbSwapped()))

                # print(res_set[0][6])
                block_crop = image[0:24, 0:(24 * int(res_set[0][6]))]
                curr_block = cv2.resize(block_crop,
                                        (24 * int(res_set[0][6]), 24))
                block_image = QImage(curr_block.data, curr_block.shape[1],
                                     curr_block.shape[0],
                                     curr_block.shape[1] * curr_block.shape[2],
                                     QImage.Format_RGB888)
                self.block_plate_widget.setPixmap(
                    QPixmap.fromImage(block_image.rgbSwapped()))

                self.segmentation_recognition_edit.setText(res_set[0][0])

                self.filename_edit.setText(image_filename_text)
                self.confidence_edit.setText("%.3f" % (float(res_set[0][1])))
                self.plate_color_edit.setText(res_set[0][3])
                self.e2e_recognization_edit.setText(res_set[0][4])
                self.e2e_confidence_edit.setText("%.3f" %
                                                 (float(res_set[0][5])))
            else:
                self.license_plate_widget.clear()
                self.block_plate_widget.clear()
                self.segmentation_recognition_edit.setText("")
                self.filename_edit.setText("")
                self.confidence_edit.setText("")
                self.plate_color_edit.setText("")
                self.e2e_recognization_edit.setText("")
                self.e2e_confidence_edit.setText("")

            self.fill_table_widget_with_res_info(res_set, row)

    def batch_recognize_all_images(self):
        self.segmentation_recognition_correct_number = 0
        self.color_correct_number = 0
        self.e2e_recognization_correct_number = 0
        self.batch_recognization_thread.set_parameter(self.image_filename_list,
                                                      self.hyperlpr_dir_path)

    def recognization_done_slot(self, result_list):
        row = result_list[0]
        res_set = result_list[1]
        self.fill_table_widget_with_res_info(res_set, row)

        if row == len(self.image_filename_list) - 1:
            total_number = len(self.image_filename_list)

            row_count = self.hyperlpr_tableview.rowCount()
            if row_count > total_number:
                self.hyperlpr_tableview.removeRow(total_number)

            self.hyperlpr_tableview.insertRow(total_number)

            item0 = QTableWidgetItem()
            item0.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 0, item0)
            self.hyperlpr_tableview.item(total_number, 0).setText("统计结果")

            item1 = QTableWidgetItem()
            item1.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 1, item1)
            self.hyperlpr_tableview.item(total_number, 1).setText(
                "{0} / {1} = {2: .3f}".format(
                    self.segmentation_recognition_correct_number, total_number,
                    self.segmentation_recognition_correct_number /
                    total_number))

            item2 = QTableWidgetItem()
            item2.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 2, item2)

            item3 = QTableWidgetItem()
            item3.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 3, item3)
            self.hyperlpr_tableview.item(total_number, 3).setText(
                "{0} / {1} = {2: .3f}".format(
                    self.e2e_recognization_correct_number, total_number,
                    self.e2e_recognization_correct_number / total_number))

            item4 = QTableWidgetItem()
            item4.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 4, item4)
            self.hyperlpr_tableview.item(total_number, 4).setText(
                "{0} / {1} = {2: .3f}".format(
                    self.color_correct_number, total_number,
                    self.color_correct_number / total_number))

            item5 = QTableWidgetItem()
            item5.setTextAlignment(Qt.AlignCenter)
            self.hyperlpr_tableview.setItem(total_number, 5, item5)

    def fill_table_widget_with_res_info(self, res_set, row):
        image_filename_text = self.image_filename_list[row]
        if len(res_set) > 0:

            self.hyperlpr_tableview.item(row, 1).setText(res_set[0][0])
            if res_set[0][0] in image_filename_text:
                self.hyperlpr_tableview.item(row, 1).setForeground(
                    QBrush(QColor(0, 0, 255)))
                self.segmentation_recognition_correct_number += 1
            else:
                self.hyperlpr_tableview.item(row, 1).setForeground(
                    QBrush(QColor(255, 0, 0)))

            self.hyperlpr_tableview.item(row, 2).setText(
                "%.3f" % (float(res_set[0][1])))

            self.hyperlpr_tableview.item(row, 3).setText(res_set[0][3])
            if res_set[0][3] in image_filename_text:
                self.hyperlpr_tableview.item(row, 3).setForeground(
                    QBrush(QColor(0, 0, 255)))
                self.color_correct_number += 1
            else:
                self.hyperlpr_tableview.item(row, 3).setForeground(
                    QBrush(QColor(255, 0, 0)))

            self.hyperlpr_tableview.item(row, 4).setText(res_set[0][4])
            if res_set[0][4] in image_filename_text:
                self.hyperlpr_tableview.item(row, 4).setForeground(
                    QBrush(QColor(0, 0, 255)))
                self.e2e_recognization_correct_number += 1
            else:
                self.hyperlpr_tableview.item(row, 4).setForeground(
                    QBrush(QColor(255, 0, 0)))

            self.hyperlpr_tableview.item(row, 5).setText(
                "%.3f" % (float(res_set[0][5])))
Ejemplo n.º 24
0
class Table(QMainWindow):
    def __init__(self, parent):
        super().__init__(parent)

        self.db = DB()

        self.initUI()

    def initUI(self):

        in_class = "tables"

        self.sidebar = sidebar.Sidebar(self)
        self.sidebar.window.connect(self.getvalue)

        self.addDockWidget(Qt.LeftDockWidgetArea, self.sidebar)

        header = AppName(in_class)
        footer = Footer()

        add_and_search = AddSearchFrame(in_class)
        add_and_search.add_button.clicked.connect(
            lambda: self.add_tables(in_class))
        add_and_search.search_button.clicked.connect(
            lambda: self.search_tables(add_and_search.search_box))

        self.table = QTableWidget()
        self.table.setColumnCount(4)
        # self.table.setStyleSheet("border: none")
        # self.table.setStyleSheet(
        #     "background-color: rgb(255, 255, 255);\n"
        #     'font: 10pt "MS Shell Dlg 2";\n'
        #     "color: rgb(30, 45, 66);"
        # )

        # self.table.setHorizontalHeaderItem(0, QTableWidgetItem("ID"))
        self.table.setHorizontalHeaderItem(0, QTableWidgetItem("Table Name"))
        self.table.setHorizontalHeaderItem(1, QTableWidgetItem("Covers"))
        self.table.setHorizontalHeaderItem(2, QTableWidgetItem("Edit"))
        self.table.setHorizontalHeaderItem(3, QTableWidgetItem("Delete"))

        # self.table.insertRow(self.table.rowCount())
        #
        # self.table.setItem(self.table.rowCount() - 1, 0, QTableWidgetItem("ID1"))
        # self.table.setItem(self.table.rowCount() - 1, 1, QTableWidgetItem("Name1"))
        # self.table.setItem(self.table.rowCount() - 1, 2, QTableWidgetItem("Job1"))
        # self.table.setItem(self.table.rowCount() - 1, 3, QTableWidgetItem("Joining Date1"))
        # self.table.setItem(self.table.rowCount() - 1, 4, QTableWidgetItem("Salary1"))
        # self.table.setItem(self.table.rowCount() - 1, 5, QTableWidgetItem("Bonus1"))
        # self.table.setItem(self.table.rowCount() - 1, 6, QTableWidgetItem("Total Salary1"))
        # self.table.setItem(self.table.rowCount() - 1, 7, QTableWidgetItem("Edit1"))
        # self.table.setItem(self.table.rowCount() - 1, 8, QTableWidgetItem("Delete1"))

        data = self.load_tables_data()
        print(data)

        for x in data:
            print(x)

        self.populate_table(data)

        layout = QVBoxLayout()

        layout.addWidget(header)
        layout.addWidget(add_and_search)
        layout.addWidget(self.table)
        # layout.addStretch()
        layout.addWidget(footer)

        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        centralWidget = QWidget()
        centralWidget.setLayout(layout)

        self.setCentralWidget(centralWidget)
        self.setContentsMargins(0, 0, 0, 0)

        # self.resize(800, 600)
        self.setWindowTitle("Login")
        self.resize(1160, 605)

        self.show()
        self.center()

    def center(self):
        '''centers the window on the screen'''
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)

    def getvalue(self, value):
        print(value)
        print(type(value))

        if value == 1:
            self.hide()
            view = sidebar.Dashboard(self)
        elif value == 2:
            self.hide()
            view = sidebar.Employee(self)
        elif value == 3:
            pass
        elif value == 4:
            self.hide()
            view = sidebar.Reservations(self)
        elif value == 5:
            self.hide()
            view = sidebar.Category(self)
        elif value == 6:
            self.hide()
            view = sidebar.Settings(self)
        elif value == 7:
            self.hide()
            view = sidebar.Orders(self)
        elif value == 8:
            self.hide()
            view = sidebar.Menu(self)
        elif value == 9:
            self.hide()
            view = sidebar.Bill(self)

    def load_tables_data(self):
        query = "SELECT id, table_number, covers FROM tables;"

        result = self.db.fetch(query)

        return result

    '''
        This function is called after an employee has been added and returns only the last row.
    '''

    def add_update_tables_data(self):
        query = "SELECT id, table_number, covers FROM tables " \
                "order by id desc limit 1;"

        result = self.db.fetch(query)

        return result

    def edit_tables(self):
        emp_row = self.table.indexAt(self.sender().pos())
        id = int(
            self.table.cellWidget(emp_row.row(),
                                  emp_row.column()).objectName())
        print(emp_row.row())
        print(id)
        print(type(id))
        '''
            Get the data from the database for that user.
        '''
        data = self.get_data(id)

        print("Data")
        print(data)
        # print(type(data[4]))

        view = AddTableDetails(self, "update", data[0])

        view.tablenotextbox.setText(data[1])
        view.covertextbox.setText(str(data[2]))

        view.closing.connect(self.editupdate_emp)

    def editupdate_emp(self, check):
        print("I am here")
        print(check)

        self.table.clearContents()
        self.table.setRowCount(0)

        data = self.load_tables_data()

        self.populate_table(data)
        # self.table.resizeColumnsToContents()

    def get_data(self, id):
        query = "SELECT id, table_number, covers FROM tables " \
                "where id=%s"
        values = (id, )

        result = self.db.fetch(query, values)

        for (id, table_number, covers) in result:
            id = id
            table_number = table_number
            covers = covers

        return [id, table_number, covers]

    def delete_tables(self):
        emp_row = self.table.indexAt(self.sender().pos())

        # print(emp_row.row())
        # print(emp_row.column())

        # print(self.table.cellWidget(emp_row.row(), emp_row.column()).objectName())

        id = int(
            self.table.cellWidget(emp_row.row(),
                                  emp_row.column()).objectName())
        # print(id)
        # print(emp_row.child(emp_row.row(), emp_row.column()))

        query = "DELETE FROM tables WHERE id=%s"
        values = (id, )

        try:
            result = self.db.execute(query, values)
        except:
            pass

        self.table.clearContents()
        self.table.setRowCount(0)
        data = self.load_tables_data()

        self.populate_table(data)

    def add_tables(self, where):
        if where == "tables":
            print("Category Button Clicked from tables")

            view = AddTableDetails(self, "add")
            view.closing.connect(self.update_tables)

        elif where == "stocks":
            print("Stock Button Clicked")

    def search_tables(self, search_obj):
        search = search_obj.text()
        search_obj.setText("")

        print("Search")
        if search != "":
            query = "SELECT * FROM tables WHERE table_number like %s"
            values = ("%" + search + "%", )
        else:
            query = "SELECT * FROM tables"
            values = ()

        self.table.clearContents()
        self.table.setRowCount(0)

        data = self.db.fetch(query, values)

        self.populate_table(data)

    '''
        Repopulates the employee table with the updated data.
    '''

    def update_tables(self, check):
        print("I am here")
        print(check)

        data = self.add_update_tables_data()

        self.populate_table(data)

    '''
        This function populates the employee table with data.
    '''

    def populate_table(self, data):
        for (id, table_number, covers) in data:
            self.table.insertRow(self.table.rowCount())

            self.table.setItem(self.table.rowCount() - 1, 0,
                               QTableWidgetItem(str(table_number)))
            self.table.setItem(self.table.rowCount() - 1, 1,
                               QTableWidgetItem(str(covers)))

            edit = QPushButton(self.table)
            edit.setObjectName(str(id))
            edit.setStyleSheet("background-color: rgb(50,205,50);")
            edit.setText("Edit")
            edit.adjustSize()
            edit.clicked.connect(self.edit_tables)

            self.table.setCellWidget(self.table.rowCount() - 1, 2, edit)

            delete = QPushButton(self.table)
            delete.setObjectName(str(id))
            delete.setStyleSheet("background-color: #d63447;")
            delete.setText("Delete")
            delete.adjustSize()
            delete.clicked.connect(self.delete_tables)
            # delete.mousePressEvent = functools.partial(self.delete_emp, source_object=delete)
            self.table.setCellWidget(self.table.rowCount() - 1, 3, delete)
Ejemplo n.º 25
0
class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()

        self.icon_path = 'resources\\warframe.ico'
        self.app_title = 'Warframe Prime Helper'
        self.company_name = 'Warframe Tools'

        self.settings = QSettings(self.company_name, self.app_title)
        self.setWindowTitle(self.app_title)

        self.market_api = None

        self.image_label = None
        self.image_label2 = None

        self.warframe_height = 1080
        self.warframe_width = 1920

        self.table = None
        self.mission_table = None

        self.slider_names = None
        self.sliders = None
        self.slider_labels = None
        self.slider_default_values = None
        self.slider_orig_values = None
        self.slider_values = None
        self.is_slider_max_set = False

        #self.plat_check_box = QCheckBox("Prefer platinum")
        #self.plat_check_box.setChecked(True)

        self.update_prices_button = None
        self.update_ducats_button = None
        self.update_prices_progress = None
        self.update_ducats_progress = None
        self.last_updated_prices_value = None
        self.last_updated_ducats_value = None
        self.num_parts_value = None
        self.latest_item_value = None

        self.move_to_top_check_box = None
        self.pause_button = None
        self.is_paused = False

        self.hide_crop_check_box = None
        self.hide_filter_check_box = None
        self.hide_fissure_check_box = None

        self.relics = None
        self.hide_relics = {}
        self.hidden_relics = set()

        self.hide_missions = {}
        self.hidden_missions = set()
        self.hide_missions_box = None
        self.mission_names = None

        self.crop_img = None
        self.filter_img = None

        self.dialog = None
        self.layout = None

        self.filled_rows = 0
        self.max = -1
        self.max_row = -1

        self.ocr = None
        self.old_screenshot_shape = 0
        self.old_filtered_shape = 0

        self.missions = []

        self.num_primes = 100
        self.api = None

        self.prices_progress_lock = Lock()
        self.ducats_progress_lock = Lock()

        self.ducats_thread = None
        self.prices_thread = None

        self.timer = None

        self.init_image_labels()
        self.init_tables()
        self.init_sliders()
        self.init_dialog()
        self.set_layout()
        self.init_timer()

        self.show()

        #measured correct values
        self.setFixedSize(978, 617)

    def init_timer(self):
        self.timer = QTimer()
        self.timer.timeout.connect(self.update_mission_table_time)
        self.timer.start(1000)

    def init_image_labels(self):
        self.image_label = QLabel()
        image = QPixmap('temp\\crop_27.bmp')
        self.image_label.setPixmap(image)

        self.image_label2 = QLabel()
        self.image_label2.setPixmap(image)

    def set_layout(self):
        settings_button_box = self.make_settings_button_box()
        self.init_imgs()
        bot_box = self.make_bot_box()

        self.layout = QVBoxLayout()
        self.layout.setAlignment(Qt.AlignTop)
        self.layout.addSpacing(-12)
        self.layout.addLayout(settings_button_box)
        self.layout.addWidget(self.crop_img)
        self.layout.addWidget(self.filter_img)
        self.layout.addWidget(bot_box)
        self.setLayout(self.layout)

    def make_settings_button_box(self):
        settings_button = QPushButton()
        # Gear icon is from: https://iconscout.com/icon/gear-222
        style_sheet = """
        QPushButton {
            qproperty-icon: url(" ");
            qproperty-iconSize: 15px 15px;
            border-image: url("resources/Gear.svg");
            background-color: rgba(255, 255, 255, 0);
        }
        
        QPushButton:hover {
            border-image: url("resources/SelectedGear.svg");
        }"""
        settings_button.setStyleSheet(style_sheet)
        #settings_button.setStyleSheet("background-color: rgba(0, 0, 0, 255); font-size: 23px;")
        settings_button.clicked.connect(self.show_preferences)
        settings_button.setFixedWidth(30)
        settings_button.setFixedHeight(30)

        settings_button_hb = QHBoxLayout()
        settings_button_hb.setAlignment(Qt.AlignRight)
        settings_button_hb.addWidget(settings_button)
        settings_button_hb.addSpacing(-11)
        return settings_button_hb

    def make_bot_box(self):
        bot_layout = QHBoxLayout()
        bot_layout.addWidget(self.table)
        bot_layout.addWidget(self.mission_table)

        bot_box = QGroupBox()
        bot_box.setLayout(bot_layout)
        bot_box.setFixedHeight(287)
        return bot_box

    def init_dialog(self):
        crop_box = self.make_crop_box()
        filter_box = self.make_filter_box()
        other_box = self.make_other_box()

        settings_layout_1 = QVBoxLayout()
        settings_layout_1.addWidget(crop_box)
        settings_layout_1.addWidget(filter_box)
        settings_layout_1.addWidget(other_box)

        update_box = self.make_update_box()
        rate_box = self.make_rate_box()

        settings_layout_2 = QVBoxLayout()
        settings_layout_2.addWidget(update_box)
        settings_layout_2.addWidget(rate_box)

        hide_box = self.make_hide_box()
        hide_relics_box = self.make_hide_relics_box()
        button_box = self.make_button_box()

        settings_layout_3 = QVBoxLayout()
        settings_layout_3.addWidget(hide_box)
        settings_layout_3.addWidget(hide_relics_box)

        hide_missions_box = self.make_hide_missions_box()
        settings_layout_4 = QVBoxLayout()
        settings_layout_4.addWidget(hide_missions_box)
        settings_layout_4.addWidget(button_box)

        settings_layout = QHBoxLayout()
        settings_layout.addLayout(settings_layout_1)
        settings_layout.addLayout(settings_layout_2)
        settings_layout.addLayout(settings_layout_3)
        settings_layout.addLayout(settings_layout_4)

        self.dialog = QDialog()
        self.dialog.setWindowTitle("Preferences")
        self.dialog.setWindowModality(Qt.ApplicationModal)
        self.dialog.setLayout(settings_layout)

    def make_button_box(self):
        button_box = QDialogButtonBox()
        button_box.setOrientation(Qt.Horizontal)
        button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
        button_box.accepted.connect(self.save_settings)
        button_box.rejected.connect(self.load_settings)
        return button_box

    def load_settings(self):
        self.settings.sync()
        slider_orig_values = {'x': 521, 'y': 400, 'w': 908, 'h': 70, 'v1': 197, 'v2': 180, 'd': 4,
                              'Screencap (hz)': 1, 'Fissure (s)': 30, 'API Threads': 4}
        self.slider_default_values = {}
        slider_default_max = {'x': self.warframe_width/2,
                              'y': self.warframe_height/2,
                              'w': self.warframe_width,
                              'h': self.warframe_height,
                              'v1': 255,
                              'v2': 255,
                              'd': 40}

        for slider_name in self.slider_names:
            self.slider_default_values[slider_name] = self.settings.value(slider_name,defaultValue=slider_orig_values[slider_name])
            if len(slider_name) <= 2:
                max_val = self.settings.value("{}_max".format(slider_name), defaultValue=slider_default_max[slider_name], type=int)
                self.sliders[slider_name].setMaximum(max_val)
            self.sliders[slider_name].setValue(self.slider_default_values[slider_name])

        prices = self.settings.value("last_updated_prices_value", defaultValue="Never", type=str)
        ducats = self.settings.value("last_updated_ducats_value", defaultValue="Never", type=str)
        num_parts = self.settings.value("num_parts_value", defaultValue=350, type=int)
        latest_item = self.settings.value("latest_item_value", defaultValue="", type=str)

        self.last_updated_prices_value.setText(prices)
        self.last_updated_ducats_value.setText(ducats)
        self.num_parts_value.setNum(num_parts)
        self.latest_item_value.setText(latest_item)

        for relic in self.relics:
            checked = self.settings.value("hide_{}".format(relic), defaultValue=False,type=bool)
            self.hide_relics[relic].setChecked(checked)
            if checked:
                self.set_hidden_relic(relic)

        for mission in self.mission_names:
            checked = self.settings.value("hide_{}".format(mission), defaultValue=False, type=bool)
            self.hide_missions[mission].setChecked(checked)
            if checked:
                self.set_hidden_mission(mission)

        if self.settings.value("toggle_fissure_table", defaultValue=False, type=bool):
            self.hide_fissure_check_box.setChecked(True)
            self.toggle_fissure_table()

        if self.settings.value("toggle_move_to_top", defaultValue=False, type=bool):
            self.move_to_top_check_box.setChecked(True)
            self.toggle_move_to_top()

        if self.settings.value("toggle_cropped_img", defaultValue=False, type=bool):
            self.hide_crop_check_box.setChecked(True)
            self.toggle_cropped_img()

        if self.settings.value("toggle_filtered_img", defaultValue=False, type=bool):
            self.hide_filter_check_box.setChecked(True)
            self.toggle_filtered_img()
        self.dialog.close()

    def save_settings(self):
        for slider_name in self.slider_names:
            self.settings.setValue(slider_name, self.sliders[slider_name].value())

        for relic in self.relics:
            self.settings.setValue("hide_{}".format(relic), self.hide_relics[relic].isChecked())

        for mission in self.mission_names:
            self.settings.setValue("hide_{}".format(mission), self.hide_missions[mission].isChecked())

        self.settings.setValue("toggle_fissure_table", self.hide_fissure_check_box.isChecked())
        self.settings.setValue("toggle_move_to_top", self.move_to_top_check_box.isChecked())
        self.settings.setValue("toggle_cropped_img", self.hide_crop_check_box.isChecked())
        self.settings.setValue("toggle_filtered_img", self.hide_filter_check_box.isChecked())
        self.dialog.close()
        self.settings.sync()

    def init_imgs(self):
        self.crop_img = QGroupBox("Crop")
        crop_img_layout = QVBoxLayout()
        crop_img_layout.addWidget(self.image_label)
        self.crop_img.setLayout(crop_img_layout)

        self.filter_img = QGroupBox("Filtered")
        filter_img_layout = QVBoxLayout()
        filter_img_layout.addWidget(self.image_label2)
        self.filter_img.setLayout(filter_img_layout)

    def make_hide_missions_box(self, missions=None):
        if self.hide_missions_box is None:
            self.hide_missions_box = QGroupBox("Hide Missions")
        if missions is not None:
            hide_missions_layout = QGridLayout()
            hide_missions_layout.setColumnStretch(2, 2)
            hide_missions_layout.setAlignment(Qt.AlignTop)
            hide_missions_layout.setContentsMargins(0, 0, 0, 0)

            skip_missions = ["MT_SECTOR", "MT_PVP", "MT_LANDSCAPE", "MT_EVACUATION", "MT_ASSASSINATION", "MT_ARENA"]
            seen_missions = set()
            i = 0
            for mission in missions:
                mission_name = missions[mission]['value']
                if mission_name == "Extermination":
                    mission_name = "Exterminate"
                if mission not in skip_missions and mission_name not in seen_missions:
                    self.hide_missions[mission_name] = QCheckBox(mission_name)
                    self.hide_missions[mission_name].setChecked(False)
                    self.hide_missions[mission_name].stateChanged.connect(partial(self.set_hidden_mission, mission_name))
                    hide_missions_layout.addWidget(self.hide_missions[mission_name], int(i/2), i % 2)
                    i += 1
                    seen_missions.add(mission_name)
            self.hide_missions_box.setLayout(hide_missions_layout)
            self.mission_names = list(seen_missions)

            self.load_settings()
        return self.hide_missions_box

    def set_hidden_mission(self, mission):
        if self.hide_missions[mission].isChecked():
            self.hidden_missions.add(mission)
        else:
            self.hidden_missions.remove(mission)
        self.update_mission_table_hidden()

    def make_hide_relics_box(self):
        hide_relics_layout = QVBoxLayout()
        hide_relics_layout.setAlignment(Qt.AlignTop)
        hide_relics_layout.setContentsMargins(0, 0, 0, 0)
        self.relics = ["Axi", "Neo", "Meso", "Lith", "Requiem"]

        for relic in self.relics:
            self.hide_relics[relic] = QCheckBox(relic)
            self.hide_relics[relic].setChecked(False)
            self.hide_relics[relic].stateChanged.connect(partial(self.set_hidden_relic, relic))
            hide_relics_layout.addWidget(self.hide_relics[relic])

        hide_relics_box = QGroupBox("Hide Relics")
        hide_relics_box.setLayout(hide_relics_layout)
        return hide_relics_box

    def make_hide_box(self):
        hide_layout = QVBoxLayout()
        hide_layout.setAlignment(Qt.AlignTop)
        hide_layout.setContentsMargins(0, 0, 0, 0)

        self.hide_crop_check_box = QCheckBox("Hide Crop")
        self.hide_crop_check_box.setChecked(False)
        self.hide_crop_check_box.stateChanged.connect(self.toggle_cropped_img)
        hide_layout.addWidget(self.hide_crop_check_box)

        self.hide_filter_check_box = QCheckBox("Hide Filtered")
        self.hide_filter_check_box.setChecked(False)
        self.hide_filter_check_box.stateChanged.connect(self.toggle_filtered_img)
        hide_layout.addWidget(self.hide_filter_check_box)

        self.hide_fissure_check_box = QCheckBox("Hide Fissure Table")
        self.hide_fissure_check_box.setChecked(False)
        self.hide_fissure_check_box.stateChanged.connect(self.toggle_fissure_table)
        hide_layout.addWidget(self.hide_fissure_check_box)

        hide_box = QGroupBox("Hide UI")
        hide_box.setLayout(hide_layout)
        return hide_box

    def make_rate_box(self):
        rate_grid = QGridLayout()
        rate_grid.setColumnStretch(3, 3)
        rate_grid.setContentsMargins(0, 0, 0, 0)
        for i in range(3):
            slider_name = self.slider_names[i + 7]
            rate_grid.addWidget(self.slider_labels[slider_name], i, 0)
            rate_grid.addWidget(self.slider_values[slider_name], i, 1)
            rate_grid.addWidget(self.sliders[slider_name], i, 2)

        rate_box = QGroupBox("Rates")
        rate_box.setLayout(rate_grid)
        return rate_box

    def make_other_box(self):
        self.move_to_top_check_box = QCheckBox("Bring to front")
        self.move_to_top_check_box.setChecked(True)
        self.move_to_top_check_box.stateChanged.connect(self.toggle_move_to_top)
        self.pause_button = QPushButton("Pause")
        self.pause_button.clicked.connect(self.toggle_button)
        self.is_paused = False
        other_layout = QVBoxLayout()
        other_layout.setAlignment(Qt.AlignTop)
        other_layout.setContentsMargins(0, 0, 0, 0)
        other_layout.addWidget(self.move_to_top_check_box)
        other_layout.addWidget(self.pause_button)

        other_box = QGroupBox("Other")
        other_box.setLayout(other_layout)
        return other_box

    def make_filter_box(self):
        filter_grid = QGridLayout()
        filter_grid.setColumnStretch(3, 3)
        filter_grid.setAlignment(Qt.AlignTop)
        filter_grid.setContentsMargins(0, 0, 0, 0)
        for i in range(3):
            slider_name = self.slider_names[i + 4]
            filter_grid.addWidget(self.slider_labels[slider_name], i, 0)
            filter_grid.addWidget(self.slider_values[slider_name], i, 1)
            filter_grid.addWidget(self.sliders[slider_name], i, 2)

        filter_box = QGroupBox("Filter Parameters")
        filter_box.setLayout(filter_grid)
        return filter_box

    def make_crop_box(self):
        crop_grid = QGridLayout()
        crop_grid.setColumnStretch(3, 4)
        crop_grid.setAlignment(Qt.AlignTop)
        crop_grid.setContentsMargins(0, 0, 0, 0)
        for i in range(4):
            slider_name = self.slider_names[i]
            crop_grid.addWidget(self.slider_labels[slider_name], i, 0)
            crop_grid.addWidget(self.slider_values[slider_name], i, 1)
            crop_grid.addWidget(self.sliders[slider_name], i, 2)

        crop_box = QGroupBox("Crop Parameters")
        crop_box.setLayout(crop_grid)
        return crop_box

    def make_update_box(self):
        update_layout = QGridLayout()
        update_layout.setColumnStretch(4, 2)
        update_layout.setAlignment(Qt.AlignTop)
        update_layout.setContentsMargins(0, 0, 0, 0)
        self.update_prices_button = QPushButton("Update Prices")
        self.update_prices_button.clicked.connect(self.update_prices)
        self.update_prices_progress = QProgressBar()
        self.update_prices_progress.setFixedWidth(110)
        self.update_prices_progress.setRange(0, 100)
        update_layout.addWidget(self.update_prices_button, 0, 0)
        update_layout.addWidget(self.update_prices_progress, 0, 1)

        self.update_ducats_button = QPushButton("Update Ducats")
        self.update_ducats_button.clicked.connect(self.update_ducats)
        self.update_ducats_progress = QProgressBar()
        self.update_ducats_progress.setFixedWidth(110)
        self.update_ducats_progress.setRange(0, 100)
        update_layout.addWidget(self.update_ducats_button, 1, 0)
        update_layout.addWidget(self.update_ducats_progress, 1, 1)

        last_updated_prices_label = QLabel("Prices Updated")

        prices = self.settings.value("last_updated_prices_value", defaultValue="Never", type=str)
        ducats = self.settings.value("last_updated_ducats_value", defaultValue="Never", type=str)
        num_parts = self.settings.value("num_parts_value", defaultValue=350, type=str)
        latest_item = self.settings.value("latest_item_value", defaultValue="", type=str)

        self.last_updated_prices_value = QLabel(prices)
        self.last_updated_ducats_value = QLabel(ducats)
        self.num_parts_value = QLabel(num_parts)
        self.latest_item_value = QLabel(latest_item)

        update_layout.addWidget(last_updated_prices_label, 2, 0)
        update_layout.addWidget(self.last_updated_prices_value, 2, 1)

        last_updated_ducats_label = QLabel("Ducats Updated")
        update_layout.addWidget(last_updated_ducats_label, 3, 0)
        update_layout.addWidget(self.last_updated_ducats_value, 3, 1)

        num_parts_label = QLabel("Prime Parts")
        update_layout.addWidget(num_parts_label, 4, 0)
        update_layout.addWidget(self.num_parts_value, 4, 1)

        latest_item_label = QLabel("Latest Prime")
        update_layout.addWidget(latest_item_label, 5, 0)
        update_layout.addWidget(self.latest_item_value, 5, 1)

        update_box = QGroupBox("Updates")
        update_box.setLayout(update_layout)
        return update_box

    def init_sliders(self):
        self.slider_names = ['x', 'y', 'w', 'h', 'v1', 'v2', 'd', 'Screencap (hz)', 'Fissure (s)', 'API Threads']
        self.sliders = {x: QSlider(Qt.Horizontal) for x in self.slider_names}
        self.slider_labels = {x: QLabel(x) for x in self.slider_names}
        self.slider_default_values = {}
        self.slider_orig_values = {'x': 521, 'y': 400, 'w': 908, 'h': 70, 'v1': 197, 'v2': 180, 'd': 4,
                                   'Screencap (hz)': 1, 'Fissure (s)': 30, 'API Threads': 4}
        for slider_name in self.slider_names:
            self.slider_default_values[slider_name] = self.settings.value(slider_name, defaultValue=self.slider_orig_values[slider_name])
        self.slider_values = {x: QLabel(str(self.slider_default_values[x])) for x in self.slider_names}
        self.slider_values['Screencap (hz)'].setNum(self.slider_default_values['Screencap (hz)']/4)
        self.slider_values['d'].setNum(self.slider_default_values['d'] / 4)

        self.slider_labels['d'].setText('\u0394')

        self.sliders['x'].setMaximum(int(self.warframe_width / 2))
        self.sliders['y'].setMaximum(int(self.warframe_height / 2))
        self.sliders['w'].setMaximum(self.warframe_width)
        self.sliders['h'].setMaximum(self.warframe_height)
        self.sliders['v1'].setMaximum(255)
        self.sliders['v2'].setMaximum(255)
        self.sliders['d'].setMaximum(40)
        self.sliders['Screencap (hz)'].setMaximum(20)
        self.sliders['Screencap (hz)'].setMinimum(1)
        self.sliders['Fissure (s)'].setMaximum(60)
        self.sliders['Fissure (s)'].setMinimum(10)
        self.sliders['API Threads'].setMaximum(10)
        self.sliders['API Threads'].setMinimum(2)
        for slider_name in self.slider_names:
            if len(slider_name) <= 2:
                self.sliders[slider_name].setMinimum(0)
            self.sliders[slider_name].setSingleStep(1)
            self.slider_values[slider_name].setFixedWidth(35)
            self.sliders[slider_name].setValue(self.slider_default_values[slider_name])

    def init_tables(self):
        self.table = QTableWidget(7, 3)
        self.table.setHorizontalHeaderLabels(['Prime Part', 'Plat', 'Ducats'])
        self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)

        self.mission_table = QTableWidget(30, 4)
        self.mission_table.setHorizontalHeaderLabels(['Relic', 'Mission', 'Type', 'Time Left'])
        self.mission_table.setEditTriggers(QAbstractItemView.NoEditTriggers)

        mission_header = self.mission_table.horizontalHeader()

        for i in range(4):
            mission_header.setSectionResizeMode(i, QHeaderView.Interactive)
        mission_header.resizeSection(0, 55)
        mission_header.resizeSection(1, 150)
        mission_header.resizeSection(2, 90)
        mission_header.resizeSection(3, 60)
        self.mission_table.setFixedWidth(405)

    def update_prices(self):
        self.prices_thread = threading.Thread(name="prices_thread", target=self.market_api.update_prices)
        self.prices_thread.start()

        self.update_prices_button.setEnabled(False)
        self.update_ducats_button.setEnabled(False)

    def update_ducats(self):
        self.ducats_thread = threading.Thread(name="ducats_thread", target=self.market_api.update_ducats)
        self.ducats_thread.start()

        self.update_prices_button.setEnabled(False)
        self.update_ducats_button.setEnabled(False)

    def update_primes_info(self, num, latest):
        self.num_parts_value.setNum(num)
        self.latest_item_value.setText(latest)
        self.update_prices_progress.setMaximum(num)
        self.update_ducats_progress.setMaximum(num)
        self.num_primes = num

    def get_datetime(self):
        return datetime.now().strftime("%b %d %Y %H:%M:%S")

    def update_ducats_time(self):
        self.last_updated_ducats_value.setText(self.get_datetime())
        self.ducats_progress_lock.acquire()
        self.update_ducats_progress.setValue(self.num_primes)
        self.ducats_progress_lock.release()

        self.settings.setValue("last_updated_ducats_value", self.last_updated_ducats_value.text())
        self.settings.setValue("num_parts_value", self.num_parts_value.text())
        self.settings.setValue("latest_item_value", self.latest_item_value.text())

    def update_prices_time(self):
        self.last_updated_prices_value.setText(self.get_datetime())
        self.prices_progress_lock.acquire()
        self.update_prices_progress.setValue(self.num_primes)
        self.prices_progress_lock.release()

        self.settings.setValue("last_updated_prices_value", self.last_updated_prices_value.text())
        self.settings.setValue("num_parts_value", self.num_parts_value.text())
        self.settings.setValue("latest_item_value", self.latest_item_value.text())

    def set_update_prices_progress(self, val):
        if self.prices_progress_lock.acquire():
            self.update_prices_progress.setValue(val)
            self.prices_progress_lock.release()

    def set_update_ducats_progress(self, val):
        if self.ducats_progress_lock.acquire():
            self.update_ducats_progress.setValue(val)
            self.ducats_progress_lock.release()

    def finished_update_progress(self):
        self.update_prices_button.setEnabled(True)
        self.update_ducats_button.setEnabled(True)

    def show_preferences(self):
        self.dialog.exec_()
        self.load_settings()

    def toggle_fissure_table(self):
        if self.hide_fissure_check_box.isChecked():
            self.mission_table.hide()
        else:
            self.mission_table.show()
        self.setFixedSize(self.layout.sizeHint())

    def toggle_move_to_top(self):
        self.ocr.set_move_to_top(self.move_to_top_check_box.isChecked())

    def toggle_cropped_img(self):
        if self.hide_crop_check_box.isChecked():
            self.crop_img.hide()
        else:
            self.crop_img.show()
        self.setFixedSize(self.layout.sizeHint())

    def toggle_filtered_img(self):
        if self.hide_filter_check_box.isChecked():
            self.filter_img.hide()
        else:
            self.filter_img.show()
        self.setFixedSize(self.layout.sizeHint())
        #print("{}h,{}w".format(self.frameGeometry().height(),self.frameGeometry().width()))

    def set_sliders_range(self, x, y):
        max_values = {'x': int(x/2), 'y': int(y/2), 'w':x, 'h':y}
        for slider_name in max_values:
            self.sliders[slider_name].setMaximum(max_values[slider_name])
            self.sliders[slider_name].setValue(self.slider_default_values[slider_name])
            self.settings.setValue("{}_max", max_values[slider_name])

    def toggle_button(self):
        self.is_paused = not self.is_paused
        if self.is_paused:
            self.pause_button.setText("Resume")
        else:
            self.pause_button.setText("Pause")
        if self.ocr is not None:
            if self.is_paused:
                self.ocr.save_screenshot()
                self.ocr.skip_screenshot = True
            else:
                self.ocr.skip_screenshot = False

    def clear_table(self):
        self.table.clearSelection()
        self.table.clearContents()
        self.filled_rows = 0
        #self.table.setRowCount(self.filled_rows)

    def is_plat_preferred(self):
        return self.plat_check_box.isChecked()

    def insert_table_row(self, row):
        for i in range(3):
            self.table.setItem(self.filled_rows, i, QTableWidgetItem(str(row[i])))

        self.filled_rows = self.filled_rows + 1
        #self.table.setRowCount(self.filled_rows)

    def update_mission_table(self, missions):
        self.missions = list(missions)
        cur_time = time.time()
        for i in range(len(missions)):
            for j in range(3):
                self.mission_table.setItem(i, j, QTableWidgetItem(str(self.missions[i][j])))

            self.mission_table.setItem(i, 3, QTableWidgetItem(self.get_duration_str(self.missions[i][3]-cur_time)))
            if self.missions[i][0] in self.hidden_relics:
                self.mission_table.setRowHidden(i, True)
            if self.missions[i][2] in self.hidden_missions:
                self.mission_table.setRowHidden(i, True)
            else:
                self.mission_table.setRowHidden(i, False)

        self.mission_table.setRowCount(len(self.missions)-1)

    def update_mission_table_time(self):
        cur_time = time.time()
        needs_update = False
        for i in range(len(self.missions)):
            self.mission_table.setItem(i, 3, QTableWidgetItem(self.get_duration_str(self.missions[i][3]-cur_time)))
            if self.missions[i][3]-cur_time < 0:
                needs_update = True
        if needs_update:
            self.api.filter_expired_missions()

    def update_mission_table_hidden(self):
        for i in range(len(self.missions)):
            if self.missions[i][0] in self.hidden_relics:
                self.mission_table.setRowHidden(i, True)
            elif self.missions[i][2] in self.hidden_missions:
                self.mission_table.setRowHidden(i, True)
            else:
                self.mission_table.setRowHidden(i, False)

    def get_duration_str(self, duration):
        m, s = divmod(int(duration), 60)
        h, m = divmod(m, 60)
        return '{:d}:{:02d}:{:02d}'.format(h, m, s)

    def set_ocr_connection(self, ocr):
        for slider_name in self.slider_names:
            self.sliders[slider_name].valueChanged.connect(partial(self.set_ocr_crop, ocr, slider_name))
        self.ocr = ocr
        self.market_api = MarketReader(ocr=self.ocr, gui=self)

    def set_api(self, wf_api):
        self.api = wf_api
        self.make_hide_missions_box(self.api.mission_types)

    def set_hidden_relic(self, relic):
        if self.hide_relics[relic].isChecked():
            self.hidden_relics.add(relic)
        else:
            self.hidden_relics.remove(relic)
        self.update_mission_table_hidden()

    def set_ocr_crop(self, ocr, dim, val):
        if dim == 'Screencap (hz)' or dim == 'd':
            val = val / 4
        self.slider_values[dim].setNum(val)
        if val < 0 or val > 100000 or val is None:
            return
        if dim == 'x':
            ocr.set_x_offset(val)
        if dim == 'y':
            ocr.set_y_offset(val)
        if dim == 'w':
            ocr.set_w(val)
        if dim == 'h':
            ocr.set_h(val)
        if dim == 'v1':
            ocr.set_v1(val)
        if dim == 'v2':
            ocr.set_v2(val)
        if dim == 'd':
            self.ocr.set_diff_threshold(val/4)
        if dim == 'Screencap (hz)':
            ocr.set_interval(1/val)
        if dim == 'Fissure (s)':
            self.api.set_rate(val)
        if dim == 'API Threads':
            self.market_api.set_num_threads(val)

    #def select_max(self):
    #    # TODO doesnt work
    #    self.table.clearSelection()
    #    self.table.selectRow(self.max_row)

    def update_filtered(self, filtered):
        filtered_shape = None
        if not self.hide_filter_check_box.isChecked():
            filtered_shape = filtered.shape
            h, w = filtered.shape
            bytes_per_line = w
            filtered_pix = QPixmap(QImage(filtered, w, h, bytes_per_line, QImage.Format_Grayscale8))
            filtered_pix = filtered_pix.scaled(908, 70, Qt.KeepAspectRatio)
            self.image_label2.setPixmap(filtered_pix)
        #self.update_window_size(None, filtered_shape)

    def update_screenshot(self, screenshot):
        screenshot_shape = None
        if not self.hide_crop_check_box.isChecked():
            screenshot_shape = screenshot.shape
            h, w, ch = screenshot.shape
            bytes_per_line = ch * w
            screenshot_pix = QPixmap(QImage(screenshot, w, h, bytes_per_line, QImage.Format_RGB888))
            screenshot_pix = screenshot_pix.scaled(908, 70, Qt.KeepAspectRatio)
            self.image_label.setPixmap(screenshot_pix)
        #self.update_window_size(screenshot_shape, None)

    def update_window_size(self, screenshot_shape, filtered_shape):
        should_update = False
        if screenshot_shape is not None and screenshot_shape == self.old_screenshot_shape:
            self.old_screenshot_shape = screenshot_shape
            should_update = True
        if filtered_shape is not None and filtered_shape == self.old_filtered_shape:
            self.old_filtered_shape = filtered_shape
            should_update = True
        if should_update:
            self.setFixedSize(self.layout.sizeHint())

    def __exit__(self):
        self.market_api.exit_now = True
        self.ocr.exit_now = True
Ejemplo n.º 26
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        self.conn = pymysql.connect(host='localhost',
                                    port=3306,
                                    user='******',
                                    password='',
                                    db='')
        self.cur = self.conn.cursor()
        self.sqlString = "select * from student where "
        MainWindow.setObjectName('MainWindow')
        MainWindow.resize(760, 440)
        MainWindow.setFixedSize(MainWindow.width(), MainWindow.height())
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName('centralwidget')

        self.frame = QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(10, 10, 491, 121))
        self.frame.setFrameShape(QFrame.StyledPanel)
        self.frame.setFrameShadow(QFrame.Raised)
        self.frame.setObjectName('frame')

        self.check_sid = QCheckBox(self.frame)
        self.check_sid.setGeometry(QtCore.QRect(20, 10, 71, 16))
        self.check_sid.setObjectName('check_sid')

        # self.check_sage = QCheckBox(self.frame)
        # self.check_sage.setGeometry(QtCore.QRect(20, 70, 71, 16))
        # self.check_sage.setObjectName("check_Sage")

        self.check_sname = QCheckBox(self.frame)
        self.check_sname.setGeometry(QtCore.QRect(20, 40, 71, 16))
        self.check_sname.setObjectName('check_sname')

        self.check_sgender = QCheckBox(self.frame)
        self.check_sgender.setGeometry(QtCore.QRect(20, 100, 71, 16))
        self.check_sgender.setObjectName('check_sgender')

        self.sid = QLineEdit(self.frame)
        self.sid.setGeometry(QtCore.QRect(90, 10, 113, 16))
        self.sid.setObjectName('sid')

        self.sname = QLineEdit(self.frame)
        self.sname.setGeometry(QtCore.QRect(90, 40, 113, 16))
        self.sname.setObjectName("sname")

        # self.first_sage = QLineEdit(self.frame)
        # self.first_sage.setGeometry(QtCore.QRect(90, 70, 41, 16))
        # self.first_sage.setObjectName("first_sage")

        self.sgender = QLineEdit(self.frame)
        self.sgender.setGeometry(QtCore.QRect(90, 100, 113, 16))
        self.sgender.setObjectName("sgender")

        self.label = QLabel(self.frame)
        self.label.setGeometry(QtCore.QRect(140, 70, 16, 16))
        self.label.setObjectName('label')

        self.check_sdept = QCheckBox(self.frame)
        self.check_sdept.setGeometry(QtCore.QRect(270, 40, 71, 16))
        self.check_sdept.setObjectName("check_sdept")
        self.sdept = QLineEdit(self.frame)
        self.sdept.setGeometry(QtCore.QRect(340, 40, 113, 16))
        self.sdept.setObjectName("sdept")

        self.sclass = QLineEdit(self.frame)
        self.sclass.setGeometry(QtCore.QRect(340, 10, 113, 16))
        self.sclass.setObjectName("sclass")
        self.check_sclass = QCheckBox(self.frame)
        self.check_sclass.setGeometry(QtCore.QRect(270, 10, 71, 16))
        self.check_sclass.setObjectName("check_sclass")

        self.find = QPushButton(self.frame)
        self.find.setGeometry(QtCore.QRect(380, 100, 75, 21))
        self.find.setObjectName('find')
        self.find.clicked.connect(self.find_btn)

        self.sql_out = QTextBrowser(self.centralwidget)
        self.sql_out.setGeometry(QtCore.QRect(10, 140, 740, 61))
        self.sql_out.setObjectName('sql_out')

        self.result_out = QTableWidget(self.centralwidget)
        self.result_out.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.result_out.setGeometry(QtCore.QRect(10, 210, 740, 171))
        self.result_out.setObjectName('result_out')

        self.result_out.setColumnCount(5)
        self.result_out.setRowCount(5)
        self.result_out.resizeColumnsToContents()
        self.result_out.resizeRowsToContents()
        item = QTableWidgetItem()
        self.result_out.setHorizontalHeaderItem(0, item)
        item = QTableWidgetItem()
        self.result_out.setHorizontalHeaderItem(1, item)
        item = QTableWidgetItem()
        self.result_out.setHorizontalHeaderItem(2, item)
        item = QTableWidgetItem()
        self.result_out.setHorizontalHeaderItem(3, item)
        item = QTableWidgetItem()
        self.result_out.setHorizontalHeaderItem(4, item)
        self.result_out.horizontalHeader().setDefaultSectionSize(100)
        self.result_out.horizontalHeader().setMinimumSectionSize(25)
        self.result_out.verticalHeader().setDefaultSectionSize(30)

        self.pushButton_2 = QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(675, 390, 75, 21))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.clicked.connect(self.p2_clicked)
        MainWindow.setCentralWidget(self.centralwidget)

        self.menubar = QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 509, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)

        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def p2_clicked(self):
        self.pyqt_clicked1.emit()

    def find_btn(self):
        self.pyqt_clicked2.emit()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.check_sid.setText(_translate("MainWindow", "学号", None))
        # self.check_Sage.setText(_translate("MainWindow", "年龄自", None))
        self.check_sname.setText(_translate("MainWindow", "姓名", None))
        self.check_sgender.setText(_translate("MainWindow", "性别", None))
        # self.label.setText(_translate("MainWindow", "到", None))
        self.check_sdept.setText(_translate("MainWindow", "方向", None))
        self.check_sclass.setText(_translate("MainWindow", "班级", None))
        self.find.setText(_translate("MainWindow", "查询", None))
        self.sql_out.setText(self.sqlString)

        item = self.result_out.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "学号", None))
        item = self.result_out.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "姓名", None))
        item = self.result_out.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "性别", None))
        item = self.result_out.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "班级", None))
        item = self.result_out.horizontalHeaderItem(4)
        item.setText(_translate("MainWindow", "专业方向", None))
        self.pushButton_2.setText(_translate("MainWindow", "退出", None))

    def mousePressEvent(self, event):
        print(">_<")

    def buttonTest(self):
        temp_sqlstring = self.sqlString
        is_first = True
        if self.check_sid.isChecked():
            mystr = self.sid.text()
            if is_first:
                is_first = False
                if mystr.find("%") == -1:
                    temp_sqlstring += "sid='" + self.sid.text() + "'"
                else:
                    temp_sqlstring += "sid like'" + self.sid.text() + "'"
            else:
                if mystr.find("%") == -1:
                    temp_sqlstring += " and sid = '" + self.sid.text() + "'"
                else:
                    temp_sqlstring += " and sid like '" + self.sid.text() + "'"

        if self.check_sname.isChecked():
            if is_first:
                mystr = self.sname.text()
                is_first = False
                if mystr.find("%") == -1:
                    temp_sqlstring += "sname = '" + self.sname.text() + "'"
                else:
                    temp_sqlstring += "sname like '" + self.sname.text() + "'"
            else:
                if mystr.find("%") == -1:
                    temp_sqlstring += " and sname = '" + self.sname.text(
                    ) + "'"
                else:
                    temp_sqlstring += " and sname like '" + self.sname.text(
                    ) + "'"

        if self.check_sgender.isChecked():
            if is_first:
                is_first = False
                temp_sqlstring += "sgender = '" + self.sgender.text() + "'"
            else:
                temp_sqlstring += " and sgender = '" + self.sgender.text(
                ) + "'"

        if self.check_sclass.isChecked():
            if is_first:
                mystr = self.sclass.text()
                is_first = False
                if mystr.find("%") == -1:
                    temp_sqlstring += "sclass = '" + self.sclass.text() + "'"
                else:
                    temp_sqlstring += "sclass like '" + self.sclass.text(
                    ) + "'"
            else:
                if mystr.find("%") == -1:
                    temp_sqlstring += " and sclass = '" + self.sclass.text(
                    ) + "'"
                else:
                    temp_sqlstring += " and sclass like '" + self.sclass.text(
                    ) + "'"

        if self.check_sdept.isChecked():
            if is_first:
                mystr = self.sdept.text()
                is_first = False
                if mystr.find("%") == -1:
                    temp_sqlstring += "sdept = '" + self.sdept.text() + "'"
                else:
                    temp_sqlstring += "sdept like '" + self.sdept.text() + "'"
            else:
                if mystr.find("%") == -1:
                    temp_sqlstring += " and sdept = '" + self.sdept.text(
                    ) + "'"
                else:
                    temp_sqlstring += " and sdept like '" + self.sdept.text(
                    ) + "'"

        self.result_out.clearContents()

        if not (is_first):
            print(temp_sqlstring)
            self.cur.execute(temp_sqlstring)
            k = 0
            for i in self.cur:
                print("------------", i)
                w = 0
                for j in i:
                    if type(j) == int:
                        newItem = QTableWidgetItem(str(j))
                    else:
                        newItem = QTableWidgetItem(j)
                    self.result_out.setItem(k, w, newItem)
                    w += 1
                k += 1

        self.sql_out.setText("")
        self.sql_out.append(temp_sqlstring)
        print("find button pressed")

    def buttonExit(self):
        self.conn.commit()
        self.cur.close()
        self.conn.close()
        self.close()

    def keyPressEvent(self, e):
        if e.key() == QtCore.Qt.key_Escape:
            self.buttonExit()
Ejemplo n.º 27
0
class CrawlWindow(QWidget):
    def __init__(self):
        super(CrawlWindow, self).__init__()
        self.resize(1000, 600)
        self.setWindowTitle('关键词新闻搜索')
        self.setWindowIcon(QIcon(':reson/4.jpg'))

        # 初始化搜索文本框
        self.movie_name = QLineEdit(self)
        # 初始化渠道下拉框
        self.source_combobox = QComboBox(self)
        # 初始化一键搜索按钮
        self.start_btn = QPushButton(self)
        # 初始化开始爬取按钮
        self.get_btn = QPushButton(self)
        # 初始化一键分析按钮
        self.word_cloud = QPushButton(self)
        # 初始化另存下拉框
        self.save_combobox = QComboBox(self)
        # 初始化表格控件
        self.table = QTableWidget(self)
        # 初始化输出文本框
        self.log_browser = QTextBrowser(self)
        # 初始化进度条
        self.progressbar = QProgressBar(self)

        # 初始化水平布局
        self.h_layout = QHBoxLayout()
        # 初始化垂直布局
        self.v_layout = QVBoxLayout()

        # 实例化词云程序
        self.cloud = Cloud()
        # 实例化启动程序
        self.crawl_thread = CrawlThread()
        # 初始化数据库
        self.db = None
        # 初始化音频播放
        self.btn_sound = QSound(':reson/btn.wav', self)
        self.finish_sound = QSound(':reson/finish.wav', self)

        # 实例化
        self.movie_init()
        self.source_init()
        self.btn_init()
        self.combobox_init()
        self.table_init()
        self.word_cloud_init()
        self.log_init()
        self.progressbar_init()
        self.layout_init()
        self.crawl_init()
        # self.db_connect()

    def movie_init(self):
        """搜索文本框默认配置"""
        # 设置文本框尺寸
        self.movie_name.setFixedSize(200, 25)
        # 设置默认文本
        self.movie_name.setPlaceholderText("请输入关键词,不超过十个中文")
        # 限制10个中文字符
        self.movie_name.setMaxLength(10)

    def source_init(self):
        """搜索渠道下拉框配置"""
        save_list = ['搜索渠道选择', '新华网', '新浪新闻', '百度新闻']
        self.source_combobox.addItems(save_list)
        # 设置标签状态为可用
        self.source_combobox.setEnabled(True)

        #  当下拉索引发生改变时发射信号触发绑定的事件
        # self.source_combobox.currentTextChanged.connect(self.combobox_slot)

    def btn_init(self):
        self.start_btn.setText('一键搜索')
        self.get_btn.setText('开始爬取')
        self.get_btn.setEnabled(False)

        self.start_btn.clicked.connect(lambda: self.btn_slot(self.start_btn))
        self.get_btn.clicked.connect(lambda: self.btn_slot(self.get_btn))

    # TODO
    def word_cloud_init(self):
        """一键分析配置"""
        self.word_cloud.setText('一键分析')
        self.word_cloud.setEnabled(False)
        self.word_cloud.clicked.connect(self.word_cloud_slot)

    def combobox_init(self):
        """另存为下拉框配置"""
        save_list = ['另存为', 'MySQL', 'csv', 'txt', 'json']
        self.save_combobox.addItems(save_list)
        # 设置标签状态为不可用
        self.save_combobox.setEnabled(False)

        #  当下拉索引发生改变时发射信号触发绑定的事件
        self.save_combobox.currentTextChanged.connect(self.combobox_slot)  # 1

    def table_init(self):
        self.table.setColumnCount(5)
        self.table.setHorizontalHeaderLabels(['新闻链接', '新闻摘要', '评论信息', '渠道来源', '发布日期'])
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

    def log_init(self):
        """输出文本框配置"""
        # 设置盒子尺寸
        self.log_browser.setMaximumHeight(150)

    def progressbar_init(self):
        """进度条"""
        self.progressbar.setRange(0, 10)
        self.progressbar.setValue(0)

    def layout_init(self):
        """页面布局"""
        self.h_layout.addWidget(self.movie_name)
        self.h_layout.addWidget(self.source_combobox)
        self.h_layout.addWidget(self.start_btn)
        self.h_layout.addWidget(self.get_btn)
        self.h_layout.addWidget(self.word_cloud)
        self.h_layout.addWidget(self.save_combobox)

        self.v_layout.addWidget(self.table)
        self.v_layout.addWidget(self.log_browser)
        self.v_layout.addWidget(self.progressbar)
        self.v_layout.addLayout(self.h_layout)
        self.setLayout(self.v_layout)

    def crawl_init(self):
        self.crawl_thread.total_nums.connect(self.total_nums_slot)
        self.crawl_thread.finished_signal.connect(self.finish_slot)
        self.crawl_thread.log_signal.connect(self.set_log_slot)
        self.crawl_thread.result_signal.connect(self.set_table_slot)

    def btn_slot(self, btn):
        self.btn_sound.play()
        # 点击一键搜索
        if btn == self.start_btn:
            # 判断是否输入关键词
            if self.movie_name.text():
                self.log_browser.clear()
                self.log_browser.append('<font color="red">一键搜索</font>')
                self.log_browser.append('<font color="red">搜索中...</font>')
                self.table.clearContents()
                self.table.setRowCount(0)
                self.get_btn.setEnabled(True)
                self.save_combobox.setEnabled(False)

                self.crawl_thread.render(self.movie_name, self.source_combobox)
                self.crawl_thread.start()
            else:
                self.log_browser.append('<font color="red">请输入搜索关键词!</font>')

        if btn == self.get_btn:
            self.log_browser.append('<font color="red">开始爬取</font>')
            self.get_btn.setEnabled(False)
            self.start_btn.setEnabled(True)
            self.word_cloud.setEnabled(True)
            self.save_combobox.setEnabled(True)

            self.run()

    def word_cloud_slot(self):
        self.cloud.run()

    def total_nums_slot(self, total_nums):
        """搜索到新闻数"""
        total_nums = '本次搜索总找到新闻:{}条'.format(total_nums)
        self.log_browser.append(total_nums)

    def finish_slot(self):
        self.start_btn.setEnabled(True)
        self.get_btn.setEnabled(False)
        self.save_combobox.setEnabled(True)

    def set_log_slot(self, new_log):
        self.log_browser.append(new_log)

    def set_table_slot(self, img, summary, name, star, time):
        row = self.table.rowCount()
        self.table.insertRow(row)

        self.table.setItem(row, 0, QTableWidgetItem(img))
        self.table.setItem(row, 1, QTableWidgetItem(summary))
        self.table.setItem(row, 2, QTableWidgetItem(name))
        self.table.setItem(row, 3, QTableWidgetItem(star))
        self.table.setItem(row, 4, QTableWidgetItem(time))

    def combobox_slot(self, text):
        if text == 'MySQL':
            # self.save_to_MySQL()
            pass
        elif text == 'csv':
            self.save_to_csv()
        elif text == 'txt':
            self.save_to_txt()
        elif text == 'json':
            self.save_to_json()

    # def db_connect(self):
    #     """
    #     SQL配置
    #     db = QtSql.QSqlDatabase.addDatabase('QMYSQL')
    #     db.setHostName('主机名')
    #     db.setDatabaseName('数据库名')
    #     db.setUserName('用户名')
    #     db.setPassword('密码')
    #     db.setPort(3306) # 端口号
    #     db.open() # 判断是否连接数据库成功 返回布尔值
    #     """
    #     # 创建数据库连接并打开
    #     self.db = QSqlDatabase.addDatabase('QMYSQL')
    #     self.db.setHostName('localhost')
    #     self.db.setDatabaseName('news')
    #     self.db.setUserName('root')
    #     self.db.setPassword('raspberry')
    #     if not self.db.open():
    #         QMessageBox.critical(self, 'Database Connection', self.db.lastError().text())

    def closeEvent(self, QCloseEvent):
        self.db.close()

    # def save_to_MySQL(self):
    #     query = QSqlQuery()
    #
    #     # query.exec_("CREATE TABLE IF NOT EXISTS movie "
    #     #             "(img VARCHAR(100), name VARCHAR(50), star VARCHAR(100),"
    #     #             " time VARCHAR(50), score VARCHAR(5))")
    #
    #     for row in range(self.table.rowCount()):
    #         word = self.movie_name.text()
    #         img = self.table.item(row, 0).text()
    #         name = self.table.item(row, 1).text()
    #         star = self.table.item(row, 2).text()
    #         time = self.table.item(row, 3).text()
    #         query.prepare("INSERT INTO words (keyword,new_url,new_tag,new_summary,source) "
    #                       "VALUES (?, ?, ?, ?, ?)")
    #         # sql = 'insert into words(keyword,new_url,new_tag,new_summary,source) VALUES ' \
    #         #       '(%(keyword)s,%(url)s,%(tag)s,%(summary)s,%(source)s)'
    #         # query.bindValue(0, word)
    #         # query.bindValue(1, img)
    #         # query.bindValue(2, name)
    #         # query.bindValue(3, star)
    #         # query.bindValue(4, time)
    #         query.addBindValue(word)
    #         query.addBindValue(img)
    #         query.addBindValue(name)
    #         query.addBindValue(star)
    #         query.addBindValue(time)
    #
    #         query.exec_()
    #
    #     QMessageBox.information(self, '保存到MySQL', '保存成功!', QMessageBox.Ok)

    def save_to_csv(self):
        """保存为scv文件"""
        content = []
        for row in range(self.table.rowCount()):
            img = self.table.item(row, 0).text()
            summary = self.table.item(row, 1).text()
            name = self.table.item(row, 2).text()
            star = self.table.item(row, 3).text()
            time = self.table.item(row, 4).text()
            content.append([img, summary, name, star, time])

        with open('./关键词搜索.csv', 'w', newline='', encoding='utf-8') as f:
            writer = csv.writer(f)
            writer.writerow(['新闻链接', '新闻摘要', '渠道来源', '发布日期', '新闻摘要'])
            writer.writerows(content)

        QMessageBox.information(self, '保存到csv', '保存成功!', QMessageBox.Ok)

    def save_to_txt(self):
        """保存为txt"""
        content = ''
        for row in range(self.table.rowCount()):
            img = '新闻链接:{}\n'.format(self.table.item(row, 0).text())
            summary = '新闻摘要:{}\n'.format(self.table.item(row, 1).text())
            name = '渠道来源:{}\n'.format(self.table.item(row, 2).text())
            star = '发布日期:{}\n'.format(self.table.item(row, 3).text())
            time = '新闻摘要:{}\n'.format(self.table.item(row, 4).text())

            content += img + summary + name + star + time + '\n'

        with open('./关键词搜索新闻.txt', 'w', encoding='utf-8') as f:
            f.write(content)

        QMessageBox.information(self, '保存到txt', '保存成功!', QMessageBox.Ok)

    def save_to_json(self):
        """保存为json文件"""
        content = []
        for row in range(self.table.rowCount()):
            img = self.table.item(row, 0).text()
            summary = self.table.item(row, 1).text()
            name = self.table.item(row, 2).text()
            star = self.table.item(row, 3).text()
            time = self.table.item(row, 4).text()
            content.append(
                {
                    '新闻链接': img,
                    '新闻摘要': summary,
                    '渠道来源': name,
                    '评论内容': star,
                    '发布日期': time,
                }
            )

        with open('./关键词搜索新闻.json', 'w', encoding='utf-8') as f:
            json.dump(content, f, ensure_ascii=False)

        QMessageBox.information(self, '保存到json', '保存成功!', QMessageBox.Ok)

    def run(self):
        """根据url爬取数据"""

        for row in range(self.table.rowCount()):
            new_url = self.table.item(row, 0).text()
            self.log_browser.append('开始爬取:{}'.format(new_url))

            self.progressbar.setValue(row + 1)
            if self.progressbar.value() == 10:
                self.finish_sound.play()
        self.log_browser.append('<font color="red">全部爬取完毕!</font>')
Ejemplo n.º 28
0
class AdminWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.table = QTableWidget(self)  # 添加表格对象
        self.database = Database('./data.db')
        self.check_list = []  # 保存所有的选择框
        self.show_password_flag = False  # 是否显示原密码
        self.select_all_flag = False  # 是否选择全部
        self.main_window = None
        self.set_ui()

    def set_main_window(self, widget):
        self.main_window = widget

    def set_ui(self):
        self.setWindowTitle("Management page")
        self.setFixedSize(1200, 900)  # 配合图片大小设定的值
        self.font = QFont("Consolas")
        self.setFont(self.font)
        self.setWindowIcon(QIcon("./IMG/python-logo.png"))  # 设置图标
        self.add_table()  # 添加数据表格
        self.get_all_user()  # add table 之后才有show
        self.add_line_edit()  # 添加输入框
        self.add_label()  # 添加标签
        self.add_button()  # 添加按钮并绑定事件

    # 添加数据表格
    def add_table(self):
        self.table.setFixedWidth(1020)  # 设置宽度
        self.table.setFixedHeight(600)  # 设置高度
        self.table.move(10, 30)  # 设置显示的位置
        self.table.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)  # 自动填充
        self.table.horizontalHeader().setFont(self.font)  # 设置一下字体
        # self.table.setSelectionMode(QAbstractItemView.SingleSelection)  # 只能单选
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)  # 只能选择整行
        self.table.setColumnCount(4)  # 设置列数
        self.table.setHorizontalHeaderLabels(
            ["Choice", "username", "password", 'created_time'])  # 设置首行
        self.table.setEditTriggers(
            QAbstractItemView.NoEditTriggers)  # 表格中的内容设置为无法修改
        self.table.verticalHeader().hide()  # 把序号隐藏
        self.table.setSortingEnabled(False)  # 自动排序

    # 获取所有的用户信息
    def get_all_user(self):
        data = self.database.read_table(
        )  # 从数据库中获取用户信息,用户信息以 username, password, created_time 形式返回
        for user in data:
            self.add_row(user[0], user[1], user[2])

    # 在表格上添加一行新的内容
    def add_row(self, username, password, created_time):
        row = self.table.rowCount()  # 表格的行数
        self.table.setRowCount(row + 1)  # 添加一行表格
        self.table.setItem(row, 1,
                           QTableWidgetItem(str(username)))  # 将用户信息插入到表格中
        self.table.setItem(row, 2, QTableWidgetItem(str(password)))
        self.table.setItem(row, 3, QTableWidgetItem(str(created_time)))
        # 设置复选框
        widget = QWidget()
        check = QCheckBox()
        self.check_list.append(check)  # 添加到复选框列表中
        check_lay = QHBoxLayout()
        check_lay.addWidget(check)
        check_lay.setAlignment(Qt.AlignCenter)
        widget.setLayout(check_lay)
        self.table.setCellWidget(row, 0, widget)

    def add_line_edit(self):
        self.username_edit = QLineEdit(self)
        self.username_edit.setFixedSize(240, 40)
        self.username_edit.move(760, 700)
        self.username_edit.setPlaceholderText('username')

        self.password_edit = QLineEdit(self)
        self.password_edit.setFixedSize(240, 40)
        self.password_edit.move(760, 760)
        self.password_edit.setPlaceholderText('password')
        self.password_edit.setEchoMode(QLineEdit.Password)

        # 更新密码的输入框
        self.update_username_edit = QLineEdit(self)
        self.update_username_edit.setFixedSize(240, 40)
        self.update_username_edit.move(160, 700)
        self.update_username_edit.setPlaceholderText('username')

        self.update_password_edit = QLineEdit(self)
        self.update_password_edit.setFixedSize(240, 40)
        self.update_password_edit.move(160, 760)
        self.update_password_edit.setPlaceholderText('new password')

    def show_password(self):
        if self.show_password_flag:  # 如果是真,隐藏密码
            self.password_edit.setEchoMode(QLineEdit.Password)
            self.show_password_flag = False
            self.show_password_button.setText('Show')
        else:  # 否则显示密码
            self.password_edit.setEchoMode(QLineEdit.Normal)
            self.show_password_flag = True
            self.show_password_button.setText("Hide")

    # 添加界面上的标签控件
    def add_label(self):
        self.username_label = QLabel(self)
        self.username_label.setFixedSize(160, 40)
        self.username_label.move(640, 700)
        self.username_label.setText('username')

        self.password_label = QLabel(self)
        self.password_label.setFixedSize(160, 40)
        self.password_label.move(640, 760)
        self.password_label.setText('password')

        # 更新密码的标签
        self.update_username_label = QLabel(self)
        self.update_username_label.setFixedSize(160, 40)
        self.update_username_label.move(40, 700)
        self.update_username_label.setText('username')

        self.update_password_label = QLabel(self)
        self.update_password_label.setFixedSize(160, 40)
        self.update_password_label.move(40, 760)
        self.update_password_label.setText('password')

    # 添加界面上的按钮控件
    def add_button(self):
        # 创建按钮对象
        self.delete_button = QPushButton(self)
        self.update_button = QPushButton(self)
        self.add_button_ = QPushButton(self)
        self.show_password_button = QPushButton(self)
        self.clear_button = QPushButton(self)
        self.select_all_button = QPushButton(self)
        self.refresh_button = QPushButton(self)
        self.main_window_button = QPushButton(self)

        # 设置按钮上的文本
        self.delete_button.setText("Delete")
        self.update_button.setText("Update")
        self.add_button_.setText("Add")
        self.show_password_button.setText("Show")
        self.clear_button.setText("Clear")
        self.select_all_button.setText("Select All")
        self.refresh_button.setText("Refresh")
        self.main_window_button.setText("Main window")

        # 在按钮上设置提示信息
        self.delete_button.setToolTip(
            "Delete the selected user, you can choose multiple users")
        self.clear_button.setToolTip(
            "Clear all the users, including the super user, but the super user will be "
            "created later by default")
        self.select_all_button.setToolTip(
            "Select all the users, including the super user")
        self.show_password_button.setToolTip("Show or hide the password")
        self.add_button_.setToolTip(
            "Add a new user with the username and password in the input box")
        self.update_button.setToolTip(
            "Update the password with the chosen username")
        self.refresh_button.setToolTip("Click here to refresh the table")
        self.main_window_button.setToolTip(
            "Click here and you will go to the user interface")

        # 控制位置
        self.delete_button.move(1040, 340)
        self.select_all_button.move(1040, 280)
        self.clear_button.move(1040, 400)
        self.refresh_button.move(1040, 460)

        self.update_button.move(430, 700)
        self.add_button_.move(1020, 700)
        self.show_password_button.move(1020, 750)

        self.main_window_button.move(500, 820)

        # 绑定事件
        self.delete_button.clicked.connect(self.delete_user)
        self.select_all_button.clicked.connect(self.select_all)
        self.clear_button.clicked.connect(self.clear)
        self.show_password_button.clicked.connect(self.show_password)
        self.add_button_.clicked.connect(self.add_user)
        self.update_button.clicked.connect(self.update_password)
        self.refresh_button.clicked.connect(self.refresh)
        self.main_window_button.clicked.connect(self.show_main_window)

        self.main_window_button.setFixedSize(200, 40)

    def show_main_window(self):
        self.main_window.show()

    def delete_user(self):
        choose_list = []
        for i in self.check_list:
            if i.isChecked():
                username = self.table.item(self.check_list.index(i), 1).text()
                if username == 'admin':
                    answer = QMessageBox.critical(
                        self, 'Error',
                        'You are going to delete the super user, but it will be created later with the default password',
                        QMessageBox.Yes | QMessageBox.Cancel,
                        QMessageBox.Cancel)
                    if answer == QMessageBox.Yes:
                        choose_list.append(i)
                    if answer == QMessageBox.Cancel:
                        return
                else:
                    choose_list.append(i)

        for i in choose_list:
            username = self.table.item(self.check_list.index(i), 1).text()
            self.database.delete_table_by_username(username)
            self.table.removeRow(self.check_list.index(i))
            self.check_list.remove(i)
        self.database.create_table()

    # 选择是否选择全部
    def select_all(self):
        try:
            if not self.select_all_flag:
                for check in self.check_list:
                    check.setCheckState(2)  # 设置为选择状态
                self.select_all_button.setText("Unselect")
                self.select_all_flag = True
            else:
                for check in self.check_list:
                    check.setCheckState(0)  # 设置为未选状态
                self.select_all_button.setText("Select All")
                self.select_all_flag = False
        except:  # 该错误是由于没有复选框引起
            pass

    # 一行一行的添加数据
    def add_user(self):
        username = self.username_edit.text()
        password = self.password_edit.text()
        if all((username, password)):
            flag = self.database.insert_table(username, password)
            if flag:
                QMessageBox.critical(
                    self, 'Error',
                    'Already exists the username {}, please use another username'
                    .format(username))
            else:
                self.add_row(username, password, self.database.get_time())
            self.username_edit.setText('')  # 清空输入的用户信息
            self.password_edit.setText('')
        else:
            QMessageBox.critical(self, 'Error', "Please fill in the blanks")

    # 清空所有的数据,包括数据库和表格中的数据
    def clear(self):
        self.table.clearContents()  # 清空表格的内容
        self.table.setRowCount(0)  # 将表格的行数重置为0
        self.database.clear()  # 清空数据库数据

    # 更新密码
    def update_password(self):
        username = self.update_username_edit.text()
        password = self.update_password_edit.text()
        if len(password) >= 6:
            self.database.update_table(username, password)
            self.change_table(username, password)
            self.update_password_edit.setText('')
            self.update_username_edit.setText('')
        else:
            QMessageBox.information(self, 'Error',
                                    'Password is too short, at least 6 words',
                                    QMessageBox.Yes, QMessageBox.Yes)

    # 更新表格
    def change_table(self, username, password):
        find_flag = False
        for row in range(self.table.rowCount()):
            username_find = self.table.item(row, 1).text()
            if username_find == username:
                self.table.item(row, 2).setText(password)
                find_flag = True
                break
        if not find_flag:  # 如果没有找到对应的用户名
            QMessageBox.information(
                self, 'prompt',
                'Can not find the username {}'.format(username))

    # 重新加载数据库并显示
    def refresh(self):
        self.table.clearContents()
        self.check_list.clear()
        self.table.setRowCount(0)
        self.database.create_table()
        self.get_all_user()
Ejemplo n.º 29
0
class WidgetGallery(QDialog):
    def __init__(self, parent=None):
        super(WidgetGallery, self).__init__(parent)
        self.resize(1000, 750)
        self.fileName = None
        self.ppfile = None
        self.abafile = None
        self.syncfile = None
        self.segfile = None
        self.poifile = None
        self.key = None
        self.ppdata = 0.0
        self.output = np.array([])
        self.counter = 0
        self.initUI()

    def initUI(self):

        self.setWindowIcon(QIcon('srail.jpg'))
        self.originalPalette = QApplication.palette()
        styleComboBox = QComboBox()
        styleComboBox.addItems(QStyleFactory.keys())
        styleLabel = QLabel("&Style:")
        styleLabel.setBuddy(styleComboBox)

        self.useStylePaletteCheckBox = QCheckBox(
            "&Use style's standard palette")
        self.useStylePaletteCheckBox.setChecked(True)

        disableWidgetsCheckBox = QCheckBox("&Disable widgets")

        self.createTopLeftGroupBox()
        self.createTopRightGroupBox()
        self.createBottomLeftTabWidget(self.output)
        self.createBottomRightGroupBox()
        # self.createProgressBar()

        styleComboBox.activated[str].connect(self.changeStyle)
        self.useStylePaletteCheckBox.toggled.connect(self.changePalette)
        disableWidgetsCheckBox.toggled.connect(
            self.topLeftGroupBox.setDisabled)
        disableWidgetsCheckBox.toggled.connect(
            self.topRightGroupBox.setDisabled)
        disableWidgetsCheckBox.toggled.connect(
            self.bottomLeftTabWidget.setDisabled)
        disableWidgetsCheckBox.toggled.connect(
            self.bottomRightGroupBox.setDisabled)

        topLayout = QHBoxLayout()
        topLayout.addWidget(styleLabel)
        topLayout.addWidget(styleComboBox)
        topLayout.addStretch(0)
        topLayout.addWidget(self.useStylePaletteCheckBox)
        topLayout.addWidget(disableWidgetsCheckBox)

        mainLayout = QGridLayout()
        mainLayout.addLayout(topLayout, 0, 0, 1, 2)
        mainLayout.addWidget(self.topLeftGroupBox, 1, 0)
        mainLayout.addWidget(self.topRightGroupBox, 1, 1)
        mainLayout.addWidget(self.bottomLeftTabWidget, 2, 0)
        mainLayout.addWidget(self.bottomRightGroupBox, 2, 1)
        # mainLayout.addWidget(self.progressBar, 3, 0, 1, 2)
        mainLayout.setRowStretch(1, 1)
        mainLayout.setRowStretch(2, 1)
        mainLayout.setColumnStretch(0, 1)
        mainLayout.setColumnStretch(1, 1)
        self.setLayout(mainLayout)

        self.setWindowTitle("RAIL CONDITION MONITORING SYSTEM")
        self.changeStyle('Fusion')
        self.setWindowFlags(Qt.WindowCloseButtonHint
                            | Qt.WindowMinimizeButtonHint)

    def changeStyle(self, styleName):
        QApplication.setStyle(QStyleFactory.create(styleName))
        self.changePalette()

    def changePalette(self):
        if (self.useStylePaletteCheckBox.isChecked()):
            QApplication.setPalette(QApplication.style().standardPalette())
        else:
            QApplication.setPalette(self.originalPalette)

    def advanceProgressBar(self):
        curVal = self.progressBar.value()
        maxVal = self.progressBar.maximum()
        self.progressBar.setValue(curVal + (maxVal - curVal) / 100)

    def createTopLeftGroupBox(self):
        self.topLeftGroupBox = QGroupBox("Pre-processing")

        radioButton1 = QRadioButton("Radio button 1")
        loadabaButton = QPushButton("Browse")
        loadsyncButton = QPushButton("Browse")
        loadsegButton = QPushButton("Browse")
        loadpoiButton = QPushButton("Browse")
        radioButton1.setChecked(True)

        checkBox = QCheckBox("Tri-state check box")
        checkBox.setTristate(True)
        checkBox.setCheckState(Qt.PartiallyChecked)

        loadabaButton.clicked.connect(self.browse_aba)
        loadsyncButton.clicked.connect(self.browse_sync)
        loadsegButton.clicked.connect(self.browse_seg)
        loadpoiButton.clicked.connect(self.browse_poi)

        self.abaEdit = QLineEdit()
        self.abaEdit.setText("ABA file")
        self.abaEdit.setReadOnly(True)
        self.syncEdit = QLineEdit()
        self.syncEdit.setReadOnly(True)
        self.syncEdit.setText("SYNC file")
        self.segEdit = QLineEdit()
        self.segEdit.setText("SEG file")
        self.segEdit.setReadOnly(True)
        self.poiEdit = QLineEdit()
        self.poiEdit.setText("POI file")
        self.poiEdit.setReadOnly(True)

        self.pprocessButton = QPushButton("Start")
        self.pprocessButton.setStyleSheet("height: 15px;width: 24px;")
        self.pprocessButton.clicked.connect(self.processing)
        self.pprocessButton.setToolTip('Click to start pre-processing')

        self.savefileButton = QPushButton("Save")
        self.savefileButton.setStyleSheet("height: 15px;width: 24px;")
        self.savefileButton.clicked.connect(self.save_pdata)
        self.savefileButton.setToolTip("Click to save the results")
        self.savefileButton.setVisible(False)

        layout = QFormLayout()
        layout.addRow(loadabaButton, self.abaEdit)
        layout.addRow(loadsyncButton, self.syncEdit)
        layout.addRow(loadsegButton, self.segEdit)
        layout.addRow(loadpoiButton, self.poiEdit)
        layout.addWidget(self.pprocessButton)
        layout.addWidget(self.savefileButton)

        self.topLeftGroupBox.setLayout(layout)

    def createTopRightGroupBox(self):

        self.topRightGroupBox = QGroupBox("Anomaly detection")

        loadpfileButton = QPushButton("Browse")
        loadpfileButton.clicked.connect(self.browse_file)

        self.processedEdit = QLineEdit()
        self.processedEdit.setText("Pre-processed file")
        self.processedEdit.setReadOnly(True)

        loadsegButton = QPushButton("Browse")
        loadsegButton.clicked.connect(self.browse_seg1)

        self.segEdit1 = QLineEdit()
        self.segEdit1.setText("SEG file")
        self.segEdit1.setReadOnly(True)

        self.fqbox = QComboBox()
        self.fqbox.addItems([
            'RMS', 'Kurtosis', 'Crest factor', 'Impulse factor', 'Skewness',
            'Peak-to-peak', 'All'
        ])
        self.fqbox.currentIndexChanged.connect(self.selection_change)

        self.swinqbox = QComboBox()
        self.swinqbox.addItems([
            '500', '1000', '1500', '2000', '2500', '3000', '3500', '4000',
            '5000', '500'
        ])
        self.swinqbox.currentIndexChanged.connect(self.selection_change)

        swinsbox = QSpinBox()
        swinsbox.stepBy(1000)
        swinsbox.setMinimum(1000)
        swinsbox.setMaximum(6000)

        self.detectanomButton = QPushButton("Start")
        self.detectanomButton.setStyleSheet("height: 15px;width: 24px;")
        self.detectanomButton.clicked.connect(self.detect_anomalies)
        self.detectanomButton.setToolTip("Click to start anomaly detection")

        self.saveButton = QPushButton("Save")
        self.saveButton.setStyleSheet("height: 15px;width: 24px;")
        self.saveButton.clicked.connect(self.save_results)
        self.saveButton.setToolTip("Click to save the results")
        self.saveButton.setVisible(False)

        layout = QFormLayout()
        layout.addRow(loadpfileButton, self.processedEdit)
        layout.addRow(loadsegButton, self.segEdit1)
        layout.addRow(QLabel("No. of features:"), self.fqbox)
        layout.addRow(QLabel("Sliding window:"), self.swinqbox)
        layout.addWidget(self.detectanomButton)
        layout.addWidget(self.saveButton)

        self.topRightGroupBox.setLayout(layout)

    def createBottomLeftTabWidget(self, output):

        self.bottomLeftTabWidget = QTabWidget()
        self.bottomLeftTabWidget.setSizePolicy(QSizePolicy.Preferred,
                                               QSizePolicy.Ignored)

        tab1 = QWidget()
        self.tableWidget = QTableWidget(100, 3)
        self.tableWidget.setHorizontalHeaderLabels(
            ['Position(km)', 'Counter', 'Severity'])

        tab1hbox = QHBoxLayout()
        tab1hbox.setContentsMargins(3, 3, 3, 3)
        tab1hbox.addWidget(self.tableWidget)
        tab1.setLayout(tab1hbox)

        tab2 = QWidget()
        textEdit = QTextEdit()
        textEdit.isReadOnly()
        textEdit.setPlainText(
            "Train axle-box acceleration data\n"
            "has been used to find incipient defects\n"
            "rail defects.\n\n"
            "Blue color in results represents incipient ABA anomaly.\n"
            "Yellow color in results represents intermediate ABA anomaly.\n"
            "Red color in results represents severe ABA anomaly.\n")

        tab2hbox = QHBoxLayout()
        tab2hbox.setContentsMargins(5, 5, 5, 5)
        tab2hbox.addWidget(textEdit)
        tab2.setLayout(tab2hbox)

        self.bottomLeftTabWidget.addTab(tab1, "&Results")
        self.bottomLeftTabWidget.addTab(tab2, "Description")

    def createBottomRightGroupBox(self):
        self.bottomRightGroupBox = QGroupBox("Model parameters")
        self.bottomRightGroupBox.setCheckable(True)
        self.bottomRightGroupBox.setChecked(True)

        self.tbox = QComboBox()
        self.tbox.addItems(['25', '50', '100', '150', '200', '250'])
        self.tbox.currentIndexChanged.connect(self.selection_change)

        self.ispinBox = QSpinBox(self.bottomRightGroupBox)
        self.ispinBox.setValue(0)
        self.ispinBox.setMinimum(0)
        self.ispinBox.setMaximum(15)
        self.ispinBox.valueChanged.connect(self.selection_change)

        self.stbox = QComboBox()
        self.stbox.addItems(['16', '32', '64', '128', '256', '512'])
        self.stbox.currentIndexChanged.connect(self.selection_change)

        slider = QSlider(Qt.Horizontal, self.bottomRightGroupBox)
        slider.setValue(40)
        slider.show()

        layout = QGridLayout()
        layout.addWidget(QLabel("Impurity ratio (%):"), 0, 0, 1, 3)
        layout.addWidget(self.ispinBox, 0, 1, 1, 3)
        layout.addWidget(QLabel("Sub-sampling size:"), 1, 0, 1, 3)
        layout.addWidget(self.stbox, 1, 1, 1, 3)
        layout.addWidget(QLabel("No. of trees:"), 2, 0, 1, 3)
        layout.addWidget(self.tbox, 2, 1, 1, 3)
        layout.addWidget(slider, 3, 0, 1, 4)
        # layout.setRowStretch(5, 1)
        self.bottomRightGroupBox.setLayout(layout)

    def createProgressBar(self):
        self.progressBar = QProgressBar()
        self.progressBar.setRange(0, 10000)
        self.progressBar.setValue(0)

        timer = QTimer(self)
        timer.timeout.connect(self.advanceProgressBar)
        timer.start(1000)


# ///////////////////// System functions /////////////////////////

    def openFileNameDialog(self, type=None):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self,
            "QFileDialog.getOpenFileName()",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)

        if fileName:
            if self.type == 'anomaly' and not str(fileName).endswith('.h5'):
                msg = QMessageBox()
                msg.setIcon(QMessageBox.Critical)
                msg.setText("File Error")
                msg.setInformativeText(
                    'Please select the file with .h5 format!')
                msg.setWindowTitle("Error")
                msg.exec_()

            elif self.type != 'anomaly' and not str(fileName).endswith('.csv'):
                if self.type == 'aba' and not str(fileName).endswith('.h5'):
                    msg = QMessageBox()
                    msg.setIcon(QMessageBox.Critical)
                    msg.setText("File Error")
                    msg.setInformativeText(
                        'Please select the file with .h5 format!')
                    msg.setWindowTitle("Error")
                    msg.exec_()
                elif self.type != 'aba':
                    msg = QMessageBox()
                    msg.setIcon(QMessageBox.Critical)
                    msg.setText("File Error")
                    msg.setInformativeText(
                        'Please select the file with .csv format!')
                    msg.setWindowTitle("Error")
                    msg.exec_()

        if self.type == 'anomaly':
            print(fileName)
            self.ppfile = fileName
            self.processedEdit.setText(str(fileName))

        elif self.type == 'aba':
            print(fileName)
            self.abafile = fileName
            self.abaEdit.setText(str(fileName))
            # self.tableWidget.setItem(0, 1, QTableWidgetItem(str(123)))
            # self.close()
        elif self.type == 'sync':
            print(fileName)
            self.syncfile = fileName
            self.syncEdit.setText(str(fileName))
        elif self.type == 'poi':
            print(fileName)
            self.poifile = fileName
            self.poiEdit.setText(str(fileName))
        elif self.type == 'seg':
            print(fileName)
            self.segfile = fileName
            self.segEdit.setText(str(fileName))
        elif self.type == 'seg1':
            print(fileName)
            self.segfile = fileName
            self.segEdit1.setText(str(fileName))

    def openFileNamesDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self,
            "QFileDialog.getOpenFileNames()",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)

        if files:
            print(files)
            self.close()

    def saveFileDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getSaveFileName(
            self,
            "QFileDialog.getSaveFileName()",
            "",
            "All Files (*); MS Excel Files (*.csv); ; hdf5 (*.h5)",
            options=options)

        if fileName:
            print(fileName)
            self.savefile = fileName

    def selection_change(self):

        self.feature = self.fqbox.currentText()
        print(self.feature)
        self.swin = int(self.swinqbox.currentText())
        self.impurity = float(self.ispinBox.value() / 100)
        print(self.impurity)
        self.sssize = int(self.stbox.currentText())
        self.trees = int(self.tbox.currentText())

    def processing(self):

        if self.abafile and self.syncfile and self.segfile and self.poifile:

            self.ppdata = pre_processing(self.abafile, self.syncfile,
                                         self.segfile, self.poifile, None)
            self.savefileButton.setVisible(True)
            self.pprocessButton.setVisible(False)
            self.abaEdit.setText("ABA file")
            self.syncEdit.setText("SYNC file")
            self.segEdit.setText("SEG file")
            self.poiEdit.setText("POI file")

        else:
            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText("File Error")
            msg.setInformativeText('Please load all the required files...')
            msg.setWindowTitle("File missing!")
            msg.exec_()

    def detect_anomalies(self):

        if self.ppfile == None:

            msg = QMessageBox()
            msg.setIcon(QMessageBox.Critical)
            msg.setText("File Error")
            msg.setInformativeText('Please load the pre-processed file!')
            msg.setWindowTitle("Error")
            msg.exec_()
        else:
            obj = RailDefects(1)
            self.output = obj.anomaly_detection(self.ppfile, self.segfile,
                                                self.feature, self.swin,
                                                self.sssize, self.impurity)
            loc = self.output[0, 0]
            cnt = self.output[0, 1]
            sev = self.output[0, 2]
            print("First Anomaly: ", loc, cnt, sev)
            # self.output = np.array([[2], [3], [5]])
            self.saveButton.setVisible(True)
            self.detectanomButton.setVisible(False)
            self.processedEdit.setText("Pre-processed file")
            self.segEdit.setText("SEG file")

            # Populate the table
            if len(self.output) > 0:
                for i in range(75):
                    for j in range(3):
                        val = self.output[i, j]
                        print("Value:", val)
                        self.tableWidget.setItem(i, j,
                                                 QTableWidgetItem(str(val)))
                        if j == 2:
                            if self.output[i, 2] <= 0.4:
                                self.tableWidget.item(i, 2).setBackground(
                                    QColor(Qt.blue))
                            elif self.output[i, 2] > 0.4 and self.output[
                                    i, 2] <= 0.75:
                                self.tableWidget.item(i, 2).setBackground(
                                    QColor(Qt.yellow))
                            else:
                                self.tableWidget.item(i, 2).setBackground(
                                    QColor(Qt.red))

    def browse_aba(self):

        self.type = 'aba'
        self.openFileNameDialog(self.type)

    def browse_sync(self):

        self.type = 'sync'
        self.openFileNameDialog(self.type)

    def browse_poi(self):

        self.type = 'poi'
        self.openFileNameDialog(self.type)

    def browse_seg(self):

        self.type = 'seg'
        self.openFileNameDialog(self.type)

    def browse_seg1(self):

        self.type = 'seg1'
        self.openFileNameDialog(self.type)

    def browse_file(self):

        self.type = 'anomaly'
        self.openFileNameDialog(self.type)

    def save_results(self):

        self.key = None
        self.saveFileDialog()

        with open(self.savefile + '.csv', 'w', newline='') as file:
            try:
                writer = csv.writer(file,
                                    delimiter=',',
                                    quotechar='"',
                                    quoting=csv.QUOTE_MINIMAL)
                writer.writerow(['positions', 'counters', 'severity'])
                for pos, cnt, sev in self.output:
                    writer.writerow([pos, cnt, sev])
            finally:
                file.close()

        self.detectanomButton.setVisible(True)
        self.saveButton.setVisible(False)
        self.tableWidget.clearContents()

    def save_pdata(self):

        self.key = 'processed'
        self.saveFileDialog()
        self.ppdata.to_hdf(self.savefile + '.h5', key='processed', mode='w')
        self.pprocessButton.setVisible(True)
        self.savefileButton.setVisible(False)
Ejemplo n.º 30
0
class LocationItemDlg(QDialog):
    def __init__(self, item=None, position=None, scene=None, parent=None):
        super(QDialog, self).__init__(parent)
        self.parentForm = parent
        self.item = item
        self.position = position
        self.scene = scene

        self.ediEquation = QTextEdit()
        self.ediEquation.setAcceptRichText(True)
        self.ediEquation.setTabChangesFocus(True)
        lblEquation = QLabel("Equations:")
        lblEquation.setBuddy(self.ediEquation)

        self.txtLocationName = QLineEdit()
        lblLocationName = QLabel("LocationName:")
        lblLocationName.setBuddy(self.txtLocationName)

        self.isNameAbove = QCheckBox()
        lblIsNameAbove = QLabel("IsNameAbove")
        lblIsNameAbove.setBuddy(self.isNameAbove)

        self.isInitial = QCheckBox()
        lblIsInitial = QLabel("IsInitial")
        lblIsInitial.setBuddy(self.isInitial)

        self.isEnd = QCheckBox()
        lblIsEnd = QLabel("IsEnd")
        lblIsEnd.setBuddy(self.isEnd)

        self.txtInvariant = QLineEdit()
        lblInvariant = QLabel("Invariant:")
        lblInvariant.setBuddy(self.txtInvariant)

        self.figEquation = Figure(figsize=(3, 1))
        self.canvEquation = FigureCanvas(self.figEquation)

        lblCanvEquation = QLabel("Format(Equations):")
        lblCanvEquation.setBuddy(self.canvEquation)

        self.ediSymEquation = QTextEdit()
        self.ediSymEquation.setAcceptRichText(True)
        self.ediSymEquation.setTabChangesFocus(False)
        lblSymEquation = QLabel("Sympy(Equations):")
        lblSymEquation.setBuddy(self.ediSymEquation)

        self.txtCheckPointSeq = QLineEdit()
        lblCheckPointSeq = QLabel("CheckPoint Seq:")
        lblCheckPointSeq.setBuddy(self.txtCheckPointSeq)

        self.cmbVariableName = QComboBox()
        self.dicVariableList = [
            key for key in parent.dicVariable.keys()
            if parent.dicVariable[key].isConstant == False
        ]

        self.cmbVariableName.addItems(self.dicVariableList)
        lblVariableName = QLabel("variableName:")
        lblVariableName.setBuddy(self.cmbVariableName)

        self.txtValue = QLineEdit()
        lblValue = QLabel("Value:")
        lblValue.setBuddy(self.txtValue)

        btnAddCheckPoint = QPushButton("&Save CheckPoint")
        btnAddCheckPoint.clicked.connect(self.SaveCheckPoint)

        btnRemoveCheckPoint = QPushButton("&Remove CheckPoint")
        btnRemoveCheckPoint.clicked.connect(self.RemoveCheckPoint)

        #self.EdgeWidget.resizeColumnsToContents()
        self.VariablesWidget = QTableWidget()
        # setup table widget
        self.VariablesWidget.itemDoubleClicked.connect(
            self.VariablesWidgetDoubleClicked)
        self.VariablesWidget.setColumnCount(3)
        self.VariablesWidget.setHorizontalHeaderLabels(
            ['Seq', 'Variable', 'Value'])

        #self.figInvariant = Figure(figsize=(5, 0.4))

        #self.canvInvariant  = FigureCanvas(self.figInvariant)

        #lblCanvInvariant = QLabel("&Format(Invariant):")
        #lblCanvInvariant.setBuddy(self.canvInvariant)
        btnDelete = QPushButton("Delete Location")
        btnDelete.clicked.connect(self.delete)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        #self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        self.isNameAbove.setChecked(True)
        if self.item is not None:
            self.ediEquation.setPlainText("\n".join(self.item.equation))
            self.txtLocationName.setText(self.item.boxName)
            self.isInitial.setChecked(self.item.isInitial)
            self.isEnd.setChecked(self.item.isEnd)
            self.isNameAbove.setChecked(self.item.isNameAbove)
            self.txtInvariant.setText(self.item.invariant)
            self.SetVariableWdigetAll(self.item.checkPoints)

        layout = QGridLayout()
        layout.addWidget(lblEquation, 0, 0)
        layout.addWidget(self.ediEquation, 1, 0, 1, 8)
        layout.addWidget(lblLocationName, 2, 0)
        layout.addWidget(self.txtLocationName, 2, 1, 1, 2)
        layout.addWidget(lblIsNameAbove, 2, 3)
        layout.addWidget(self.isNameAbove, 2, 4, 1, 2)
        layout.addWidget(lblIsInitial, 3, 0)
        layout.addWidget(self.isInitial, 3, 1)
        layout.addWidget(lblIsEnd, 3, 2)
        layout.addWidget(self.isEnd, 3, 3)
        layout.addWidget(lblInvariant, 4, 0)
        layout.addWidget(self.txtInvariant, 4, 1, 1, 7)

        layout.addWidget(lblCanvEquation, 5, 0)
        layout.addWidget(self.canvEquation, 6, 0, 3, 8)

        layout.addWidget(lblSymEquation, 10, 0)
        layout.addWidget(self.ediSymEquation, 11, 0, 1, 8)
        #layout.addWidget(lblCanvInvariant, 10, 0)
        #layout.addWidget(self.canvInvariant, 10,1, 1, 5)
        layout.addWidget(self.buttonBox, 12, 0, 1, 6)
        layout.addWidget(btnDelete, 12, 7)
        self.setLayout(layout)

        layout.addWidget(lblCheckPointSeq, 13, 0)
        layout.addWidget(self.txtCheckPointSeq, 13, 1)
        layout.addWidget(lblVariableName, 13, 2)
        layout.addWidget(self.cmbVariableName, 13, 3)
        layout.addWidget(lblValue, 13, 4)
        layout.addWidget(self.txtValue, 13, 5)

        layout.addWidget(btnAddCheckPoint, 13, 6)
        layout.addWidget(btnRemoveCheckPoint, 13, 7)

        layout.addWidget(self.VariablesWidget, 14, 0, 1, 8)

        self.VariablesWidget.setSelectionMode(
            QAbstractItemView.SingleSelection)
        #self.VariablesWidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.VariablesWidget.setSelectionBehavior(
            QAbstractItemView.SelectItems)
        self.VariablesWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.ediEquation.textChanged.connect(self.updateUi)
        self.txtInvariant.textChanged.connect(self.updateUi)

        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.resize(900, 1000)
        #self.buttonBox.button(QDialogButtonBox.Reset).clicked.connect(self.apply)

        self.setWindowTitle(
            "{0} Location Item".format("Add" if self.item is None else "Edit"))
        self.updateUi()

    def delete(self):
        self.parentForm.deleteText(self.item)
        self.parentForm.setDirty()
        QDialog.accept(self)

    def updateUi(self):
        self.apply()

    def SetVariableWdigetAll(self, checkPoints):
        self.VariablesWidget.clearContents()
        self.VariablesWidget.setRowCount(0)
        for strSeq in sorted(checkPoints.keys()):
            #for key in sorted(mydict.iterkeys()):

            self.AddCheckPoint(checkPoints[strSeq])

    def SaveCheckPoint(self):
        if not self.txtCheckPointSeq.text():
            QMessageBox.question(
                self, "CheckPoint Seq Is None",
                "Fail to Save,Please input a CheckPoint Seq!", QMessageBox.Ok)
            return
        if not self.cmbVariableName.currentText():
            QMessageBox.question(
                self, "CheckPoint variable Name Is None",
                "Fail to Save,Please select  a variable name!", QMessageBox.Ok)
            return
        if not self.txtValue.text():
            QMessageBox.question(
                self, "CheckPoint Value Is None",
                "Fail to Save,Please input a CheckPoint Value!",
                QMessageBox.Ok)
            return
        checkPoint = {
            "boxName": self.txtCheckPointSeq.text(),
            "VariableName": self.cmbVariableName.currentText(),
            "Value": self.txtValue.text()
        }
        self.UpdateCheckPoint(checkPoint)

    def AddCheckPoint(self, checkPoint):
        rowCount = self.VariablesWidget.rowCount()

        row_index = self.VariablesWidget.rowCount()
        self.VariablesWidget.insertRow(row_index)
        row_index = row_index
        self.VariablesWidget.setItem(
            row_index, 0, QTableWidgetItem(checkPoint["boxName"], 0))
        self.VariablesWidget.setItem(
            row_index, 1, QTableWidgetItem(checkPoint["VariableName"], 0))
        self.VariablesWidget.setItem(row_index, 2,
                                     QTableWidgetItem(checkPoint["Value"], 0))

    def UpdateCheckPoint(self, checkPoint):
        rowCount = self.VariablesWidget.rowCount()
        for row_index in range(rowCount):
            if self.VariablesWidget.item(row_index,
                                         0).text() == checkPoint["boxName"]:
                self.VariablesWidget.setItem(
                    row_index, 1,
                    QTableWidgetItem(checkPoint["VariableName"], 0))
                self.VariablesWidget.setItem(
                    row_index, 2, QTableWidgetItem(checkPoint["Value"], 0))
                #ui->tableWidget->resizeRowToContents(curRow)
                return
        self.AddCheckPoint(checkPoint)

    def RemoveCheckPoint(self):
        if not self.txtCheckPointSeq.text():
            QMessageBox.question(
                self, "CheckPoint Seq Is None",
                "Fail to Remove,Please input a CheckPoint Seq!",
                QMessageBox.Ok)
            return
        rowCount = self.VariablesWidget.rowCount()
        for row_index in range(rowCount):
            if self.VariablesWidget.item(row_index,
                                         0).text() == checkPoint["boxName"]:
                VariablesWidget.removeRow(row_index)
                return

    def GetCheckPoints(self):
        rowCount = self.VariablesWidget.rowCount()
        checkPoints = {}
        for row_index in range(rowCount):
            strCheckPointSeq = self.VariablesWidget.item(row_index, 0).text()
            if strCheckPointSeq:
                checkPoints[strCheckPointSeq] = {
                    "boxName": strCheckPointSeq,
                    "VariableName": self.VariablesWidget.item(row_index,
                                                              1).text(),
                    "Value": self.VariablesWidget.item(row_index, 2).text()
                }
        return checkPoints

    def VariablesWidgetDoubleClicked(self, item):
        self.txtCheckPointSeq.setText(
            self.VariablesWidget.item(item.row(), 0).text())
        self.cmbVariableName.setCurrentIndex(
            self.dicVariableList.index(
                self.VariablesWidget.item(item.row(), 1).text()))
        self.txtValue.setText(self.VariablesWidget.item(item.row(), 2).text())

    def accept(self):
        iEditLine = self.ediEquation.document().lineCount()
        equation = [
            self.ediEquation.document().findBlockByLineNumber(i).text()
            for i in range(iEditLine)
        ]
        tmpLocationName = self.txtLocationName.text()
        if (tmpLocationName == ""):
            QMessageBox.question(
                self, "Please Input Location Name",
                "Fail to Accept,Please Input a Name for the Location!",
                QMessageBox.Ok)
            return
        if self.item is None:
            if (tmpLocationName in self.parentForm.dicText.keys()):
                QMessageBox.question(
                    self, "Location Name Exists",
                    "Fail to Accept,Please Change a Name for the Location due to there is already a location named "
                    + tmpLocationName + "!", QMessageBox.Ok)
                return
            self.item = LocationItem("", equation, self.txtInvariant.text(),
                                     self.position, self.isInitial.isChecked(),
                                     self.isEnd.isChecked(),
                                     self.isNameAbove.isChecked(), {},
                                     self.scene, self.parentForm)
        if (self.item.boxName == ""):
            self.item.boxName = self.txtLocationName.text()
        else:
            if (self.item.boxName != self.txtLocationName.text()):
                if (tmpLocationName in self.parentForm.dicText.keys()):
                    QMessageBox.question(
                        self, "Location Name Exists",
                        "Fail to Accept,Please Change a Name for the Location due to there is already a location named "
                        + tmpLocationName + "!", QMessageBox.Ok)
                    return
                self.parentForm.dicText.pop(self.item.boxName)
                self.item.boxName = self.txtLocationName.text()
        self.parentForm.dicText[self.item.boxName] = self.item
        self.item.equation = equation
        self.item.invariant = self.txtInvariant.text()
        self.item.isInitial = self.isInitial.isChecked()
        self.item.isEnd = self.isEnd.isChecked()
        self.item.isNameAbove = self.isNameAbove.isChecked()
        self.item.checkPoints = self.GetCheckPoints()
        self.item.update()
        self.parentForm.setDirty()
        QDialog.accept(self)

    def apply(self):

        #formula = #r'$x=\frac{3}{100}$'
        iEditLine = self.ediEquation.document().lineCount()
        iHeight = 1
        if (iEditLine > 4):
            iHeight = 0.2 * (iEditLine - 4) + 1
            self.figEquation.set_size_inches(5, iHeight)
        self.figEquation.clf()
        SympyLines = []
        try:
            for i in range(iEditLine):
                strData = self.ediEquation.document().findBlockByLineNumber(
                    i).text()
                try:
                    #if True:
                    if '=' in strData:
                        strLeftEquation, strRightEquation = FormatParseLatex.formatParseLatex4Design(
                            strData)
                        SympyLines.append('='.join(
                            [strLeftEquation, strRightEquation]))
                        self.figEquation.text(0.1,
                                              iHeight - 0.2 * (i + 1),
                                              strData,
                                              fontsize=10)

                except Exception as e:
                    #else:
                    SympyLines.append(strData + "Error:" + str(e))
                    print(str(e))
                except:
                    print("Unexpected error:", sys.exc_info()[0])

            self.ediSymEquation.setPlainText("\n".join(SympyLines))
            self.canvEquation.draw()
        except:
            print("")
Ejemplo n.º 31
0
class LabelAssistDialog(QDialog):
    """
    A simple UI for showing bookmarks and navigating to them.

    FIXME: For now, this window is tied to a particular lane.
           If your project has more than one lane, then each one
           will have it's own bookmark window, which is kinda dumb.
    """
    def __init__(self, parent, topLevelOperatorView):
        super(LabelAssistDialog, self).__init__(parent)

        # Create thread router to populate table on main thread
        self.threadRouter = ThreadRouter(self)

        # Set object classification operator view
        self.topLevelOperatorView = topLevelOperatorView

        self.setWindowTitle("Label Assist")
        self.setMinimumWidth(500)
        self.setMinimumHeight(700)

        layout = QGridLayout()
        layout.setContentsMargins(10, 10, 10, 10)

        # Show variable importance table
        rows = 0
        columns = 4
        self.table = QTableWidget(rows, columns)
        self.table.setHorizontalHeaderLabels(
            ['Frame', 'Max Area', 'Min Area', 'Labels'])
        self.table.verticalHeader().setVisible(False)

        # Select full row on-click and call capture double click
        self.table.setSelectionBehavior(QTableView.SelectRows)
        self.table.doubleClicked.connect(self._captureDoubleClick)

        layout.addWidget(self.table, 1, 0, 3, 2)

        # Create progress bar
        self.progressBar = QProgressBar()
        self.progressBar.setMinimum(0)
        self.progressBar.setMaximum(0)
        self.progressBar.hide()
        layout.addWidget(self.progressBar, 4, 0, 1, 2)

        # Create button to populate table
        self.computeButton = QPushButton('Compute object info')
        self.computeButton.clicked.connect(self._triggerTableUpdate)
        layout.addWidget(self.computeButton, 5, 0)

        # Create close button
        closeButton = QPushButton('Close')
        closeButton.clicked.connect(self.close)
        layout.addWidget(closeButton, 5, 1)

        # Set dialog layout
        self.setLayout(layout)

    def _triggerTableUpdate(self):
        # Check that object area is included in selected features
        featureNames = self.topLevelOperatorView.SelectedFeatures.value

        if 'Standard Object Features' not in featureNames or 'Count' not in featureNames[
                'Standard Object Features']:
            box = QMessageBox(
                QMessageBox.Warning, 'Warning',
                'Object area is not a selected feature. Please select this feature on: \"Standard Object Features > Shape > Size in pixels\"',
                QMessageBox.NoButton, self)
            box.show()
            return

        # Clear table
        self.table.clearContents()
        self.table.setRowCount(0)
        self.table.setSortingEnabled(False)
        self.progressBar.show()
        self.computeButton.setEnabled(False)

        def compute_features_for_frame(tIndex, t, features):
            # Compute features and labels (called in parallel from request pool)
            roi = [
                slice(None) for i in range(
                    len(self.topLevelOperatorView.LabelImages.meta.shape))
            ]
            roi[tIndex] = slice(t, t + 1)
            roi = tuple(roi)

            frame = self.topLevelOperatorView.SegmentationImages(roi).wait()
            frame = frame.squeeze().astype(numpy.uint32, copy=False)

            # Dirty trick: We don't care what we're passing here for the 'image' parameter,
            # but vigra insists that we pass *something*, so we'll cast the label image as float32.
            features[t] = vigra.analysis.extractRegionFeatures(
                frame.view(numpy.float32), frame, ['Count'], ignoreLabel=0)

        tIndex = self.topLevelOperatorView.SegmentationImages.meta.axistags.index(
            't')
        tMax = self.topLevelOperatorView.SegmentationImages.meta.shape[tIndex]

        features = {}
        labels = {}

        def compute_all_features():
            # Compute features in parallel
            pool = RequestPool()
            for t in range(tMax):
                pool.add(
                    Request(
                        partial(compute_features_for_frame, tIndex, t,
                                features)))
            pool.wait()

        # Compute labels
        labels = self.topLevelOperatorView.LabelInputs([]).wait()

        req = Request(compute_all_features)
        req.notify_finished(partial(self._populateTable, features, labels))
        req.submit()

    @threadRouted
    def _populateTable(self, features, labels, *args):
        self.progressBar.hide()
        self.computeButton.setEnabled(True)

        for time, feature in features.items():
            # Insert row
            rowNum = self.table.rowCount()
            self.table.insertRow(self.table.rowCount())

            # Get max and min object areas
            areas = feature[
                'Count']  #objectFeatures['Standard Object Features']['Count']
            maxObjArea = numpy.max(areas[numpy.nonzero(areas)])
            minObjArea = numpy.min(areas[numpy.nonzero(areas)])

            # Get number of labeled objects
            labelNum = numpy.count_nonzero(labels[time])

            # Load fram number
            item = QTableWidgetItem(str(time))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 0, item)

            # Load max object areas
            item = QTableWidgetItemWithFloatSorting(
                str("{: .02f}".format(maxObjArea)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 1, item)

            # Load min object areas
            item = QTableWidgetItemWithFloatSorting(
                str("{: .02f}".format(minObjArea)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 2, item)

            # Load label numbers
            item = QTableWidgetItemWithFloatSorting(
                str("{: .01f}".format(labelNum)))
            item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
            self.table.setItem(rowNum, 3, item)

        # Resize column size to fit dialog size
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)

        # Sort by max object area
        self.table.setSortingEnabled(True)
        self.table.sortByColumn(1, Qt.DescendingOrder)

    def _captureDoubleClick(self):
        # Navigate to selected frame
        index = self.table.selectedIndexes()[0]
        frameStr = self.table.model().data(index).toString()

        if frameStr:
            frameNum = int(frameStr)
            self.parent().editor.posModel.time = frameNum
Ejemplo n.º 32
0
class ExTags(QDialog):
    """A dialog that shows you the tags in a file

    In addition, any attached cover art is shown."""
    rowChanged = pyqtSignal(object, name='rowChanged')
    extendedtags = pyqtSignal(dict, name='extendedtags')

    def __init__(self, parent=None, row=None, files=None, preview_mode=False,
                 artwork=True, status=None):

        if status is None:
            status = {'cover_pattern': 'folder'}

        self.status = status

        QDialog.__init__(self, parent)
        winsettings('extendedtags', self)
        self.get_fieldlist = []
        self.previewMode = preview_mode

        add = QColor.fromRgb(255, 255, 0)
        edit = QColor.fromRgb(0, 255, 0)
        remove = QColor.fromRgb(255, 0, 0)
        self._colors = {ADD: QBrush(add),
                        EDIT: QBrush(edit), REMOVE: QBrush(remove)}

        self.table = QTableWidget(0, 2, self)
        self.table.setVerticalHeader(VerticalHeader())
        self.table.verticalHeader().setVisible(False)
        self.table.setSortingEnabled(True)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.setHorizontalHeaderLabels([
            translate('Extended Tags', 'Field'),
            translate('Extended Tags', 'Value')])

        header = self.table.horizontalHeader()
        header.setVisible(True)
        header.setSortIndicatorShown(True)
        header.setStretchLastSection(True)
        header.setSortIndicator(0, Qt.AscendingOrder)

        self.piclabel = PicWidget(buttons=True)
        self.piclabel.imageChanged.connect(
            self._imageChanged)

        if not isinstance(self.piclabel.removepic, QAction):
            self.piclabel.removepic.clicked.connect(
                self.removePic)
        else:
            self.piclabel.removepic.triggered.connect(self.removePic)

        if row and row >= 0 and files:
            buttons = MoveButtons(files, row)
            buttons.indexChanged.connect(self._prevnext)
            buttons.setVisible(True)
        else:
            buttons = MoveButtons([], row)
            buttons.setVisible(False)

        self._files = files

        self.okcancel = OKCancel()
        self.okcancel.insertWidget(0, buttons)

        self._reset = QToolButton()
        self._reset.setToolTip(translate('Extended Tags',
                                         'Resets the selected fields to their original value.'))
        self._reset.setIcon(get_icon('edit-undo', ':/undo.png'))
        self._reset.clicked.connect(self.resetFields)

        self.listbuttons = ListButtons()
        self.listbuttons.layout().addWidget(self._reset)
        self.listbuttons.moveupButton.hide()
        self.listbuttons.movedownButton.hide()

        listframe = QFrame()
        listframe.setFrameStyle(QFrame.Box)
        hbox = QHBoxLayout()
        hbox.addWidget(self.table, 1)
        hbox.addLayout(self.listbuttons, 0)
        listframe.setLayout(hbox)

        layout = QVBoxLayout()
        if artwork:
            imageframe = QFrame()
            imageframe.setFrameStyle(QFrame.Box)
            vbox = QVBoxLayout()
            vbox.setContentsMargins(0, 0, 0, 0)
            vbox.addWidget(self.piclabel)
            vbox.addStretch()
            vbox.addStrut(0)
            imageframe.setLayout(vbox)

            hbox = QHBoxLayout()
            hbox.addWidget(listframe, 1)
            hbox.addSpacing(4)
            hbox.addWidget(imageframe)
            hbox.addStrut(1)
            layout.addLayout(hbox)
        else:
            layout.addWidget(listframe)

        layout.addLayout(self.okcancel)
        self.setLayout(layout)

        self.okcancel.cancel.connect(self.closeMe)
        self.table.itemDoubleClicked.connect(self.editField)
        self.table.itemSelectionChanged.connect(self._checkListBox)
        self.okcancel.ok.connect(self.okClicked)

        self.listbuttons.edit.connect(self.editField)
        self.listbuttons.addButton.clicked.connect(self.addField)
        self.listbuttons.removeButton.clicked.connect(self.removeField)
        self.listbuttons.duplicate.connect(self.duplicate)

        self.setMinimumSize(450, 350)

        self.canceled = False
        self.filechanged = False

        if row and row >= 0 and files:
            self._prevnext(row)
        else:
            self.loadFiles(files)

    def addField(self):
        win = EditField(parent=self, field_list=self.get_fieldlist)
        win.setModal(True)
        win.show()
        win.donewithmyshit.connect(self.editFieldBuddy)

    def _checkListBox(self):
        if self.table.rowCount() <= 0:
            self.table.setEnabled(False)
            self.listbuttons.editButton.setEnabled(False)
            self.listbuttons.removeButton.setEnabled(False)
            self.listbuttons.duplicateButton.setEnabled(False)
            self._reset.setEnabled(False)
        else:
            self.table.setEnabled(True)
            self._reset.setEnabled(True)
            if len(self.table.selectedIndexes()) / 2 > 1:
                self.listbuttons.editButton.setEnabled(False)
                self.listbuttons.duplicateButton.setEnabled(False)
            else:
                self.listbuttons.editButton.setEnabled(True)
                self.listbuttons.removeButton.setEnabled(True)
                self.listbuttons.duplicateButton.setEnabled(True)
        self.table.resizeColumnToContents(0)

    def closeEvent(self, event):
        self.piclabel.close()
        QDialog.closeEvent(self, event)

    def closeMe(self):
        self.canceled = True
        self.close()

    def _deletePressed(self, item):
        if self.table.deletePressed:
            self.table.deletePressed = False
            self.removeField()

    def duplicate(self):
        self.editField(True)

    def editField(self, duplicate=False):
        """Opens a dialog to edit the currently selected Field.

        If duplicate is True the Edit Field dialog will be populated
        with the currently selected field's values. The new field'll then
        be added to the field list."""
        row = self.table.currentRow()
        if row != -1:
            prevtag = self.get_field(row)
            if duplicate is True:
                win = EditField(prevtag, self, self.get_fieldlist, edit=False)
            else:
                win = EditField(prevtag, self, self.get_fieldlist)
            win.setModal(True)
            win.show()

            # Have to check for truth, because this method is
            # called by the doubleclicked signal.
            if duplicate is True:
                buddy = partial(self.editFieldBuddy, duplicate=True)
            else:
                buddy = self.editFieldBuddy
            win.donewithmyshit.connect(buddy)

    def editFieldBuddy(self, tag, value, prevtag=None, duplicate=False):
        rowcount = self.table.rowCount()
        if prevtag is not None:
            if duplicate:
                row = rowcount
                self._settag(rowcount, tag, value, ADD,
                             self.previewMode, True)
            else:
                if tag == prevtag[0]:
                    row = self.table.currentRow()
                    self._settag(row, tag, value, EDIT,
                                 self.previewMode, True)
                    if row + 1 < rowcount:
                        self.table.selectRow(row + 1)
                else:
                    cur_item = self.table.item(self.table.currentRow(), 0)
                    self.resetFields([cur_item])
                    self.table.setCurrentItem(cur_item,
                                              QItemSelectionModel.ClearAndSelect)
                    self.table.selectRow(self.table.row(cur_item))
                    self.removeField()
                    valitem = self._settag(rowcount, tag,
                                           value, ADD, self.previewMode, True)
                    cur_item.linked = [valitem]
        else:
            self._settag(rowcount, tag, value, ADD, self.previewMode, True)
        self._checkListBox()
        self.filechanged = True
        self.table.clearSelection()

    def get_field(self, row, status=None):
        getitem = self.table.item
        item = getitem(row, 0)
        tag = str(item.text())
        try:
            value = str(getitem(row, 1).text())
        except AttributeError:
            value = str(self.table.cellWidget(row, 1).currentText())
        if status:
            return (tag, value, item.status)
        else:
            return (tag, value)

    def _imageChanged(self):
        self.filechanged = True

    def loadSettings(self):
        cparser = PuddleConfig()
        self.get_fieldlist = gettaglist()
        get = lambda k, v: cparser.get('extendedtags', k, v, True)
        add = QColor.fromRgb(*get('add', [255, 255, 0]))
        edit = QColor.fromRgb(*get('edit', [0, 255, 0]))
        remove = QColor.fromRgb(*get('remove', [255, 0, 0]))

        self._colors = {ADD: QBrush(add),
                        EDIT: QBrush(edit), REMOVE: QBrush(remove)}

        item = self.table.item
        for row in range(self.table.rowCount()):
            field_item = self.get_item(row, 0)
            field_item.statusColors = self._colors
            field_item.status = field_item.status

            val_item = self.get_item(row, 1)
            val_item.statusColors = self._colors
            val_item.status = val_item.status

    def listtotag(self):
        get_field = self.get_field
        tags = {}
        lowered = {}
        listitems = [get_field(row, True) for row
                     in range(self.table.rowCount())]

        for field, val, status in listitems:
            if status != REMOVE:
                if val == KEEP:
                    continue
                l_field = field.lower()
                if l_field in lowered:
                    tags[lowered[l_field]].append(val)
                else:
                    lowered[l_field] = field
                    tags[field] = [z.strip() for z in val.split('\\') if z.strip()]
            else:
                if field.lower() not in lowered:
                    tags[field] = []
                    lowered[field.lower()] = field
        return tags

    def loadFiles(self, audios):
        if self.filechanged:
            self.save()
        self.filechanged = False
        self.table.clearContents()
        self.table.setRowCount(0)
        self.piclabel.lastfilename = audios[0].filepath
        self.piclabel.setEnabled(False)
        self.piclabel.setImages(None)

        if len(audios) == 1:
            audio = audios[0]
            self.setWindowTitle(audios[0].filepath)
            self._loadsingle(audio)
        else:
            self.setWindowTitle(
                translate('Extended Tags', 'Different files.'))

            from .tagmodel import status
            k = status['table'].model().taginfo[0]
            common, numvalues, imagetags = commontags(audios)
            images = common['__image']
            del (common['__image'])
            previews = set(audios[0].preview)
            italics = set(audios[0].equal_fields())
            self.piclabel.currentFile = audios[0]
            self.piclabel.filePattern = self.status['cover_pattern']

            for audio in audios[1:]:
                previews = previews.intersection(audio.preview)
                italics = italics.intersection(audio.equal_fields())

            row = 0

            for field, values in common.items():
                if field in italics:
                    preview = UNCHANGED
                # field in italics => field in previews.
                elif field in previews:
                    preview = BOLD
                else:
                    preview = UNCHANGED
                if numvalues[field] != len(audios):
                    self._settag(row, field, values, multi=True)
                    row += 1
                else:
                    if isinstance(values, str):
                        self._settag(row, field, values, None, preview)
                        row += 1
                    else:
                        for v in values:
                            self._settag(row, field, v, None, preview)
                            row += 1

            self.piclabel.setImageTags(imagetags)
            if images:
                self.piclabel.setEnabled(True)
                self.piclabel.setImages(images)
            else:
                self.piclabel.setImages(None)
                self.piclabel.setEnabled(True)
                if images == 0:
                    self.piclabel.context = 'Cover Varies'
                    self.piclabel.removepic.setEnabled(True)
        self._checkListBox()

    def _loadsingle(self, tags):
        items = []
        d = tags.usertags.copy()
        italics = tags.equal_fields()
        self.piclabel.currentFile = tags
        self.piclabel.filePattern = self.status['cover_pattern']

        for key, val in sorted(d.items()):
            if key in italics:
                preview = UNCHANGED
            elif key in tags.preview:
                preview = BOLD
            else:
                preview = UNCHANGED
            if isinstance(val, str):
                items.append([key, val, None, preview])
            else:
                [items.append([key, z, None, preview]) for z in val]

        [self._settag(i, *item) for i, item in enumerate(items)]

        self.piclabel.lastfilename = tags.filepath
        if not tags.library:
            self.piclabel.setImageTags(tags.IMAGETAGS)
            if tags.IMAGETAGS:
                if '__image' in tags.preview:
                    images = tags.preview['__image']
                else:
                    images = tags.images
                self.piclabel.setEnabled(True)
                if images:
                    self.piclabel.setImages(deepcopy(images))
                else:
                    self.piclabel.setImages(None)
        self._checkListBox()
        self.setWindowTitle(tags[PATH])

    def okClicked(self):
        self.save()
        self.close()

    def _prevnext(self, row):
        if self.filechanged:
            self.save()
        self.loadFiles([self._files[row]])
        self.rowChanged.emit(row)

    def get_item(self, row, column=None):
        if column is None:  # Assume QModelIndex passed
            column = row.column()
            row = row.row()
        item = self.table.item(row, column)
        if item is None:
            item = self.table.cellWidget(row, column)
        return item

    def removeField(self):
        tb = self.table
        tb.setSortingEnabled(False)
        to_remove = {}
        rows = []
        for index in self.table.selectedIndexes():
            row = index.row()
            item = self.get_item(index)
            if item.status == ADD:
                to_remove[row] = item
            rows.append(row)
            item.status = REMOVE
            item.status = REMOVE
        [tb.removeRow(tb.row(z)) for z in to_remove.values()]
        tb.setSortingEnabled(True)
        self.filechanged = True
        self._checkListBox()
        if rows:
            row = max(rows)
            self.table.clearSelection()
            if row + 1 < self.table.rowCount():
                self.table.selectRow(row + 1)

    def resetFields(self, items=None):
        box = self.table
        to_remove = {}  # Stores row: item values so that only one item
        # gets removed per row.

        max_row = -1
        for index in box.selectedIndexes():
            row = index.row()
            item = self.table.item(row, index.column())
            if item is None:
                item = self.table.cellWidget(row, index.column())
            for i in item.linked:
                try:
                    to_remove[box.row(i)] = i
                except RuntimeError:
                    pass
            item.reset()
            if row > max_row:
                max_row = row
            if item.status == REMOVE:
                to_remove[row] = item

        self.table.clearSelection()
        if max_row != -1 and max_row + 1 < self.table.rowCount():
            self.table.selectRow(max_row + 1)

        for item in to_remove.values():
            self.table.removeRow(self.table.row(item))
        self._checkListBox()

    def removePic(self):
        if self.piclabel.context == 'Cover Varies':
            self.piclabel.context = 'No Images'
            self.piclabel.removepic.setEnabled(False)
            if not isinstance(self.piclabel.removepic, QAction):
                self.piclabel.removepic.clicked.disconnect(
                    self.removePic)
            else:
                self.piclabel.removepic.triggered.disconnect(self.removePic)

            self.piclabel.setImages(None)

    def save(self):

        if not self.filechanged:
            table = self.table
            for row in range(table.rowCount()):
                combo = table.cellWidget(row, 1)
                if combo is not None and combo.currentIndex() != 0:
                    self.filechanged = True
                    break

        if not self.filechanged:
            return

        tags = self.listtotag()
        if self.piclabel.context != 'Cover Varies':
            if not self.piclabel.images:
                tags['__image'] = []
            else:
                tags["__image"] = self.piclabel.images
        newtags = [z for z in tags if z not in self.get_fieldlist]
        if newtags and newtags != ['__image']:
            settaglist(newtags + self.get_fieldlist)
        self.extendedtags.emit(tags)

    def _settag(self, row, field, value, status=None, preview=False,
                check=False, multi=False):

        tb = self.table
        tb.setSortingEnabled(False)
        if row >= tb.rowCount():
            tb.insertRow(row)
            field_item = StatusWidgetItem(field, status,
                                          self._colors, preview)
            tb.setItem(row, 0, field_item)
            if not multi and (len(value) == 1 or isinstance(value, str)):
                valitem = StatusWidgetItem(to_string(value), status, self._colors, preview)
                tb.setItem(row, 1, valitem)
            else:
                valitem = StatusWidgetCombo(value, status, self._colors, preview)
                tb.setCellWidget(row, 1, valitem)
        else:
            field_item = tb.item(row, 0)
            field_item.setText(field)
            field_item.status = status

            val_item = self.get_item(row, 1)
            val_item.setText(value)
            val_item.status = status

        if check:
            lowered_tag = field.lower()
            for row in range(tb.rowCount()):
                item = tb.item(row, 0)
                text = str(item.text())
                if text != field and text.lower() == lowered_tag:
                    item.setText(field)
                    if item.status not in [ADD, REMOVE]:
                        item.status = EDIT
                        try:
                            tb.item(row, 1).status = EDIT
                        except AttributeError:
                            tb.cellWidget(row, 1).status = EDIT

        tb.setSortingEnabled(True)
        return field_item
Ejemplo n.º 33
0
class tableWidget(QDialog):
    def __init__(self, parent=None):
        super(tableWidget, self).__init__(parent)

        self.setWindowTitle("QTableWidget en PyQt5 por: ANDRES NIÑO")
        self.setWindowIcon(QIcon("Qt.png"))
        self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowCloseButtonHint |
                            Qt.MSWindowsFixedSizeDialogHint)
        self.setFixedSize(740, 348)

        self.initUI()

    def initUI(self):

      # ================== WIDGET  QTableWidget ==================
      
        self.tabla = QTableWidget(self)

        # Deshabilitar edición
        self.tabla.setEditTriggers(QAbstractItemView.NoEditTriggers)

        # Deshabilitar el comportamiento de arrastrar y soltar
        self.tabla.setDragDropOverwriteMode(False)

        # Seleccionar toda la fila
        self.tabla.setSelectionBehavior(QAbstractItemView.SelectRows)

        # Seleccionar una fila a la vez
        self.tabla.setSelectionMode(QAbstractItemView.SingleSelection)

        # Especifica dónde deben aparecer los puntos suspensivos "..." cuando se muestran
        # textos que no encajan
        self.tabla.setTextElideMode(Qt.ElideRight)# Qt.ElideNone

        # Establecer el ajuste de palabras del texto 
        self.tabla.setWordWrap(False)

        # Deshabilitar clasificación
        self.tabla.setSortingEnabled(False)

        # Establecer el número de columnas
        self.tabla.setColumnCount(6)

        # Establecer el número de filas
        self.tabla.setRowCount(0)

        # Alineación del texto del encabezado
        self.tabla.horizontalHeader().setDefaultAlignment(Qt.AlignHCenter|Qt.AlignVCenter|
                                                          Qt.AlignCenter)

        # Deshabilitar resaltado del texto del encabezado al seleccionar una fila
        self.tabla.horizontalHeader().setHighlightSections(False)

        # Hacer que la última sección visible del encabezado ocupa todo el espacio disponible
        self.tabla.horizontalHeader().setStretchLastSection(True)

        # Ocultar encabezado vertical
        self.tabla.verticalHeader().setVisible(False)

        # Dibujar el fondo usando colores alternados
        self.tabla.setAlternatingRowColors(True)

        # Establecer altura de las filas
        self.tabla.verticalHeader().setDefaultSectionSize(20)
        
        # self.tabla.verticalHeader().setHighlightSections(True)

        nombreColumnas = ("Id","Nombre", "Apellido", "Sexo", "Fecha de nacimiento", "País")

        # Establecer las etiquetas de encabezado horizontal usando etiquetas
        self.tabla.setHorizontalHeaderLabels(nombreColumnas)
        
        # Menú contextual
        self.tabla.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tabla.customContextMenuRequested.connect(self.menuContextual)
        
        # Establecer ancho de las columnas
        for indice, ancho in enumerate((80, 120, 120, 110, 150), start=0):
            self.tabla.setColumnWidth(indice, ancho)

        self.tabla.resize(700, 240)
        self.tabla.move(20, 56)

      # =================== WIDGETS QPUSHBUTTON ==================

        botonMostrarDatos = QPushButton("Mostrar datos", self)
        botonMostrarDatos.setFixedWidth(140)
        botonMostrarDatos.move(20, 20)

        menu = QMenu()
        for indice, columna in enumerate(nombreColumnas, start=0):
            accion = QAction(columna, menu)
            accion.setCheckable(True)
            accion.setChecked(True)
            accion.setData(indice)

            menu.addAction(accion)

        botonMostrarOcultar = QPushButton("Motrar/ocultar columnas", self)
        botonMostrarOcultar.setFixedWidth(180)
        botonMostrarOcultar.setMenu(menu)
        botonMostrarOcultar.move(170, 20)

        botonEliminarFila = QPushButton("Eliminar fila", self)
        botonEliminarFila.setFixedWidth(100)
        botonEliminarFila.move(530, 20)

        botonLimpiar = QPushButton("Limpiar", self)
        botonLimpiar.setFixedWidth(80)
        botonLimpiar.move(640, 20)

        botonCerrar = QPushButton("Cerrar", self)
        botonCerrar.setFixedWidth(80)
        botonCerrar.move(640, 306)

      # ======================== EVENTOS =========================

        botonMostrarDatos.clicked.connect(self.datosTabla)
        botonEliminarFila.clicked.connect(self.eliminarFila)
        botonLimpiar.clicked.connect(self.limpiarTabla)
        botonCerrar.clicked.connect(self.close)

        self.tabla.itemDoubleClicked.connect(self.Suscribete)

        menu.triggered.connect(self.mostrarOcultar)

  # ======================= FUNCIONES ============================

    def Suscribete(self, celda):
        QMessageBox.warning(self, "Suscribirse", "Hola, l@ invito a que se suscriba al "
                            "canal.\nPor cierto hiciste doble clic sobre esta "
                            "celda: {}.   ".format(celda.text()), QMessageBox.Ok)

    def datosTabla(self):
        datos = [("1", "Andres", "Niño", "Masculino", "06/12/2019", "Colombia"),
                 ("2", "Donald", "Trump", "Masculino", "06/12/1950", "Estados Unidos"),
                 ("3", "María Fernanda", "Espinosa", "Femenino", "06/10/1980", "Ecuador"),
                 ("4", "Alberto", "Canosa", "Masculino", "04/05/1876", "España"),
                 ("5", "Virtud", "Pontes", "Femenino", "23/18/1965", "España"),
                 ("6", "Elon", "Musk", "Masculino", "06/12/1960", "Estados Unidos"),
                 ("7", "Richard", "Branson", "Masculino", "14/12/1956", "Reino Unido"),
                 ("8", "Gabriel", "Garcia Marquez", "Masculino", "19/11/1948", "Colombia"),
                 ("9", "Valentina", "Tereshkova", "Femenino", "06/03/1937", "Rusia"),
                 ("10", "Artur", "Fischer", "Masculino", "31/12/1919", "Alemania"),
                 ("11", "Grace", "Murray Hopper", "Femenino", "09/12/1906", "Estados Unidos"),
                 ("12", "Guido van", "Rossum", "Masculino", "31/01/1956", "Países Bajos")]

        self.tabla.clearContents()

        row = 0
        for endian in datos:
            self.tabla.setRowCount(row + 1)
            
            idDato = QTableWidgetItem(endian[0])
            idDato.setTextAlignment(4)
            
            self.tabla.setItem(row, 0, idDato)
            self.tabla.setItem(row, 1, QTableWidgetItem(endian[1]))
            self.tabla.setItem(row, 2, QTableWidgetItem(endian[2]))
            self.tabla.setItem(row, 3, QTableWidgetItem(endian[3]))
            self.tabla.setItem(row, 4, QTableWidgetItem(endian[4]))
            self.tabla.setItem(row, 5, QTableWidgetItem(endian[5]))

            row += 1

    def mostrarOcultar(self, accion):
        columna = accion.data()
        
        if accion.isChecked():
            self.tabla.setColumnHidden(columna, False)
        else:
            self.tabla.setColumnHidden(columna, True)

    def eliminarFila(self):
        filaSeleccionada = self.tabla.selectedItems()

        if filaSeleccionada:
            fila = filaSeleccionada[0].row()
            self.tabla.removeRow(fila)

            self.tabla.clearSelection()
        else:
            QMessageBox.critical(self, "Eliminar fila", "Seleccione una fila.   ",
                                 QMessageBox.Ok)

    def limpiarTabla(self):
        self.tabla.clearContents()
        self.tabla.setRowCount(0)

    def menuContextual(self, posicion):
        indices = self.tabla.selectedIndexes()

        if indices:
            menu = QMenu()

            itemsGrupo = QActionGroup(self)
            itemsGrupo.setExclusive(True)
            
            menu.addAction(QAction("Copiar todo", itemsGrupo))

            columnas = [self.tabla.horizontalHeaderItem(columna).text()
                        for columna in range(self.tabla.columnCount())
                        if not self.tabla.isColumnHidden(columna)]

            copiarIndividual = menu.addMenu("Copiar individual") 
            for indice, item in enumerate(columnas, start=0):
                accion = QAction(item, itemsGrupo)
                accion.setData(indice)
                
                copiarIndividual.addAction(accion)

            itemsGrupo.triggered.connect(self.copiarTableWidgetItem)
            
            menu.exec_(self.tabla.viewport().mapToGlobal(posicion))

    def copiarTableWidgetItem(self, accion):
        filaSeleccionada = [dato.text() for dato in self.tabla.selectedItems()]
            
        if accion.text() == "Copiar todo":
            filaSeleccionada = tuple(filaSeleccionada)
        else:
            filaSeleccionada = filaSeleccionada[accion.data()]

        print(filaSeleccionada)

        return
Ejemplo n.º 34
0
class Menu(QMainWindow):

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

        self.db = DB()

        self.initUI()

    def initUI(self):

        in_class = "menu"

        self.sidebar = sidebar.Sidebar(self)
        self.sidebar.window.connect(self.getvalue)

        self.addDockWidget(Qt.LeftDockWidgetArea, self.sidebar)

        header = AppName(in_class)
        footer = Footer()

        add_and_search = AddSearchFrame(in_class)
        add_and_search.add_button.clicked.connect(lambda: self.add_menu(in_class))
        add_and_search.search_button.clicked.connect(
                                        lambda: self.search_menu(add_and_search.search_box))


        self.table = QTableWidget()
        self.table.setColumnCount(5)
        # self.table.setStyleSheet("border: none")
        # self.table.setStyleSheet(
        #     "background-color: rgb(255, 255, 255);\n"
        #     'font: 10pt "MS Shell Dlg 2";\n'
        #     "color: rgb(30, 45, 66);"
        # )

        # self.table.setHorizontalHeaderItem(0, QTableWidgetItem("ID"))
        self.table.setHorizontalHeaderItem(0, QTableWidgetItem("Food"))
        self.table.setHorizontalHeaderItem(1, QTableWidgetItem("Category"))
        self.table.setHorizontalHeaderItem(2, QTableWidgetItem("Price"))
        # self.table.setHorizontalHeaderItem(3, QTableWidgetItem("Bonus"))
        # self.table.setHorizontalHeaderItem(3, QTableWidgetItem("Joining Date"))
        # self.table.setHorizontalHeaderItem(6, QTableWidgetItem("Total Salary"))
        self.table.setHorizontalHeaderItem(3, QTableWidgetItem("Edit"))
        self.table.setHorizontalHeaderItem(4, QTableWidgetItem("Delete"))


        data = self.load_menu_data()
        print(data)

        for x in data:
            print(x)

        self.populate_table(data)
        self.table.resizeColumnsToContents()

        layout = QVBoxLayout()

        layout.addWidget(header)
        layout.addWidget(add_and_search)
        layout.addWidget(self.table)
        # layout.addStretch()
        layout.addWidget(footer)

        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        centralWidget = QWidget()
        centralWidget.setLayout(layout)

        self.setCentralWidget(centralWidget)
        self.setContentsMargins(0, 0, 0, 0)

        # self.resize(800, 600)
        self.setWindowTitle("Employee")
        self.resize(1160, 605)

        self.show()
        self.center()

    def center(self):
        '''centers the window on the screen'''
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)

    def getvalue(self, value):
        print(value)
        print(type(value))

        if value == 1:
            self.hide()
            view = sidebar.Dashboard(self)
        elif value == 2:
            self.hide()
            view = sidebar.Employee(self)
        elif value == 3:
            self.hide()
            view = sidebar.Table(self)
        elif value == 4:
            self.hide()
            view = sidebar.Reservations(self)
        elif value == 5:
            pass
        elif value == 6:
            self.hide()
            view = sidebar.Settings(self)
        elif value == 7:
            self.hide()
            view = sidebar.Orders(self)
        elif value == 8:
            self.hide()
            view = sidebar.Menu(self)
        elif value == 9:
            self.hide()
            view = sidebar.Bill(self)

    def load_menu_data(self):
        query = "SELECT food_name, price, category_name FROM menu " \
                "join category on menu.category_id = category.id order by category_name"

        result = self.db.fetch(query)

        return result

    '''
        This function is called after an employee has been added and returns only the last row.
    '''
    def add_update_menu_data(self):
        query = "SELECT food_name, price, category_name FROM menu " \
                "join category on menu.category_id = category.id " \
                "order by id desc limit 1;"

        result = self.db.fetch(query)

        return result

    def edit_menu(self):
        emp_row = self.table.indexAt(self.sender().pos())
        id = self.table.cellWidget(emp_row.row(), emp_row.column()).objectName()
        print(emp_row.row())
        print(id)
        print(type(id))

        '''
            Get the data from the database for that user.
        '''
        data = self.get_data(id)

        print("Data")
        print(data)
        # print(type(data[4]))



        view = AddMenuDetails(self, "update", data[0])

        view.nametextbox.setText(data[0])
        view.pricetextbox.setText(str(data[1]))

        category = self.get_category(data[2])
        view.category_list.setCurrentText(category)

        view.closing.connect(self.editupdate_emp)

    def get_category(self, category):
        query = "SELECT category_name FROM category " \
                "where id=%s"
        values = (category,)

        result = self.db.fetch(query, values)

        for (category) in result:
            category = category[0]

        return category

    def editupdate_emp(self, check):
        print("I am here")
        print(check)

        self.table.clearContents()
        self.table.setRowCount(0)

        data = self.load_menu_data()

        self.populate_table(data)
        self.table.resizeColumnsToContents()
        # self.table.resizeColumnsToContents()

    def get_data(self, id):
        query = "SELECT food_name, price, category_id FROM menu " \
                "where food_name=%s"
        values = (id,)

        result = self.db.fetch(query, values)

        for (food_name, price, category) in result:
            food_name = food_name
            price = price
            category = category

        return [food_name, price, category]

    def delete_menu(self):
        emp_row = self.table.indexAt(self.sender().pos())

        # print(emp_row.row())
        # print(emp_row.column())

        # print(self.table.cellWidget(emp_row.row(), emp_row.column()).objectName())

        id = self.table.cellWidget(emp_row.row(), emp_row.column()).objectName()
        # print(id)
        # print(emp_row.child(emp_row.row(), emp_row.column()))

        query = "DELETE FROM menu WHERE food_name=%s"
        values = (id,)

        result = self.db.execute(query, values)

        self.table.clearContents()
        self.table.setRowCount(0)
        data = self.load_menu_data()

        self.populate_table(data)

    def add_menu(self, where):
        if where == "menu":
            print("Employee Button Clicked from Menu")

            view = AddMenuDetails(self, "add")
            view.closing.connect(self.update_menu)

        elif where == "stocks":
            print("Stock Button Clicked")

    def search_menu(self, search_obj):
        search = search_obj.text()
        search_obj.setText("")

        print("Search")
        if search != "":
            query = "SELECT * FROM menu WHERE food_name like %s"
            values = ("%" + search + "%",)
        else:
            query = "SELECT * FROM menu"
            values = ()

        self.table.clearContents()
        self.table.setRowCount(0)

        data = self.db.fetch(query, values)

        self.populate_table(data)




    '''
        Repopulates the employee table with the updated data.
    '''
    def update_menu(self, check):
        print("I am here")
        print(check)

        self.table.clearContents()
        self.table.setRowCount(0)
        data = self.load_menu_data()

        self.populate_table(data)

    '''
        This function populates the employee table with data.
    '''
    def populate_table(self, data):
        for (food_name, price, category_name) in data:
            self.table.insertRow(self.table.rowCount())

            self.table.setItem(self.table.rowCount() - 1, 0, QTableWidgetItem(str(food_name)))
            self.table.setItem(self.table.rowCount() - 1, 1, QTableWidgetItem(str(category_name)))
            self.table.setItem(self.table.rowCount() - 1, 2, QTableWidgetItem(str(price)))
            # self.table.setItem(self.table.rowCount() - 1, 3, QTableWidgetItem(str(bonus)))
            # self.table.setItem(self.table.rowCount() - 1, 3, QTableWidgetItem(str(joining_date.strftime("%d-%m-%Y"))))
            edit = QPushButton(self.table)
            edit.setObjectName(str(food_name))
            edit.setStyleSheet("background-color: rgb(50,205,50);")
            edit.setText("Edit")
            edit.adjustSize()
            edit.clicked.connect(self.edit_menu)

            self.table.setCellWidget(self.table.rowCount() - 1, 3, edit)

            delete = QPushButton(self.table)
            delete.setObjectName(str(food_name))
            delete.setStyleSheet("background-color: #d63447;")
            delete.setText("Delete")
            delete.adjustSize()
            delete.clicked.connect(self.delete_menu)
            # delete.mousePressEvent = functools.partial(self.delete_menu, source_object=delete)
            self.table.setCellWidget(self.table.rowCount() - 1, 4, delete)
Ejemplo n.º 35
0
class Query_Form(QDialog):  #自定义creat_view类继承了QDialog类
    def __init__(self, parent=None):  #不是QWidget对象但继承了QObject对象要用parent
        super(Query_Form, self).__init__(parent)  #调用QDialog类中_init_变量. 初始化构造函数

        #设置界面大小、名称、背景
        self.resize(1000, 800)
        self.setWindowTitle('Database')
        self.setStyleSheet("background-image:url(tubiao_meitu.jpg)")

        #窗体属性
        self.setWindowFlags(Qt.Widget)

        #连接数据库
        # db = pymysql.connect("localhost", "root", "root", "mrp",charset='utf8')
        db = pymysql.connect(
            host='127.0.0.1',
            port=3308,
            user='******',
            password='******',
            db='mrp',
            charset='utf8',
        )
        #获取游标、数据
        cur = db.cursor()
        cur.execute("SELECT * FROM 技术要求")
        data = cur.fetchall()  #接收全部的返回结果行

        #数据列字段名 tup:数组 #description:种类
        col_lst = [tup[0] for tup in cur.description]

        #数据的大小
        row = len(data)  #获得data的行数
        vol = len(data[0])  #获得data的卷数.第一行的数量(列数)

        #插入表格
        self.MyTable = QTableWidget(row, vol)  #row行,vol列的表格
        font = QtGui.QFont('微软雅黑', 10)

        #设置字体、表头
        self.MyTable.horizontalHeader().setFont(font)  #设置行表头字体
        self.MyTable.setHorizontalHeaderLabels(col_lst)  #设置标题
        #设置竖直方向表头不可见
        self.MyTable.verticalHeader().setVisible(False)
        self.MyTable.setFrameShape(QFrame.NoFrame)
        #设置表格颜色
        # self.MyTable.horizontalHeader().setStyleSheet('QHeaderView::section{background:skyblue}')

        #构建表格插入数据
        for i in range(row):  #i到row-1的数量
            for j in range(vol):
                temp_data = data[i][j]  # 临时记录,不能直接插入表格
                data1 = QTableWidgetItem(str(temp_data))  # 转换后可插入表格
                self.MyTable.setItem(i, j, data1)

        #编辑按钮
        self.qle = QLineEdit()
        buttonBox = QDialogButtonBox()
        #增删查改四个按钮
        addButton = buttonBox.addButton("&增加", QDialogButtonBox.ActionRole)
        okButton = buttonBox.addButton("&确定", QDialogButtonBox.ActionRole)
        deleteButton = buttonBox.addButton("&DELETE",
                                           QDialogButtonBox.ActionRole)
        inquireButton = buttonBox.addButton("&查询", QDialogButtonBox.ActionRole)

        #设置按钮内字体样式
        addButton.setFont(font)
        okButton.setFont(font)
        deleteButton.setFont(font)
        inquireButton.setFont(font)

        #垂直布局
        layout = QVBoxLayout()
        layout.addWidget(self.qle)
        layout.addWidget(buttonBox)
        layout.addWidget(self.MyTable)
        self.setLayout(layout)

        addButton.clicked.connect(partial(self.add_data, cur,
                                          db))  #绑定插入按钮的点击事件
        okButton.clicked.connect(partial(self.up_data, cur, db,
                                         col_lst))  #更新实现
        deleteButton.clicked.connect(partial(self.del_data, cur, db))  #删除实现
        inquireButton.clicked.connect(partial(self.inq_data,
                                              db))  #查询实现  #partialial传递db

    #插入空表格
    def add_data(self, cur, db):
        #获取行数
        row = self.MyTable.rowCount()
        #在末尾插入一空行
        self.MyTable.insertRow(row)

    #插入数据
    def up_data(self, cur, db, col_lst):
        row_1 = self.MyTable.rowCount()  #表格行数

        value_lst = []  #建值列表
        for i in range(len(col_lst)):  #从i到字段数量的循环
            if (len(self.MyTable.item(row_1 - 1, i).text()) == 0):
                value_lst.append(None)
            else:
                value_lst.append(self.MyTable.item(row_1 - 1, i).text())

        tup_va_lst = []  #创建数组列表
        for cl, va in zip(col_lst, value_lst):
            tup_va_lst.append((cl, va))

        #插入语句
        cur.execute(
            "INSERT INTO 技术要求 VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
            value_lst)
        #db.commit()             学习这里是否要这句,原代码没有

    #删除
    def del_data(self, cur, db):
        #是否删除的对话框
        reply = QMessageBox.question(self, 'Message', '你确定要删除数据吗 ?',
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes:
            #当前行
            row_2 = self.MyTable.currentRow()
            del_d = self.MyTable.item(row_2, 0).text()

            #在数据库删除数据
            # cur.execute("DELETE FROM 技术要求 WHERE ID = '"+del_d+"'")
            try:  #2018-11-21添加
                # 执行SQL语句
                cur.execute("DELETE FROM 技术要求 WHERE ID = '" + del_d + "'")
                # 提交到数据库执行
                db.commit()
            except:
                # 发生错误时回滚
                db.rollback()

            # 关闭数据库连接
            db.close()

            #删除表格
            self.MyTable.removeRow(row_2)

    #查询
    def inq_data(self, db):
        txt = self.qle.text()

        #模糊查询
        if len(txt) != 0:
            cur = db.cursor()
            cur.execute(
                "SELECT * FROM 技术要求 WHERE ID LIKE '%" + txt + "%'"
            )  # CONCAT('f_id','f_area','f_place','f_AQI','f_AQItype','f_PM25per1h'),concat(concat('%','#txt'),'%')
            data_x = cur.fetchall()

            self.MyTable.clearContents()

            row_4 = len(data_x)
            vol_1 = len(cur.description)

            #查询到的更新带表格当中
            for i_x in range(row_4):
                for j_y in range(vol_1):
                    temp_data_1 = data_x[i_x][j_y]  # 临时记录,不能直接插入表格
                    data_1 = QTableWidgetItem(str(temp_data_1))  # 转换后可插入表格
                    self.MyTable.setItem(i_x, j_y, data_1)

        #空输入返回原先数据表格
        else:
            self.MyTable.clearContents()
            cur.execute("SELECT * FROM 技术要求")
            data_y = cur.fetchall()

            row_5 = len(data_y)
            vol_1 = len(cur.description)

            for i_x_1 in range(row_5):
                for j_y_1 in range(vol_1):
                    temp_data_2 = data_y[i_x_1][j_y_1]  # 临时记录,不能直接插入表格
                    data_2 = QTableWidgetItem(str(temp_data_2))  # 转换后可插入表格
                    self.MyTable.setItem(i_x_1, j_y_1, data_2)
Ejemplo n.º 36
0
class SearchPage(QWidget):
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.searchMode = 0
        self.initDBConnection()
        self.initUI()

    def initUI(self):
        layout = QVBoxLayout(self)
        functionLayout = QHBoxLayout()
        functionLayout.setAlignment(Qt.AlignLeft)
        functionLayout.setSpacing(2)
        self.searchButton = QPushButton()
        self.searchButton.setText("Search")
        self.searchButton.setStyleSheet("QPushButton {max-width: 80px;}")
        functionLayout.addWidget(self.searchButton)
        functionLayout.addSpacing(10)
        matchExpressionLabel = QLabel("Match Expression: ")
        functionLayout.addWidget(matchExpressionLabel)
        matchExpressionEdit = QLineEdit()
        matchExpressionEdit.setStyleSheet(
            "QLineEdit {max-width: 450px;min-width: 300px;}")
        matchExpressionEdit.setPlaceholderText(
            "Eg: (1 & (2 | 3)), Default: (1) or (1 & 2) or ... ")
        functionLayout.addWidget(matchExpressionEdit)
        functionLayout.addSpacing(10)
        caseMatchCheckBox = QCheckBox()
        caseMatchLabel = QLabel("Match Case")
        functionLayout.addWidget(caseMatchCheckBox)
        functionLayout.addSpacing(6)
        functionLayout.addWidget(caseMatchLabel)
        functionLayout.addStretch()

        layout.addLayout(functionLayout)

        self.mygroupbox = QGroupBox()
        self.myform = QFormLayout()
        self.myform.setVerticalSpacing(0)
        self.myform.setHorizontalSpacing(2)
        self.labelList = []
        self.fieldComboList = []
        self.filterComboList = []
        self.inputboxList = []
        self.plusbuttonlist = []
        self.minusbuttonlist = []
        relationComboList = []
        self.sublayoutList = []
        for i in range(3):
            self.createSearchFilter(i)
            # self.myform.addRow(self.sublayoutList[i])
        #self.mygroupbox.setLayout(self.myform)
        self.updateSearchFilterForm()
        scroll = QScrollArea()
        scroll.setWidget(self.mygroupbox)
        scroll.setWidgetResizable(True)
        scroll.setFixedHeight(140)

        layout.addWidget(scroll)

        self.mainTable = QTableWidget(
            100, 8, self)  # create 100x8 table  rowNum, colNum
        self.mainTable.setHorizontalHeaderLabels(
            ('Year', 'Title', 'Published In', 'Authors', 'Type', 'Added',
             'Labels', 'RefID'))

        self.mainTable.setColumnWidth(0, 60)  # Year
        self.mainTable.setColumnWidth(1, 240)  # Title
        self.mainTable.setColumnWidth(2, 240)  # Published In
        self.mainTable.setColumnWidth(3, 240)  # Authors
        self.mainTable.setColumnWidth(4, 120)  # Type
        self.mainTable.setColumnWidth(5, 120)  # Added Date
        self.mainTable.setColumnWidth(6, 240)  # Labels
        self.mainTable.setColumnWidth(7, 120)  # RefAbsID

        # Table settings
        self.mainTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.mainTable.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        self.mainTable.setHorizontalScrollMode(
            QAbstractItemView.ScrollPerPixel)
        self.mainTable.setSelectionBehavior(QAbstractItemView.SelectRows)

        # Connect sorting signal
        self.mainTable.setSortingEnabled(True)
        self.mainTable.horizontalHeader().sortIndicatorChanged.connect(
            self.sortingTable)

        layout.addWidget(self.mainTable)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        # Add tabs to widget
        #self.layout.addWidget(self.scrollArea)
        #self.setLayout(self.layout)
        self.appearance = True
        # Initialize internal signal and slot
        self.initSignalsSlots()

    def createSearchFilter(self, ind):
        self.labelList.insert(ind, QLabel('Key: ' + str(ind + 1)))
        fieldCombo = QComboBox()
        fieldChoiceList = [
            'Title', 'Year', 'Published In', 'Author', 'Keywords'
        ]
        fieldCombo.addItems(fieldChoiceList)
        if ind < 3:
            fieldCombo.setCurrentIndex(ind)
        else:
            fieldCombo.setCurrentIndex(0)
        self.fieldComboList.insert(ind, fieldCombo)
        filterCombo = QComboBox()
        filterChoiceList = ['Contains', 'Is']
        filterCombo.addItems(filterChoiceList)
        self.filterComboList.insert(ind, filterCombo)
        self.inputboxList.insert(ind, QLineEdit())

        tempPlusButton = QPushButton()
        tempPlusButton.setText("+")
        tempPlusButton.setStyleSheet("QPushButton {background-color: gray; border-color: beige; border-width: 1px;" \
                                "border-radius: 1px; font: bold 14px; padding: 6px;}")
        self.plusbuttonlist.insert(ind, tempPlusButton)
        tempMinusButton = QPushButton()
        tempMinusButton.setText("-")
        tempMinusButton.setStyleSheet("QPushButton {background-color: gray; border-color: beige; border-width: 1px;" \
                                "border-radius: 1px; font: bold 14px; padding: 6px;}")
        self.minusbuttonlist.insert(ind, tempMinusButton)
        # Signal and Slot
        self.plusbuttonlist[ind].clicked.connect(
            partial(self.onPlusButtonClicked, ind))
        self.minusbuttonlist[ind].clicked.connect(
            partial(self.onMinusButtonClicked, ind))
        tempSubLayput = QHBoxLayout()
        tempSubLayput.addWidget(self.labelList[ind])
        tempSubLayput.addWidget(self.fieldComboList[ind])
        tempSubLayput.addWidget(self.filterComboList[ind])
        tempSubLayput.addWidget(self.inputboxList[ind])
        tempSubLayput.addWidget(self.plusbuttonlist[ind])
        tempSubLayput.addWidget(self.minusbuttonlist[ind])
        self.sublayoutList.insert(ind, tempSubLayput)
        self.myform.insertRow(ind, self.sublayoutList[ind])

    def removeSearchFilter(self, ind):
        self.labelList.pop(ind)
        self.fieldComboList.pop(ind)
        self.filterComboList.pop(ind)
        self.inputboxList.pop(ind)
        self.plusbuttonlist.pop(ind)
        self.minusbuttonlist.pop(ind)
        self.sublayoutList.pop(ind)
        self.myform.removeRow(ind)

    def initSignalsSlots(self):
        self.searchButton.clicked.connect(self.onSearchButtonClicked)

    def sortingTable(self, colIndex, order):
        #print("Column:" + str(colIndex))
        if order == Qt.AscendingOrder:
            pass
        elif order == Qt.DescendingOrder:
            pass

    def initDBConnection(self):
        database = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                "Data.db")
        refs = []
        try:
            self.conn = createConnectionToDB(database)
        except:
            buttonReply = QMessageBox.critical(
                self, 'Alert', "Initialize Info Tab: Database is missing.",
                QMessageBox.Ok, QMessageBox.Ok)

    def onPlusButtonClicked(self, buttonId):
        self.createSearchFilter(buttonId + 1)
        self.updateSearchFilterForm()

    def onMinusButtonClicked(self, buttonId):
        if (buttonId == 0) and (len(self.sublayoutList) == 1):
            buttonReply = QMessageBox.critical(self, 'Alert', "You need me.",
                                               QMessageBox.Ok, QMessageBox.Ok)
        else:
            self.removeSearchFilter(buttonId)
            self.updateSearchFilterForm()

    def updateSearchFilterForm(self):
        for i in range(len(self.sublayoutList)):
            self.labelList[i].setText('Key: ' + str(i + 1))
            self.plusbuttonlist[i].clicked.disconnect()
            self.minusbuttonlist[i].clicked.disconnect()
            self.plusbuttonlist[i].clicked.connect(
                partial(self.onPlusButtonClicked, i))
            self.minusbuttonlist[i].clicked.connect(
                partial(self.onMinusButtonClicked, i))
        self.mygroupbox.setLayout(self.myform)

    def onSearchButtonClicked(self):
        searchTarget = []
        for i in range(len(self.inputboxList)):
            tempStr = self.inputboxList[i].text()
            if len(tempStr) > 0:
                searchTarget.append(
                    [self.fieldComboList[i].currentText(), tempStr])
        if len(searchTarget) > 0:
            formattedSearchTarget = self.parseSearchTarget(searchTarget)
            self.switchSearchMode(formattedSearchTarget)

    def parseSearchTarget(self, searchTarget):
        # fieldChoiceList = ['Title', 'Year', 'Published In', 'Author', 'Keywords']
        formattedSearchTarget = []
        if len(searchTarget) > 0:
            for tarItem in searchTarget:
                if tarItem[0] == 'Published In':
                    formattedSearchTarget.append(['PubIn', tarItem[1]])
                else:
                    formattedSearchTarget.append(tarItem)
        return formattedSearchTarget

    def switchSearchMode(self, searchTarget):
        # Local search, online search, mix search
        if self.searchMode == 0:
            self.databaseSearch(searchTarget)
        elif self.searchMode == 1:
            self.mixSearch(searchTarget)
        else:
            self.onlineSearch(searchTarget)

    def databaseSearch(self, searchTarget):
        foundRefItems = []
        foundRefItems = searchRefInDB(self.conn, searchTarget)
        self.setRefsTable(foundRefItems)

    def onlineSearch(self, searchTarget):
        ''' 0: Local Database
            1: "Mixed Search",
            2: "Google Scholar",
            3: "PubMed",
            4: "IEEE Xplore",
            5: "Science Direct",
            6: "arXiv",
            7: "Sci-Hub",
            8: "More..."
        '''
        foundRefItems = []
        if self.searchMode == 2:
            pass
        elif self.searchMode == 3:
            pass
        elif self.searchMode == 4:
            pass
        elif self.searchMode == 5:
            pass
        elif self.searchMode == 6:
            pass
        elif self.searchMode == 7:
            pass
        else:
            pass
        self.setRefsTable(foundRefItems)

    def mixSearch(self, searchTarget):
        foundRefItems = []
        self.setRefsTable(foundRefItems)

    def setRefsTable(self, refs):
        # Clean old contents
        self.mainTable.clearContents()
        # Must disable sorting table first, otherwise error will occur
        self.mainTable.setSortingEnabled(False)
        for rowInd in range(len(refs)):
            self.mainTable.setItem(rowInd, 0,
                                   QTableWidgetItem(str(
                                       refs[rowInd]['Year'])))  # Year
            self.mainTable.setItem(rowInd, 1,
                                   QTableWidgetItem(
                                       refs[rowInd]['Title']))  # Title
            self.mainTable.setItem(rowInd, 2,
                                   QTableWidgetItem(
                                       refs[rowInd]['PubIn']))  # PubIn
            self.mainTable.setItem(rowInd, 3,
                                   QTableWidgetItem(
                                       refs[rowInd]['Author']))  # Authors
            self.mainTable.setItem(rowInd, 4,
                                   QTableWidgetItem(
                                       refs[rowInd]['MType']))  # Type
            self.mainTable.setItem(rowInd, 5,
                                   QTableWidgetItem(refs[rowInd]['AddedTime'])
                                   )  # Add Date, change to real field later
            self.mainTable.setItem(rowInd, 6,
                                   QTableWidgetItem(
                                       refs[rowInd]['Labels']))  # Labels
            self.mainTable.setItem(
                rowInd, 7,
                QTableWidgetItem(str(
                    refs[rowInd]['RefAbsID']).zfill(10)))  # RefAbsID

        # Enable sorting again.
        self.mainTable.setSortingEnabled(True)
Ejemplo n.º 37
0
class FirstTab(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        grid = QGridLayout()

        grid.addWidget(self.create_order_groupbox(), 0, 0)
        grid.addWidget(self.create_menu_groupbox(), 0, 1)

        self.setLayout(grid)

    # Groupbox: 주문현황
    def create_order_groupbox(self):
        gbox = QGroupBox()
        gbox.setTitle('주문현황')
        hbox = QHBoxLayout()
        vbox = QVBoxLayout()

        # widget
        self.cart_table = QTableWidget()
        self.create_cart_table()
        vbox.addWidget(self.cart_table)

        vbox.addLayout(hbox)

        btn_print_bill = QPushButton('영수증출력', self)
        btn_cancel_all = QPushButton('전체취소', self)
        btn_pay_in_cash = QPushButton('현금결제', self)
        btn_pay_in_card = QPushButton('카드결제', self)
        # Signal
        btn_print_bill.clicked.connect(self.print_bill_of_recent_order)
        btn_cancel_all.clicked.connect(self.cancel_all_in_cart)
        btn_pay_in_cash.clicked.connect(self.pay_in_cash)
        btn_pay_in_card.clicked.connect(self.pay_in_credit_card)

        hbox.addWidget(btn_print_bill)
        hbox.addWidget(btn_cancel_all)
        hbox.addWidget(btn_pay_in_cash)
        hbox.addWidget(btn_pay_in_card)

        gbox.setLayout(vbox)

        return gbox

    # Groupbox: 메뉴선택
    def create_menu_groupbox(self):
        gbox = QGroupBox()
        gbox.setTitle('메뉴선택')
        vbox = QVBoxLayout()

        # widget
        btns_menu = []

        for i in range(len(menu_excel['메뉴명'])):
            btns_menu.append(QPushButton())
            btns_menu[i].setText(menu_excel['메뉴명'][i] + '\n' +
                                 str(menu_excel['가격'][i]) + '원')
            vbox.addWidget(btns_menu[i])
            # Signal
            btns_menu[i].clicked.connect(
                lambda arg, idx=i: self.add_menu_in_cart(menu_excel['메뉴명'][idx]
                                                         ))

        gbox.setLayout(vbox)

        return gbox

    # Table Widget: 카트
    def create_cart_table(self):
        header_list = ['메뉴', '수량', '감소', '증가', '직접입력', '단가', '금액', '취소']

        self.cart_table.setColumnCount(len(header_list))
        self.cart_table.setRowCount(len(menu_excel['메뉴명']) + 1)

        self.cart_table.setHorizontalHeaderLabels(header_list)

        self.cart_table.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.cart_table.setItem(4, 0, QTableWidgetItem('Total'))
        self.cart_table.setItem(4, 1,
                                QTableWidgetItem(str(cal.return_total_qty())))
        self.cart_table.setItem(
            4, 6, QTableWidgetItem(str(cal.return_total_amount())))

    # Slot
    @pyqtSlot()
    def set_item_in_cart_table(self):
        self.cart_table.clearContents()

        self.cart_table.setItem(4, 0, QTableWidgetItem('Total'))
        self.cart_table.setItem(4, 1,
                                QTableWidgetItem(str(cal.return_total_qty())))
        self.cart_table.setItem(
            4, 6, QTableWidgetItem(str(cal.return_total_amount())))

        btns_minus = []
        btns_add = []
        btns_input = []
        btns_cancel = []
        row_int = 0

        if len(cal.cart_list) != 0:
            for i in range(len(cal.cart_list)):
                if cal.cart_list[i] not in cal.cart_list[:i]:
                    btns_minus.append(QPushButton('-', self))
                    btns_add.append(QPushButton('+', self))
                    btns_input.append(QPushButton('수량입력', self))
                    btns_cancel.append(QPushButton('x', self))

                    self.cart_table.setItem(row_int, 0,
                                            QTableWidgetItem(cal.cart_list[i]))
                    self.cart_table.setItem(
                        row_int, 1,
                        QTableWidgetItem(
                            str(cal.return_menu_qty(cal.cart_list[i]))))
                    self.cart_table.setItem(
                        row_int, 5,
                        QTableWidgetItem(
                            str(cal.return_menu_cost(cal.cart_list[i]))))
                    self.cart_table.setItem(
                        row_int, 6,
                        QTableWidgetItem(
                            str(cal.return_menu_amount(cal.cart_list[i]))))

                    self.cart_table.setCellWidget(row_int, 2,
                                                  btns_minus[row_int])
                    self.cart_table.setCellWidget(row_int, 3,
                                                  btns_add[row_int])
                    self.cart_table.setCellWidget(row_int, 4,
                                                  btns_input[row_int])
                    self.cart_table.setCellWidget(row_int, 7,
                                                  btns_cancel[row_int])

                    # Signal
                    btns_minus[row_int].clicked.connect(
                        lambda: self.minus_menu_in_cart(cal.cart_list[i]))
                    btns_add[row_int].clicked.connect(
                        lambda: self.add_menu_in_cart(cal.cart_list[i]))
                    btns_input[row_int].clicked.connect(
                        lambda: self.input_menu_in_cart(cal.cart_list[i]))
                    btns_cancel[row_int].clicked.connect(
                        lambda: self.cancel_menu_in_cart(cal.cart_list[i]))

                    row_int += 1

    @pyqtSlot(str)
    def add_menu_in_cart(self, menu_str):
        cal.add_qty(menu_str)
        self.set_item_in_cart_table()

    @pyqtSlot(str)
    def minus_menu_in_cart(self, menu_str):
        cal.minus_qty(menu_str)
        self.set_item_in_cart_table()

    @pyqtSlot(str)
    def input_menu_in_cart(self, menu_str):
        input_int, ok = QInputDialog.getInt(self,
                                            '수량 직접입력',
                                            menu_str + '의 수량을 입력하세요.',
                                            min=0)
        if ok:
            cal.input_qty(menu_str, input_int)
            self.set_item_in_cart_table()

    @pyqtSlot(str)
    def cancel_menu_in_cart(self, menu_str):
        cal.cancel_qty(menu_str)
        self.set_item_in_cart_table()

    @pyqtSlot()
    def cancel_all_in_cart(self):
        cal.cancel_all_qty()
        self.set_item_in_cart_table()

    @pyqtSlot()
    def print_bill_of_recent_order(self):
        msg = QMessageBox.information(self, '영수증출력', str(rec.receipt_df),
                                      QMessageBox.Ok, QMessageBox.Ok)

    @pyqtSlot()
    def pay_in_cash(self):
        if len(cal.cart_list) == 0:
            self.warn_pay_zero()
        else:
            cash, ok = QInputDialog.getInt(self, '현금결제', '결제할 금액: ' + \
                                           str(cal.return_total_amount()) + '원' + '\n' + \
                                           '받은 금액을 입력하세요.', min=cal.return_total_amount())
            if ok:
                reply = QMessageBox.question(self, '현금결제: 거스름돈',
                                             '결제할 금액: ' + str(cal.return_total_amount()) + '원' + '\n' + \
                                             '받은 금액: ' + str(cash) + '원' + '\n' + \
                                             '거스름돈: ' + str(cash - cal.return_total_amount()) + '원' + '\n' + \
                                             '이대로 결제합니까?',
                                             QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
                if reply == QMessageBox.Yes:
                    self.complete_payment('현금')

    @pyqtSlot()
    def pay_in_credit_card(self):
        if len(cal.cart_list) == 0:
            self.warn_pay_zero()
        else:
            reply = QMessageBox.question(
                self, '카드결제', '결제할 금액: ' + str(cal.return_total_amount()) +
                '원' + '\n' + '카드로 결제합니까?', QMessageBox.Yes | QMessageBox.No,
                QMessageBox.Yes)
            if reply == QMessageBox.Yes:
                self.complete_payment('카드')

    @pyqtSlot()
    def warn_pay_zero(self):
        msg = QMessageBox.information(self, '결제금액 경고', '결제금액은 0원일 수 없습니다.',
                                      QMessageBox.Ok, QMessageBox.Ok)

    @pyqtSlot(str)
    def complete_payment(self, payment_method_str):
        rec.receive_order(payment_method_str)
        msg = QMessageBox.information(
            self, '결제완료',
            '결제수단: ' + payment_method_str + '\n' + '결제가 완료되었습니다.',
            QMessageBox.Ok, QMessageBox.Ok)
        self.set_item_in_cart_table()
Ejemplo n.º 38
0
class MMWindow(QMainWindow):
    """Main Window class."""

    def __init__(self):
        """Class initializer."""
        super(MMWindow, self).__init__()
        # App data structures
        # Create the Media list object
        self.media_list = MediaList()
        # Variables for calculating total progress
        self.time_jump = 0.0
        self.partial_time = 0.0
        self.total_time = 0.0
        self.total_duration = 0.0

        # App interface setup
        # Window size
        self.resize(680, 576)
        # Set window title
        self.setWindowTitle('VideoMorph' + ' ' + VERSION)
        # Define and set app icon
        icon = QIcon()
        icon.addPixmap(QPixmap(':/logo/images/videomorph.png'))
        self.setWindowIcon(icon)
        # Define app central widget
        self.central_widget = QWidget(self)
        # Difine layouts
        self.vl = QVBoxLayout(self.central_widget)
        self.hl = QHBoxLayout()
        self.vl1 = QVBoxLayout()
        self.vl2 = QVBoxLayout()
        # Define groups
        self.group_settings()
        self.fix_layout()
        self.group_tasks_list()
        self.group_output_directory()
        self.group_progress()
        # Create the toolbar
        self.create_toolbar()
        # Add layouts
        self.hl.addLayout(self.vl2)
        self.vl.addLayout(self.hl)
        # Set central widget
        self.setCentralWidget(self.central_widget)
        # Create actions
        self.create_actions()
        # Populate PROFILES combo box
        self.populate_profiles()
        # Default conversion library
        self.conversion_lib = CONV_LIB.ffmpeg
        # Read app settings
        self.read_app_settings()

        # Create the converter according to the user selection of
        # conversion library

        self.converter = Converter(media_list=self.media_list,
                                   conversion_lib=self.conversion_lib)

        self.converter.process.setProcessChannelMode(QProcess.MergedChannels)
        self.converter.process.readyRead.connect(self._read_encoding_output)
        self.converter.process.finished.connect(self.finish_file_encoding)

        # Disable presets and profiles combo boxes
        self.cb_presets.setEnabled(False)
        self.cb_profiles.setEnabled(False)

        # Create app main menu bar
        self.create_main_menu()

        # Create app status bar
        self.create_status_bar()

        # Set tool buttons style
        self.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

    def group_settings(self):
        """Settings group."""
        gb_settings = QGroupBox(self.central_widget)
        gb_settings.setTitle(self.tr('Conversion Presets'))
        size_policy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
        size_policy.setHorizontalStretch(0)
        size_policy.setVerticalStretch(0)
        size_policy.setHeightForWidth(
            gb_settings.sizePolicy().hasHeightForWidth())
        gb_settings.setSizePolicy(size_policy)
        hl = QHBoxLayout(gb_settings)
        vl = QVBoxLayout()
        hl1 = QHBoxLayout()
        label = QLabel(self.tr('Convert to:'))
        hl1.addWidget(label)
        spacer_item = QSpacerItem(40,
                                  20,
                                  QSizePolicy.Expanding,
                                  QSizePolicy.Minimum)
        hl1.addItem(spacer_item)
        vl.addLayout(hl1)
        self.cb_profiles = QComboBox(
            gb_settings,
            statusTip=self.tr('Select the desired video format'))
        self.cb_profiles.setMinimumSize(QSize(200, 0))
        vl.addWidget(self.cb_profiles)
        hl2 = QHBoxLayout()
        label = QLabel(self.tr('Target Quality:'))
        hl2.addWidget(label)
        spacerItem1 = QSpacerItem(40,
                                  20,
                                  QSizePolicy.Expanding,
                                  QSizePolicy.Minimum)
        hl2.addItem(spacerItem1)
        vl.addLayout(hl2)
        self.cb_presets = QComboBox(
            gb_settings,
            statusTip=self.tr('Select the desired video quality'))
        self.cb_presets.setMinimumSize(QSize(200, 0))

        self.cb_profiles.currentIndexChanged.connect(partial(
            self.populate_presets, self.cb_presets))

        self.cb_presets.activated.connect(self.update_media_files_status)

        vl.addWidget(self.cb_presets)
        hl.addLayout(vl)
        self.vl1.addWidget(gb_settings)

    def fix_layout(self):
        """Fix widgets layout."""
        spacer_item = QSpacerItem(20,
                                  40,
                                  QSizePolicy.Minimum,
                                  QSizePolicy.Expanding)
        self.vl1.addItem(spacer_item)
        self.hl.addLayout(self.vl1)

    def group_tasks_list(self):
        """Define the Tasks Group arrangement."""
        gb_tasks = QGroupBox(self.central_widget)
        gb_tasks.setTitle(self.tr('List of Conversion Tasks'))
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(gb_tasks.sizePolicy().hasHeightForWidth())
        gb_tasks.setSizePolicy(sizePolicy)
        hl = QHBoxLayout(gb_tasks)
        self.tb_tasks = QTableWidget(gb_tasks)
        self.tb_tasks.setColumnCount(4)
        self.tb_tasks.setRowCount(0)
        self.tb_tasks.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tb_tasks.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tb_tasks.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch)
        self.tb_tasks.setHorizontalHeaderLabels(
            [self.tr('File Name'),
             self.tr('Duration'),
             self.tr('Target Quality'),
             self.tr('Progress')])
        self.tb_tasks.cellClicked.connect(self._enable_remove_file_action)
        # Create a combo box for Target quality
        self.tb_tasks.setItemDelegate(TargetQualityDelegate(parent=self))
        hl.addWidget(self.tb_tasks)
        self.vl2.addWidget(gb_tasks)
        self.tb_tasks.doubleClicked.connect(self.update_edit_triggers)

    def update_edit_triggers(self):
        if (int(self.tb_tasks.currentColumn()) == QUALITY and not
                self.converter.is_running):
            self.tb_tasks.setEditTriggers(QAbstractItemView.AllEditTriggers)
        else:
            self.tb_tasks.setEditTriggers(QAbstractItemView.NoEditTriggers)

    def group_output_directory(self):
        """Define the output directory Group arrangement."""
        gb_output = QGroupBox(self.central_widget)
        gb_output.setTitle(self.tr('Output Directory'))
        vl = QVBoxLayout(gb_output)
        vl1 = QVBoxLayout()
        hl = QHBoxLayout()
        self.le_output = QLineEdit(
            str(QDir.homePath()),
            statusTip=self.tr('Choose Output Directory'))
        self.le_output.setReadOnly(True)
        hl.addWidget(self.le_output)
        self.tb_output = QToolButton(
            gb_output,
            statusTip=self.tr('Choose Output Directory'))
        self.tb_output.setText('...')
        self.tb_output.clicked.connect(self.output_directory)
        hl.addWidget(self.tb_output)
        vl1.addLayout(hl)
        vl.addLayout(vl1)
        self.vl2.addWidget(gb_output)

    def group_progress(self):
        """Define the Progress Group arrangement."""
        gb_progress = QGroupBox(self.central_widget)
        gb_progress.setTitle(self.tr('Progress'))
        vl = QVBoxLayout(gb_progress)
        label_progress = QLabel(gb_progress)
        label_progress.setText(self.tr('Operation Progress'))
        vl.addWidget(label_progress)
        self.pb_progress = QProgressBar(gb_progress)
        self.pb_progress.setProperty('value', 0)
        vl.addWidget(self.pb_progress)
        label_total_progress = QLabel(gb_progress)
        label_total_progress.setText(self.tr('Total Progress'))
        vl.addWidget(label_total_progress)
        self.pb_total_progress = QProgressBar(gb_progress)
        self.pb_total_progress.setProperty('value', 0)
        vl.addWidget(self.pb_total_progress)
        self.vl2.addWidget(gb_progress)

    def read_app_settings(self):
        """Read the app settings."""
        settings = QSettings(QDir.homePath() + '/.videomorph/config.ini',
                             QSettings.IniFormat)
        pos = settings.value("pos", QPoint(600, 200), type=QPoint)
        size = settings.value("size", QSize(1096, 510), type=QSize)
        self.resize(size)
        self.move(pos)
        if 'profile' and 'preset' in settings.allKeys():
            prof = settings.value('profile')
            pres = settings.value('preset')
            self.cb_profiles.setCurrentIndex(int(prof))
            self.cb_presets.setCurrentIndex(int(pres))
        if 'output_dir' in settings.allKeys():
            self.le_output.setText(str(settings.value('output_dir')))
        if 'conversion_lib' in settings.allKeys():
            self.conversion_lib = settings.value('conversion_lib')

    def write_app_settings(self):
        """Write app settings on exit."""
        settings = QSettings(QDir.homePath() + '/.videomorph/config.ini',
                             QSettings.IniFormat)
        settings.setValue("pos", self.pos())
        settings.setValue("size", self.size())
        settings.setValue("profile", self.cb_profiles.currentIndex())
        settings.setValue("preset", self.cb_presets.currentIndex())
        settings.setValue("output_dir", self.le_output.text())
        settings.setValue('conversion_lib', self.conversion_lib)

    def closeEvent(self, event):
        """Things to todo on close."""
        # Disconnect the finished signal
        self.converter.process.finished.disconnect(self.finish_file_encoding)
        # Close communication and kill the encoding process
        if self.converter.is_running:
            self.converter.process.close()
            self.converter.process.kill()
        # Save settings
        self.write_app_settings()
        event.accept()

    def check_conversion_lib(self):
        """Check if ffmpeg or/and avconv are installed on the system."""
        if which(CONV_LIB.ffmpeg) or which(CONV_LIB.avconv):
            return True
        else:
            msg_box = QMessageBox(
                QMessageBox.Critical,
                self.tr('Error!'),
                self.tr('ffmpeg or avconv libraries not found in your system'),
                QMessageBox.NoButton, self)
            msg_box.addButton("&Ok", QMessageBox.AcceptRole)
            if msg_box.exec_() == QMessageBox.AcceptRole:
                qApp.closeAllWindows()
                return False

    def create_actions(self):
        """Create the actions and connect them to the tool bar buttons."""
        self.add_media_file_action = QAction(
            # Remove this line to use costume icons
            self.style().standardIcon(QStyle.SP_DialogOpenButton),
            self.tr('&Open'),
            self,
            shortcut="Ctrl+O",
            enabled=True,
            statusTip=self.tr('Add video files to the '
                              'list of conversion tasks'),
            triggered=self.add_media)
        # Uncomment this line to use costume icons
        # self.add_media_file_action.setIcon(QIcon(':/icons/images/abrir.png'))

        self.clear_media_list_action = QAction(
            # Remove this line to use costume icons
            self.style().standardIcon(QStyle.SP_TrashIcon),
            self.tr('Clear &List'),
            self,
            shortcut="Ctrl+Del",
            enabled=False,
            statusTip=self.tr('Clear the Media List'),
            triggered=self.clear_media_list)
        # Uncomment this line to use costume icons
        # self.clear_media_list_action.setIcon(QIcon(':/icons/images/limpiar.png'))

        self.remove_media_file_action = QAction(
            # Remove this line to use costume icons
            self.style().standardIcon(QStyle.SP_BrowserStop),
            self.tr('&Remove File'),
            self,
            shortcut="Del",
            enabled=False,
            statusTip=self.tr('Remove Video Files from the List'),
            triggered=self.remove_media_file)
        # Uncomment this line to use costume icons
        # self.remove_media_file_action.setIcon(QIcon(':/icons/images/eliminar.png'))

        self.convert_action = QAction(
            # Remove this line to use costume icons
            self.style().standardIcon(QStyle.SP_MediaPlay),
            self.tr('&Convert'),
            self,
            shortcut="Ctrl+R",
            enabled=False,
            statusTip=self.tr('Start Conversion Process'),
            triggered=self.start_encoding)
        # Uncomment this line to use costume icons
        # self.convert_action.setIcon(QIcon(':/icons/images/convertir.png'))

        self.stop_action = QAction(
            # Remove this line to use costume icons
            self.style().standardIcon(QStyle.SP_MediaStop),
            self.tr('&Stop'),
            self,
            shortcut="Ctrl+P",
            enabled=False,
            statusTip=self.tr('Stop Video File Conversion'),
            triggered=self.stop_file_encoding)
        # Uncomment this line to use costume icons
        # self.stop_action.setIcon(QIcon(':/icons/images/parar.png'))

        self.about_action = QAction(
            # Remove this line to use costume icons
            self.style().standardIcon(QStyle.SP_MessageBoxInformation),
            self.tr('&About'),
            self,
            shortcut="Ctrl+H",
            enabled=True,
            statusTip=self.tr('About VideoMorph {v}'.format(v=VERSION)),
            triggered=self.about)
        # Uncomment this line to use costume icons
        # self.about_action.setIcon(QIcon(':/icons/images/parar.png'))

        self.exit_action = QAction(
            self.style().standardIcon(QStyle.SP_DialogCloseButton),
            self.tr('E&xit'),
            self,
            shortcut="Ctrl+Q",
            enabled=True,
            statusTip=self.tr('Exit VideoMorph {v}'.format(v=VERSION)),
            triggered=self.close)

        self.settings_action = QAction(
            self.style().standardIcon(QStyle.SP_FileDialogDetailedView),
            self.tr('&Settings...'),
            self,
            shortcut="Ctrl+S",
            enabled=True,
            statusTip=self.tr('Open VideoMorph {v} Settings Dialog'.format(
                v=VERSION)),
            triggered=self.settings)

        # Add actions to the tool bar
        self.tool_bar.addAction(self.add_media_file_action)
        self.tool_bar.addSeparator()
        self.tool_bar.addAction(self.clear_media_list_action)
        self.tool_bar.addAction(self.remove_media_file_action)
        self.tool_bar.addSeparator()
        self.tool_bar.addAction(self.convert_action)
        self.tool_bar.addAction(self.stop_action)
        self.tool_bar.addSeparator()
        self.tool_bar.addAction(self.settings_action)

    def create_main_menu(self):
        self.file_menu = self.menuBar().addMenu(self.tr('&File'))
        self.file_menu.addAction(self.add_media_file_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.settings_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.exit_action)

        self.edit_menu = self.menuBar().addMenu(self.tr('&Edit'))
        self.edit_menu.addAction(self.clear_media_list_action)
        self.edit_menu.addAction(self.remove_media_file_action)

        self.convert_menu = self.menuBar().addMenu(self.tr('&Conversion'))
        self.convert_menu.addAction(self.convert_action)
        self.convert_menu.addAction(self.stop_action)

        self.hel_menu = self.menuBar().addMenu(self.tr('&Help'))
        self.hel_menu.addAction(self.about_action)

    def create_toolbar(self):
        """Create and add_file a tool bar to the interface."""
        self.tool_bar = QToolBar(self)
        self.addToolBar(Qt.TopToolBarArea, self.tool_bar)

    def create_status_bar(self):
        self.statusBar().showMessage(self.tr('Ready'))

    def about(self):
        a = AboutVM(parent=self)
        a.exec_()

    def settings(self):
        s = SettingsDialog(parent=self)
        if self.conversion_lib == CONV_LIB.ffmpeg:
            s.radio_btn_ffmpeg.setChecked(True)
        elif self.conversion_lib == CONV_LIB.avconv:
            s.radio_btn_avconv.setChecked(True)

        if not which(CONV_LIB.ffmpeg):
            s.radio_btn_ffmpeg.setEnabled(False)
        elif not which(CONV_LIB.avconv):
            s.radio_btn_avconv.setEnabled(False)

        if s.exec_():
            if s.radio_btn_ffmpeg.isChecked():
                self.conversion_lib = CONV_LIB.ffmpeg
                self.converter.conversion_lib = self.conversion_lib
            elif s.radio_btn_avconv.isChecked():
                self.conversion_lib = CONV_LIB.avconv
                self.converter.conversion_lib = self.conversion_lib

    def get_prober(self):
        if self.conversion_lib == CONV_LIB.ffmpeg:
            return 'ffprobe'
        elif self.conversion_lib == CONV_LIB.avconv:
            return 'avprobe'

    def populate_profiles(self):
        """Populate profiles combo box."""
        self.cb_profiles.addItems(PROFILES.keys())

    def populate_presets(self, cb_presets):
        """Populate presets combo box."""
        profile = self.cb_profiles.currentText()
        cb_presets.clear()

        for preset in PROFILES[profile].presets:
            cb_presets.addItem(preset)

        self.update_media_files_status()

    def output_directory(self):
        """Choose output directory."""
        options = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly
        directory = QFileDialog.getExistingDirectory(
            self,
            self.tr('Choose Output Directory'),
            QDir.homePath(),
            options=options)

        if directory:
            self.le_output.setText(directory)

    def add_media(self):
        """Add media files to the list of conversion tasks."""
        # Dialog title
        title = self.tr('Select Files')
        # Media filters
        v_filter = (self.tr('Video files') +
                    '(*.mkv *.ogg *.mp4 *.mpg *.dat '
                    '*.f4v *.flv *.wv *.3gp *.avi *.webm '
                    '*.wmv *.mov *.vob *.ogv *.ts)')
        # Select media files and store their path
        media_paths, _ = QFileDialog.getOpenFileNames(self,
                                                      title,
                                                      QDir.homePath(),
                                                      v_filter)
        # If no file is selected then return
        if not media_paths:
            return

        # Count rows in the tasks table
        rows = self.tb_tasks.rowCount()

        # This rewind the encoding list if the encoding process is not running
        if not self.converter.is_running:
            self.media_list.running_index = -1
        # Add selected medias to the table and to MediaList using threads to
        # minimize delay
        threads = []
        for media_path in media_paths:

            t = MediaFileThread(
                media_path=media_path,
                target_quality=str(self.cb_presets.currentText()),
                prober=self.get_prober())
            t.start()
            threads.append(t)

        for t in threads:
            t.join()

        for thread in threads:

            try:
                self.media_list.add_file(thread.media_file)
                self.tb_tasks.setRowCount(rows + 1)
            except FileAddedError:
                del thread.media_file
                continue
            # Test if the file was added to the list
            # (0 duration files are not added)
            if thread.media_file in self.media_list:
                item = QTableWidgetItem()
                item.setText(thread.media_file.get_name(with_extension=True))
                self.tb_tasks.setItem(rows, NAME, item)
                item = QTableWidgetItem()
                file_duration = str(
                    write_time(thread.media_file.info.format_duration))
                item.setText(file_duration)
                self.tb_tasks.setItem(rows, DURATION, item)
                item = QTableWidgetItem()
                item.setText(str(self.cb_presets.currentText()))

                self.tb_tasks.setItem(rows, QUALITY, item)
                item = QTableWidgetItem()
                item.setText(self.tr('To convert'))
                self.tb_tasks.setItem(rows, PROGRESS, item)
                # Next table row
                rows += 1
        # After adding files to the list, recalculate the list duration
        self.total_duration = self.media_list.duration
        # Update tool buttons so you can convert, or add_file, or clear...
        self.update_interface(stop=False, remove=False)

    def remove_media_file(self):
        """Remove selected media file from the list."""
        item = self.tb_tasks.currentItem().row()
        if item is not None:
            # Delete file from table
            self.tb_tasks.removeRow(item)
            # If all files are deleted... update the interface
            if not self.tb_tasks.rowCount():
                self.update_interface(convert=False,
                                      clear=False,
                                      remove=False,
                                      stop=False,
                                      presets=False,
                                      profiles=False)
            # Remove file from MediaList
            self.media_list.delete_file(file_index=item)
            self.total_duration = self.media_list.duration

    def clear_media_list(self):
        """Clear media conversion list with user confirmation."""
        msg_box = QMessageBox(
            QMessageBox.Warning,
            self.tr('Warning!'),
            self.tr('Clear all tasks?'),
            QMessageBox.NoButton, self)

        msg_box.addButton(self.tr("&Yes"), QMessageBox.AcceptRole)
        msg_box.addButton(self.tr("&No"), QMessageBox.RejectRole)

        if msg_box.exec_() == QMessageBox.AcceptRole:
            # If use says YES clear table of conversion tasks
            self.tb_tasks.clearContents()
            self.tb_tasks.setRowCount(0)
            # Clear MediaList.medias so it does not contain any element
            self.media_list.clear()
            # Update buttons so user cannot convert, clear, or stop if there
            # is no file in the list
            self.update_interface(convert=False,
                                  clear=False,
                                  remove=False,
                                  stop=False,
                                  presets=False,
                                  profiles=False)

    def start_encoding(self):
        """Start the encoding process."""
        # Update tool buttons state
        self.update_interface(presets=False,
                              profiles=False,
                              convert=False,
                              clear=False,
                              remove=False,
                              output_dir=False,
                              settings=False)

        # Increment the the MediaList index
        self.media_list.running_index += 1

        running_media = self.media_list.get_running_file()

        if (not running_media.status == STATUS.done and not
                running_media.status == STATUS.stopped):

            self.converter.start_encoding(
                cmd=self.media_list.get_running_file().get_conversion_cmd(
                    output_dir=self.le_output.text()))
        else:
            self.end_encoding_process()

    def stop_file_encoding(self):
        """Stop file encoding process and continue with the list."""
        # Set MediaFile.status attribute
        self.media_list.get_running_file().status = STATUS.stopped
        # Update the list duration and partial time for total progress bar
        self.total_duration = self.media_list.duration
        self.time_jump = 0.0
        self.partial_time = 0.0
        self.total_time = 0.0
        # Terminate the file encoding
        self.converter.stop_encoding()

    def finish_file_encoding(self):
        """Finish the file encoding process."""
        if not self.media_list.get_running_file().status == STATUS.stopped:
            # Close and kill the converter process
            self.converter.process.close()
            # Check if the process finished OK
            if self.converter.process.exitStatus() == QProcess.NormalExit:
                # When finished a file conversion...
                self.tb_tasks.item(self.media_list.running_index, 3).setText(
                    self.tr('Done!'))
                self.media_list.get_running_file().status = STATUS.done
                self.pb_progress.setProperty("value", 0)
            # Attempt to end the conversion process
            self.end_encoding_process()
        else:
            # If the process was stopped
            if not self.converter.is_running:
                self.tb_tasks.item(self.media_list.running_index, 3).setText(
                    self.tr('Stopped!'))
            # Attempt to end the conversion process
            self.end_encoding_process()

    def end_encoding_process(self):

        # Test if encoding process is finished
        if self.converter.encoding_done:
            msg_box = QMessageBox(
                QMessageBox.Information,
                self.tr('Finished!'),
                self.tr('Encoding process successfully finished!'),
                QMessageBox.Ok,
                self)
            msg_box.show()
            self.statusBar().showMessage(self.tr('Ready'))
            # Reset all progress related variables
            self.pb_progress.setProperty("value", 0)
            self.pb_total_progress.setProperty("value", 0)
            self.time_jump = 0.0
            self.partial_time = 0.0
            self.total_time = 0.0
            self.total_duration = self.media_list.duration
            # Reset the running_index
            self.media_list.running_index = -1
            # Update tool buttons
            self.update_interface(convert=False, stop=False, remove=False)
        else:
            self.start_encoding()

    def _read_encoding_output(self):
        """Read the encoding output from the self.converter stdout."""
        time_pattern = re.compile(r'time=([0-9.:]+) ')
        ret = str(self.converter.process.readAll())
        time = time_pattern.findall(ret)

        if time:
            # Convert time to seconds
            if ':' in time[0]:
                time_in_secs = 0
                for part in time[0].split(':'):
                    time_in_secs = 60 * time_in_secs + float(part)
            else:
                time_in_secs = float(time[0])

            # Calculate operation progress percent
            op_time = self.media_list.get_running_file().info.format_duration
            operation_progress = int(time_in_secs / float(op_time) * 100)

            # Update the table and the operation progress bar
            self.pb_progress.setProperty("value", operation_progress)
            self.tb_tasks.item(self.media_list.running_index, 3).setText(
                str(operation_progress) + "%")

            # Calculate total time
            if self.partial_time > time_in_secs:
                self.time_jump += self.partial_time
                self.total_time = self.time_jump + time_in_secs
                self.partial_time = time_in_secs
            else:
                self.total_time = self.time_jump + time_in_secs
                self.partial_time = time_in_secs

            # Calculate total progress percent
            total_progress = int(self.total_time /
                                 float(self.total_duration) *
                                 100)
            # Update the total progress bar
            self.pb_total_progress.setProperty("value",
                                               total_progress)

            self.statusBar().showMessage(
                self.tr('Converting: {m}\t\t\t '
                        'Operation remaining time: {rt}\t\t\t '
                        'Total remaining time: {trt}').format(
                    m=self.media_list.get_running_file().get_name(True),
                    rt=write_time(float(op_time) - time_in_secs),
                    trt=write_time(
                        self.total_duration - self.total_time)))

    # TODO: Review this and setEditorData for repeated code
    def update_media_files_status(self):
        """Update target Quality."""
        # Current item
        item = self.tb_tasks.currentItem()
        if item is not None:
            # Update target_quality in table
            self.tb_tasks.item(item.row(), QUALITY).setText(
                str(self.cb_presets.currentText()))
            # Update file target_quality
            self.media_list.get_file(item.row()).target_quality = str(
                self.cb_presets.currentText())
            # Update table Progress field if file is: Done or Stopped
            if (self.media_list.get_file_status(item.row()) == STATUS.done or
                    self.media_list.get_file_status(
                        item.row()) == STATUS.stopped):
                self.tb_tasks.item(item.row(), PROGRESS).setText(
                    self.tr('To convert'))
            # Update file Done or Stopped status
            self.media_list.set_file_status(file_index=item.row(),
                                            status=STATUS.todo)
            # Update total duration of the new tasks list
            self.total_duration = self.media_list.duration
            # Update the interface
            self.update_interface(clear=False, stop=False, remove=False)
        else:
            if self.tb_tasks.rowCount():
                for i in range(self.tb_tasks.rowCount()):
                    self.tb_tasks.item(i, QUALITY).setText(
                        str(self.cb_presets.currentText()))

                    if (self.media_list.get_file_status(i) == STATUS.done or
                            self.media_list.get_file_status(
                                i) == STATUS.stopped):
                        self.tb_tasks.item(i, PROGRESS).setText(
                            self.tr('To convert'))

                    self.media_list.get_file(i).target_quality = str(
                        self.cb_presets.currentText())
                self.update_interface(clear=False, stop=False, remove=False)
            self._set_media_status()
            self.total_duration = self.media_list.duration

    def _set_media_status(self):
        """Update media files state of conversion."""
        for media_ in self.media_list:
            media_.status = STATUS.todo
        self.media_list.running_index = -1

    def update_interface(self,
                         add=True,
                         convert=True,
                         clear=True,
                         remove=True,
                         stop=True,
                         presets=True,
                         profiles=True,
                         output_dir=True,
                         settings=True):
        self.add_media_file_action.setEnabled(add)
        self.convert_action.setEnabled(convert)
        self.clear_media_list_action.setEnabled(clear)
        self.remove_media_file_action.setEnabled(remove)
        self.stop_action.setEnabled(stop)
        self.cb_presets.setEnabled(presets)
        self.cb_profiles.setEnabled(profiles)
        self.tb_output.setEnabled(output_dir)
        self.tb_tasks.setCurrentItem(None)
        self.settings_action.setEnabled(settings)

    def _enable_remove_file_action(self):
        if not self.converter.is_running:
            self.remove_media_file_action.setEnabled(True)