def setupTabs(self):
        """ Setup the various tabs in the AddressWidget. """
        groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"]

        for group in groups:
            proxyModel = QSortFilterProxyModel(self)
            proxyModel.setSourceModel(self.tableModel)
            proxyModel.setDynamicSortFilter(True)

            tableView = QTableView()
            tableView.setModel(proxyModel)
            tableView.setSortingEnabled(True)
            tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
            tableView.horizontalHeader().setStretchLastSection(True)
            tableView.verticalHeader().hide()
            tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
            tableView.setSelectionMode(QAbstractItemView.SingleSelection)

            # This here be the magic: we use the group name (e.g. "ABC") to
            # build the regex for the QSortFilterProxyModel for the group's
            # tab. The regex will end up looking like "^[ABC].*", only
            # allowing this tab to display items where the name starts with
            # "A", "B", or "C". Notice that we set it to be case-insensitive.
            reFilter = "^[%s].*" % group

            proxyModel.setFilterRegExp(QRegExp(reFilter, Qt.CaseInsensitive))
            proxyModel.setFilterKeyColumn(0)  # Filter on the "name" column
            proxyModel.sort(0, Qt.AscendingOrder)

            # This prevents an application crash (see: http://www.qtcentre.org/threads/58874-QListView-SelectionModel-selectionChanged-Crash)
            viewselectionmodel = tableView.selectionModel()
            tableView.selectionModel().selectionChanged.connect(
                self.selectionChanged)

            self.addTab(tableView, group)
    def setupTabs(self):
        """ Setup the various tabs in the AddressWidget. """
        groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"]

        for group in groups:
            proxyModel = QSortFilterProxyModel(self)
            proxyModel.setSourceModel(self.tableModel)
            proxyModel.setDynamicSortFilter(True)

            tableView = QTableView()
            tableView.setModel(proxyModel)
            tableView.setSortingEnabled(True)
            tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
            tableView.horizontalHeader().setStretchLastSection(True)
            tableView.verticalHeader().hide()
            tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
            tableView.setSelectionMode(QAbstractItemView.SingleSelection)

            # This here be the magic: we use the group name (e.g. "ABC") to
            # build the regex for the QSortFilterProxyModel for the group's
            # tab. The regex will end up looking like "^[ABC].*", only
            # allowing this tab to display items where the name starts with
            # "A", "B", or "C". Notice that we set it to be case-insensitive.
            reFilter = "^[%s].*" % group

            proxyModel.setFilterRegExp(QRegExp(reFilter, Qt.CaseInsensitive))
            proxyModel.setFilterKeyColumn(0) # Filter on the "name" column
            proxyModel.sort(0, Qt.AscendingOrder)

            # This prevents an application crash (see: http://www.qtcentre.org/threads/58874-QListView-SelectionModel-selectionChanged-Crash)
            viewselectionmodel = tableView.selectionModel()
            tableView.selectionModel().selectionChanged.connect(self.selectionChanged)

            self.addTab(tableView, group)
class AddressWidget(QDialog):

    selectionChanged = Signal(QItemSelection)

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

        self.tableModel = TableModel()
        self.tableView = QTableView()
        self.setupTable()

        statusLabel = QLabel("Tabular data view demo")

        layout = QVBoxLayout()
        layout.addWidget(self.tableView)
        layout.addWidget(statusLabel)
        self.setLayout(layout)
        self.setWindowTitle("Address Book")
        self.resize(800,500)

        # add test data
        self.populateTestData()

    def setupTable(self):
        proxyModel = QSortFilterProxyModel(self)
        proxyModel.setSourceModel(self.tableModel)
        proxyModel.setDynamicSortFilter(True)

        self.tableView.setModel(proxyModel)
        self.tableView.setSortingEnabled(True)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.verticalHeader().hide()
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)

        proxyModel.setFilterKeyColumn(0)  # Filter on the "name" column
        proxyModel.sort(0, Qt.AscendingOrder)
        viewselectionmodel = self.tableView.selectionModel()
        self.tableView.selectionModel().selectionChanged.connect(self.selectionChanged)



    def populateTestData(self):
        addresses = [{"name": "John Doe", "address": "Alameda"},
                     {"name": "Alan Turing", "address": "San Deigo"},
                     {"name": "Bjarne Stroutsup", "address": "Columbia"},
                     {"name": "Herb Sutter", "address": "Seattle"},
                     {"name": "Micheal Konin", "address": "Colorado"}]

        for i in range(len(addresses)):
            self.tableModel.insertRows(0)
            ix = self.tableModel.index(0, 0, QModelIndex())
            self.tableModel.setData(ix, addresses[i]["name"], Qt.EditRole)

            ix = self.tableModel.index(0, 1, QModelIndex())
            self.tableModel.setData(ix, addresses[i]["address"], Qt.EditRole)

            self.tableView.resizeRowToContents(ix.row())
Exemple #4
0
    def __init__(self, data_list, header, *args):
        QWidget.__init__(self, *args)

        # setGeometry(x_pos, y_pos, width, height)
        self.setGeometry(300, 200, 570, 450)
        self.setWindowTitle('Click on column title to sort')

        # Setup the model and view
        '''tmodel = MyTableModel(self, data_list, header)
        tview = QTableView()
        tview.setModel(tmodel)
        delegate = MyDelegate()
        tview.setItemDelegate(delegate)'''

        # Setup the proxy model for sorting and filtering
        tmodel = MyTableModel(self, data_list, header)
        pmodel = QSortFilterProxyModel()
        pmodel.setSourceModel(tmodel)

        tview = QTableView()
        tview.setModel(pmodel)
        delegate = MyDelegate()
        tview.setItemDelegate(delegate)

        # TableView properties
        tview.resizeColumnsToContents()  # set column width to fit contents
        tview.setShowGrid(False)  # hide gridlines
        #tview.verticalHeader().hide() # row labels
        #tview.horizontalHeader().hide() # column labels

        # Select a single row at a time
        tview.setSelectionBehavior(QTableView.SelectRows)
        tview.setSelectionMode(QTableView.SingleSelection)

        # Enable sorting
        tview.setSortingEnabled(True)

        # Drag and drop reordering using header labels
        '''tview.verticalHeader().setSectionsMovable(True)
        tview.verticalHeader().setDragEnabled(True)
        tview.verticalHeader().setDragDropMode(QAbstractItemView.InternalMove)

        tview.horizontalHeader().setSectionsMovable(True)
        tview.horizontalHeader().setDragEnabled(True)
        tview.horizontalHeader().setDragDropMode(QAbstractItemView.InternalMove)'''

        # Drag and drop reordering using rows
        tview.setDragEnabled(True)
        tview.setAcceptDrops(True)
        tview.setDragDropMode(QTableView.InternalMove)
        tview.setDragDropOverwriteMode(False)

        layout = QVBoxLayout(self)
        layout.addWidget(tview)
        self.setLayout(layout)
Exemple #5
0
def test():
    class XTest( XBase ):
        def __init__( self ):
            XBase.__init__( self )
            self.name = ""
            self.vorname = ""
            self.alter = 0
            self.haarfarbe = ""
            self.schuhgroesse = 0
            self.bemerkung = ""

    x1 = XTest()
    x1.name = "Kendel"
    x1.vorname = "Martin"
    x1.alter = 66
    x1.haarfarbe = "grau"
    x1.schuhgroesse = 44
    x1.bemerkung = "Das ist alles \nein riesengroßer Irrtum"

    x2 = XTest()
    x2.name = "Haaretz"
    x2.vorname = "Yosh"
    x2.alter = 56
    x2.haarfarbe = "schwarz"
    x2.schuhgroesse = 42

    tm = DefaultIccTableModel( (x1, x2 ) )
    tm.setSortable( True )
    tm.setKeyHeaderMappings( { "Nachname": "name", "Vorname": "vorname", "Alter": "alter", "Bemerkung": "bemerkung" } )
    tm.setNumColumnsIndexes( (2,) )

    from PySide2.QtWidgets import QApplication
    app = QApplication()

    tv = QTableView( )
    tv.setModel( tm )
    tv.setAlternatingRowColors( True )
    tv.setSortingEnabled( True )
    tv.resizeColumnsToContents()
    tv.resizeRowsToContents()
    tm.layoutChanged.connect( tv.resizeRowsToContents ) ## <======== WICHTIG bei mehrzeiligem Text in einer Zelle!
    tv.show()

    app.exec_()
class manageMembers(QMainWindow):
    def __init__(self, parent):
        super(manageMembers, self).__init__(parent)
        self.setWindowTitle("Tagok kezelése")
        widget = QWidget()
        main_layout = QHBoxLayout()
        widget.setLayout(main_layout)

        self.setCentralWidget(widget)
        # self.client = MysqlClient()
        self.table_view = QTableView()
        # self.model = TableModel(self.table_name, fejlec)
        self.model = QSqlTableModel(db=db)
        # a megjelenített tábla neve
        self.table_name = "members"

        main_layout.addWidget(self.table_view)
        fejlec = [
            'id', "Vezetéknév", "Utónév", "Született", "Ir.szám", "Helység",
            "Cím", "Telefon", "E-mail", "Tagság kezdete", 'Aktív'
        ]

        # self.model = TableModel(self.table_name)
        # print(self.model)

        self.table_view.setModel(self.model)
        self.table_view.setSortingEnabled(True)
        # Az első oszlop (id) elrejtése
        self.table_view.hideColumn(0)
        self.table_view.resizeColumnsToContents()

        gomb_layout = QVBoxLayout()
        main_layout.addLayout(gomb_layout)

        self.delete_button = QPushButton("&Tag törlése")
        self.add_button = QPushButton("&Új tag")
        self.modify_button = QPushButton("Tag &módosítása")

        gomb_layout.addWidget(self.delete_button)
        gomb_layout.addWidget(self.add_button)
        gomb_layout.addWidget(self.modify_button)
        self.space = QSpacerItem(0, 0, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        gomb_layout.addItem(self.space)

        # self.resize(320, 200)
        self.setFixedSize(1000, 800)
        # self.showMaximized()
        # self.setWindowFlags(Qt.Window|Qt.WindowTitleHint)
        tb = self.addToolBar("File")

        exit = QAction(QIcon("images/door--arrow.png"), "Kilépés", self)
        tb.addAction(exit)

        excel = QAction(QIcon("images/excel.png"), "Excel", self)
        tb.addAction(excel)

        tb.actionTriggered[QAction].connect(self.toolbarpressed)

        # self.delete_button.clicked.connect(lambda: self.model.delete(self.table_view.selectedIndexes()[0]))
        self.delete_button.clicked.connect(self.tag_torles)
        self.add_button.clicked.connect(self.model.add)
        self.modify_button.clicked.connect(self.tag_modositas)

    def tag_torles(self):
        if len(self.table_view.selectedIndexes()) > 0:
            self.model.delete(self.table_view.selectedIndexes()[0])
        else:
            reply = QMessageBox.question(None, 'Hiba!',
                                         'Törlés előtt jelöljön ki egy sort!',
                                         QMessageBox.Ok)

    def tag_modositas(self):
        if len(self.table_view.selectedIndexes()) > 0:
            self.model.modify(self.table_view.selectedIndexes()[0])
        else:
            reply = QMessageBox.question(
                None, 'Hiba!', 'Módosítás előtt jelöljön ki egy sort!',
                QMessageBox.Ok)

    def toolbarpressed(self, a):
        # print("Pressed:", a.text())
        if a.text() == "Kilépés":
            self.close()
        if a.text() == "Excel":
            # print("Indulhat az excel exportálás")
            self.adatok = self.client.get_all(self.table_name)
            self._data = self.adatok[0]
            # print(self._data)
            p.save_as(array=self._data, dest_file_name="tagok.xlsx")
Exemple #7
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setWindowTitle("VW Competitive")
        self.setWindowIcon(QIcon(':/images/vw.png'))
        """
        Test wstawienia wartosci do tabeli
        """
        self.table = QTableView()
        self.setCentralWidget(self.table)
        self.sti = QStandardItemModel()
        self.sti.setColumnCount(6)
        self.table.setModel(self.sti)
        self.table.verticalHeader().setDefaultSectionSize(10)
        self.table.horizontalHeader().setDefaultSectionSize(200)
        self.headers = [
            'Year', 'Month', 'Week', 'Sector', 'Category', 'Sub Category',
            'Produkt(4)', 'Branża(I)', 'Kategoria(II)', 'Dział(III)',
            'Producer', 'Brand', 'Sub Brand', 'Film Code', 'Film Code 2',
            'Media', 'Glowne Medium', 'Medium', 'Wydawca Nadawca',
            'Periodyczność', 'Duration', 'Typ reklamy', 'Forma Reklamy',
            'Typ Strony', 'L.emisji', 'Sum.Str', 'Cost', 'PT/OFF', 'TRP',
            'TRP30', 'Channel group', 'Channel type', 'Wyprz', 'Upus', 'Rabat',
            'Wyprze Upust Rabat', 'Model', 'Brand final',
            'Subbrand (brand+Model)', 'Brand Type', 'Segment_detailed',
            'Segment', 'Segment_combined', 'Campaign Type'
        ]
        """
        Forms
        """
        self.excel_form = ExcelForm(self.headers, self)
        self.connect_form = ConnectRaports(self)
        self.filechoser = FileChoser(self)
        self.for_find_duplicate = FindDuplicate(self)
        self.filters_manager = FiltersManager(self)

        self.sti.setHorizontalHeaderLabels(self.headers)
        self.sti.setColumnCount(len(self.headers))
        self.table.setSortingEnabled(True)
        #self.table.horizontalHeader().connect()
        self.connect(self.table.horizontalHeader(),
                     SIGNAL("sectionClicked(int)"), self.showfilterforms)

        self.createActions()
        self.createMenus()
        self.createStatusBar()
        self.readSettings()
        self.set_color_on_header()

    def closeEvent(self, event):
        self.close()

    def open(self):
        self.filechoser.show()
        self.filechoser.clead_data()

    def save(self):
        """
        save data to data base
        :return:
        """
        #deleta rows from data base for compative name
        session = Session()
        comat = session.query(Competitive).filter(
            Competitive.name.ilike(f'%{self.compative_name}%')).first()
        session.query(Data).filter_by(competitive_id=comat.id).delete()

        #read data from row and save to data base
        for row in range(self.sti.rowCount()):
            datas = []
            for col in range(self.sti.columnCount()):
                if col in (0, 1, 2, 20, 24):
                    try:
                        #tutaj poprawic nie chce wpisać
                        if self.sti.item(row, col) is not None:
                            datas.append(int(self.sti.item(row, col).text()))
                        else:
                            datas.append(None)
                    except ValueError:
                        datas.append(None)
                elif col in (25, 26, 28, 29):
                    try:
                        if self.sti.item(row, col) is not None:
                            datas.append(float(self.sti.item(row, col).text()))
                        else:
                            datas.append(None)
                    except ValueError:
                        datas.append(None)
                else:
                    if self.sti.item(row, col) is not None:
                        datas.append(self.sti.item(row, col).text())
                    else:
                        datas.append(None)

            comat.datas.append(Data(*datas))

        session.commit()
        session.close()
        QMessageBox.information(self, "Zapis",
                                "Zapis zakonczyl się powodzeniem.")

    def createActions(self):
        self.openAct = QAction(QIcon(':/images/open.png'),
                               "&Otwórz...",
                               self,
                               shortcut=QKeySequence.Open,
                               statusTip="Otwóż nowe pliki",
                               triggered=self.open)

        self.saveAct = QAction(QIcon(':/images/save.png'),
                               "&Zapisz...",
                               self,
                               shortcut=QKeySequence.Save,
                               statusTip="Zapisz plik",
                               triggered=self.save)

        self.exitAct = QAction("&Zamknij",
                               self,
                               shortcut="Ctrl+Q",
                               statusTip="Zamknij aplikacje",
                               triggered=self.close)

        self.runWordFilter = QAction("Filtry &Automatyczne",
                                     shortcut="Ctrl+A",
                                     statusTip="Urchom filtry automatyczne",
                                     triggered=self.run_filters)

        self.showExcelForm = QAction("Generuj plik excel",
                                     triggered=self.show_excel_form)

        self.ConnectRaports = QAction("Połącz raporty",
                                      triggered=self.show_connect_raports)

        self.FindDuplicate = QAction("Znajdz duplikaty",
                                     triggered=self.show_duplicate_form)

        self.FilterManager = QAction("Filtry Manualne",
                                     triggered=self.show_filter_manager)

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu("&Plik")
        self.fileMenu.addAction(self.openAct)
        self.fileMenu.addAction(self.saveAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAct)

        self.filterMenu = self.menuBar().addMenu("&Filtry")
        self.filterMenu.addAction(self.runWordFilter)
        self.filterMenu.addAction(self.FilterManager)

        self.excelMenu = self.menuBar().addMenu("&Raporty")
        self.excelMenu.addAction(self.showExcelForm)
        self.excelMenu.addAction(self.ConnectRaports)
        self.excelMenu.addAction(self.FindDuplicate)

    def contextMenuEvent(self, event):
        contextMenu = QMenu(self)
        removeAction = contextMenu.addAction('Usuń')

        action = contextMenu.exec_(self.mapToGlobal(event.pos()))

        if action == removeAction:
            index_list = []
            for model_index in self.table.selectionModel().selectedRows():
                index = QPersistentModelIndex(model_index)
                index_list.append(index)

            for index in index_list:
                self.sti.removeRow(index.row())

    def createStatusBar(self):
        self.statusBar().showMessage("Ready")

    def readSettings(self):
        settings = QSettings("Trolltech", "Application Example")
        pos = settings.value("pos", QPoint(200, 200))
        size = settings.value("size", QSize(800, 800))
        self.resize(size)
        self.move(pos)

    def get_data(self, paths, compative_name):
        """
        receives data from the filechose form
        :param paths: dictionary with paht to techege, adexpert
        :param compative_name: name of raport
        :return:
        """
        self.compative_name = compative_name
        if len(paths[0]) > 0:
            self.techegedata = Excel.get_data(paths[0])
        else:
            self.techegedata = None
        if len(paths[1]) > 0:
            self.adxpert = Excel.get_data(paths[1], False)
        else:
            self.adxpert = None

        #wczytanie arkusza z bazy danych
        session = Session()
        self.compativedata = session.query(Competitive).filter_by(
            name=compative_name).first()

        self.populate_row()
        session.close()

    def populate_row(self):
        """
        read data from compatiedate, techegedata, adxpert and past to rows
        :return:
        """
        # without this section data in column one don't show
        self.sti.setRowCount(0)
        self.sti.setRowCount(1)

        font = QFont()
        font.setPointSize(8)

        #add data from data base
        if self.compativedata:
            for row in self.compativedata.datas:
                rownr = self.sti.rowCount()
                rowvalue = row.values()
                for nr, value in enumerate(rowvalue):
                    item = QStandardItem(f'{value}')
                    item.setFont(font)
                    self.sti.setItem(rownr - 1, nr, item)
                    self.sti.setRowCount(rownr + 1)

        #add data from techegedata
        if self.techegedata:
            for rownr in range(len(self.techegedata[0])):
                self.sti.setRowCount(self.sti.rowCount() + 1)
                for colnr in range(len(self.techegedata)):
                    if len(self.techegedata[colnr]) == 0:
                        continue
                    item = QStandardItem(f'{self.techegedata[colnr][rownr]}')
                    item.setFont(font)
                    self.sti.setItem(self.sti.rowCount() - 2, colnr, item)

        #add data from adexpert
        if self.adxpert:
            for rownr in range(len(self.adxpert[0])):
                self.sti.setRowCount(self.sti.rowCount() + 1)
                for colnr in range(len(self.adxpert)):
                    if len(self.adxpert[colnr]) == 0:
                        continue
                    item = QStandardItem(f'{self.adxpert[colnr][rownr]}')
                    item.setFont(font)
                    self.sti.setItem(self.sti.rowCount() - 2, colnr, item)

        self.sti.removeRow(self.sti.rowCount() - 1)
        self.table.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        QMessageBox.information(self, "Dane", "Dane zostały wczytane")

    def showfilterforms(self, i):
        """
        Show filters for collumn nr"
        :param i:
        :return:
        """
        session = Session()
        filter_ = session.query(FilterF).filter_by(column_nr=i).one_or_none()
        if filter_ is not None and filter_.type == 'manual':
            columns = self.prapercolumns(filter_.columns)
            headersname = [self.headers[i] for i in filter_.columns]
            self.filter = FiltersForm(filter_.id, columns, headersname, self)
            self.filter.show()

        session.close()

    def show_excel_form(self):
        """
        Show excel form
        :return:
        """
        self.excel_form.set_compatives()
        self.excel_form.show()

    def show_connect_raports(self):
        """
        Show  connect rapot
        :return:
        """
        self.connect_form.set_raports()
        self.connect_form.show()

    def show_duplicate_form(self):
        """
        show duplicate form
        """
        self.for_find_duplicate.set_raports()
        self.for_find_duplicate.show()

    def show_filter_manager(self):
        """
        show filter manager form
        """
        self.filters_manager.show()

    def prapercolumns(self, columns):
        """
        get unic data from sending columns
        :param args:
        :return:
        """
        mainlist = []
        for col in columns:
            collist = []
            for row in range(self.sti.rowCount()):
                if self.sti.item(row, col) is not None:
                    collist.append(self.sti.item(row, col).text())
            mainlist.append(collist)

        return list(set(zip(*mainlist)))

    def replace_column(self, col_nr, assignded_column):
        """
        replace column with new data
        :param col_nr:
        :param assignded_column:
        :return:
        """
        self.sti.takeColumn(col_nr)
        self.sti.insertColumn(col_nr, assignded_column)
        self.sti.setHorizontalHeaderLabels(self.headers)
        self.set_color_on_header()

    """
    
    Filters
    
    """

    def assign_value_for_filter(self, filter_id, show=True):
        """
        preper list with value from main filter, send it to make_filter_list.
        Replace column for filter_id with column with assigned data
        :param filter_id:
        :return:
        """
        session = Session()
        filter_ = session.query(FilterF).get(filter_id)
        rows = []
        for row in range(self.sti.rowCount()):
            row_value = [
                self.sti.item(row, col).text() for col in filter_.columns
            ]
            rows.append(row_value)

        read_rows = self.make_filter_list(filter_id, rows)
        col_nr = filter_.column_nr
        self.sti.takeColumn(col_nr)
        self.sti.insertColumn(col_nr, read_rows)
        self.sti.setHorizontalHeaderLabels(self.headers)
        session.close()
        self.set_color_on_header()

        if show:
            QMessageBox.information(self, "Informacja", "Operacja zakończona.")

    @staticmethod
    def make_filter_list(filter_id, rows):
        """
        make list with assigned value
        :param filter_id:
        :param rows:
        :return:
        """
        session = Session()
        filter_ = session.query(FilterF).get(filter_id)

        ready_valus = []
        for row in rows:
            flag = False
            row = [i.strip().lower() for i in row]
            for category in filter_.categorys:
                items = [[b.strip().lower() for b in a]
                         for a in category.items]
                if row in items:
                    #make QStandardItem to make column in sti model
                    item = QStandardItem(str(category.name))
                    ready_valus.append(item)
                    flag = True
            if flag is False:
                item = QStandardItem('')
                ready_valus.append(item)

        session.close()
        return ready_valus

    """
    filters: words, cut
    """

    def run_filters(self):
        """
        make filters
        :return:
        """
        session = Session()
        # filters_ = session.query(FilterF).filter_by(type='words').all()
        filters_ = session.query(FilterF).all()
        for fil in filters_:

            if fil.type == 'words':
                rows = self.get_data_from_columns(fil.columns)
                assignded_column = self.make_words_list(fil.id, rows)
                self.replace_column(fil.column_nr, assignded_column)

            elif fil.type == 'cut':
                if fil.name == 'model':
                    rows = self.get_data_from_columns(fil.columns)
                    assignded_column = self.filter_cut_model(rows)
                    self.replace_column(fil.column_nr, assignded_column)

                elif fil.name == 'subbrand_brand_model':
                    rows = self.get_data_from_columns(fil.columns)
                    assignded_column = self.join_columns(rows)
                    self.replace_column(fil.column_nr, assignded_column)

        session.close()
        QMessageBox.information(self, "Informacja", "Operacja zakończona.")

    def get_data_from_columns(self, columns_nr):
        """
        get data for sending columns
        :param columns_nr:
        :return: return list of value from table
        """
        rows = []
        for row in range(self.sti.rowCount()):
            row_value = []
            for col in columns_nr:
                if self.sti.item(row, col) is not None:
                    row_value.append(self.sti.item(row, col).text())
                else:
                    row_value.append('')
            # row_value = [self.sti.item(row, col).text() for col in columns_nr]
            rows.append(row_value)
        return rows

    @staticmethod
    def make_words_list(filter_id, rows):
        """
        make words list for filters,
        if find word in list assigned name of category
        :param filter_id:
        :param rows:
        :return:
        """

        session = Session()
        filter_ = session.query(FilterF).get(filter_id)

        ready_valus = []
        for row in rows:
            flag = False
            row = [i.lower() for i in row]
            row = ' '.join(row)
            for category in filter_.categorys:
                words = [b.lower() for b in category.words]
                for word in words:
                    if word in row:
                        item = QStandardItem(str(category.name))
                        ready_valus.append(item)
                        flag = True
                        break
            if flag is False:
                item = QStandardItem('')
                ready_valus.append(item)

        session.close()
        return ready_valus

    def filter_cut_model(self, rows):
        """
        cut ferst word from string
        :param rows:
        :return:
        """
        ready_values = []
        for row in rows:
            item = QStandardItem((row[1].replace(row[0], '')).strip())
            ready_values.append(item)

        return ready_values

    def join_columns(self, rows):
        """
        join column in list rows
        """
        temp = [QStandardItem(' '.join(x)) for x in rows]
        return temp

    def set_color_on_header(self):
        """
        changes the color of the header
        :return:
        """

        session = Session()
        filtersf = session.query(FilterF).all()

        for filterf in filtersf:
            if filterf.type == 'manual':
                self.table.model().setHeaderData(filterf.column_nr,
                                                 Qt.Horizontal,
                                                 QBrush(QColor(121, 166, 210)),
                                                 Qt.BackgroundRole)
                self.table.model().setHeaderData(
                    filterf.column_nr, Qt.Horizontal,
                    self.headers[filterf.column_nr], Qt.DisplayRole)
            if filterf.type in ('words', 'cut'):
                self.table.model().setHeaderData(filterf.column_nr,
                                                 Qt.Horizontal,
                                                 QBrush(QColor(212, 214, 219)),
                                                 Qt.BackgroundRole)
                self.table.model().setHeaderData(
                    filterf.column_nr, Qt.Horizontal,
                    self.headers[filterf.column_nr], Qt.DisplayRole)
        session.close()
class StatsManager:
    GROUP_BY = ['filename', 'lineno', 'traceback']
    # index in the combo box
    GROUP_BY_FILENAME = 0
    GROUP_BY_LINENO = 1
    GROUP_BY_TRACEBACK = 2

    def __init__(self, window, app):
        self.app = app
        self.window = window
        self.snapshots = window.snapshots
        self.source = window.source
        self.filename_parts = 3
        self._auto_refresh = False

        self.filters = []
        self.history = History(self)

        self.model = StatsModel(self)
        self.view = QTableView(window)
        self.view.setModel(self.model)
        self.cumulative_checkbox = QCheckBox(window.tr("Cumulative sizes"),
                                             window)
        self.group_by = QtGui.QComboBox(window)
        self.group_by.addItems([
            window.tr("Filename"),
            window.tr("Line number"),
            window.tr("Traceback"),
        ])

        self.filters_label = QLabel(window)
        self.summary = QLabel(window)
        self.view.verticalHeader().hide()
        self.view.resizeColumnsToContents()
        self.view.setSortingEnabled(True)

        window.connect(self.group_by,
                       QtCore.SIGNAL("currentIndexChanged(int)"),
                       self.group_by_changed)
        window.connect(self.view,
                       QtCore.SIGNAL("doubleClicked(const QModelIndex&)"),
                       self.double_clicked)
        window.connect(self.cumulative_checkbox,
                       QtCore.SIGNAL("stateChanged(int)"),
                       self.change_cumulative)
        window.connect(self.snapshots.load_button,
                       QtCore.SIGNAL("clicked(bool)"), self.load_snapshots)
        window.connect(
            self.view.selectionModel(),
            QtCore.SIGNAL(
                "selectionChanged(const QItemSelection&, const QItemSelection&)"
            ), self.selection_changed)

        self.clear()
        self._auto_refresh = True

    def clear(self):
        del self.filters[:]
        self.cumulative_checkbox.setCheckState(Qt.Unchecked)
        self.group_by.setCurrentIndex(self.GROUP_BY_FILENAME)
        self.history.clear()
        self.append_history()
        self.refresh()

    def load_snapshots(self, checked):
        self.source.clear()
        self.clear()

    def append_history(self):
        group_by = self.group_by.currentIndex()
        filters = self.filters[:]
        cumulative = self.cumulative_checkbox.checkState()
        state = HistoryState(group_by, filters, cumulative)
        self.history.append(state)

    def restore_state(self, state):
        self.filters = state.filters[:]
        self._auto_refresh = False
        self.cumulative_checkbox.setCheckState(state.cumulative)
        self.group_by.setCurrentIndex(state.group_by)
        self._auto_refresh = True
        self.refresh()

    def format_filename(self, filename):
        parts = filename.split(os.path.sep)
        if len(parts) > self.filename_parts:
            parts = [MORE_TEXT] + parts[-self.filename_parts:]
        return os.path.join(*parts)

    def get_group_by(self):
        index = self.group_by.currentIndex()
        return self.GROUP_BY[index]

    def get_cumulative(self):
        return (self.cumulative_checkbox.checkState() == Qt.Checked)

    def refresh(self):
        group_by = self.get_group_by()
        if group_by != 'traceback':
            cumulative = self.get_cumulative()
        else:
            # FIXME: add visual feedback
            cumulative = False
        snapshot1, snapshot2 = self.snapshots.load_snapshots(self.filters)

        self.view.clearSelection()
        group_by = self.get_group_by()
        self.model.set_stats(snapshot1, snapshot2, group_by, cumulative)

        self.view.resizeColumnsToContents()
        self.view.sortByColumn(self.model.get_default_sort_column(),
                               Qt.DescendingOrder)

        if self.filters:
            filters = []
            for filter in self.filters:
                text = self.format_filename(filter.filename_pattern)
                if filter.lineno:
                    text = "%s:%s" % (text, filter.lineno)
                if filter.all_frames:
                    text += self.window.tr(" (any frame)")
                if filter.inclusive:
                    text = fmt(self.window.tr("include %s"), text)
                else:
                    text = fmt(self.window.tr("exclude %s"), text)
                filters.append(text)
            filters_text = ", ".join(filters)
        else:
            filters_text = self.window.tr("(none)")
        filters_text = fmt(self.window.tr("Filters: %s"), filters_text)
        self.filters_label.setText(filters_text)

        total = self.model.total_text
        lines = len(self.model.stats)
        if group_by == 'filename':
            lines = fmt(self.window.tr("Files: %s"), lines)
        elif group_by == 'lineno':
            lines = fmt(self.window.tr("Lines: %s"), lines)
        else:
            lines = fmt(self.window.tr("Tracebacks: %s"), lines)
        total = fmt(self.window.tr("%s - Total: %s"), lines, total)
        self.summary.setText(total)

    def selection_changed(self, selected, unselected):
        indexes = selected.indexes()
        if not indexes:
            return
        stat = self.model.get_stat(indexes[0])
        if stat is None:
            return
        self.source.set_traceback(stat.traceback,
                                  self.get_group_by() != 'filename')
        self.source.show_frame(stat.traceback[0])

    def double_clicked(self, index):
        stat = self.model.get_stat(index)
        if stat is None:
            return
        group_by = self.get_group_by()
        if group_by == 'filename':
            all_frames = self.get_cumulative()
            self.filters.append(
                tracemalloc.Filter(True,
                                   stat.traceback[0].filename,
                                   all_frames=all_frames))
            self._auto_refresh = False
            self.group_by.setCurrentIndex(self.GROUP_BY_LINENO)
            self.append_history()
            self._auto_refresh = True
            self.refresh()
        elif group_by == 'lineno':
            # Replace filter by filename with filter by line
            new_filter = tracemalloc.Filter(True,
                                            stat.traceback[0].filename,
                                            stat.traceback[0].lineno,
                                            all_frames=False)
            if self.filters:
                old_filter = self.filters[-1]
                replace = (old_filter.inclusive == new_filter.inclusive
                           and old_filter.filename_pattern
                           == new_filter.filename_pattern
                           and old_filter.lineno == None)
            else:
                replace = False
            if replace:
                self.filters[-1] = new_filter
            else:
                self.filters.append(new_filter)
            self._auto_refresh = False
            self.group_by.setCurrentIndex(self.GROUP_BY_TRACEBACK)
            self.append_history()
            self._auto_refresh = True
            self.refresh()

    def group_by_changed(self, index):
        if not self._auto_refresh:
            return
        self.append_history()
        self.refresh()

    def change_cumulative(self, state):
        if not self._auto_refresh:
            return
        self.append_history()
        self.refresh()
Exemple #9
0
class ManageSettings(QMainWindow):
    def __init__(self, parent):
        super(ManageSettings, self).__init__(parent)
        self.setWindowTitle("Paraméterek kezelése")
        widget = QWidget()
        main_layout = QHBoxLayout()
        widget.setLayout(main_layout)

        self.setCentralWidget(widget)
        self.table_view = QTableView()
        main_layout.addWidget(self.table_view)

        self.model = QSqlTableModel(db=db)
        self.model.setTable("settings")
        self.model.select()
        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.model.setHeaderData(1, Qt.Horizontal, "Paraméter")
        self.model.setHeaderData(2, Qt.Horizontal, "Érték")

        self.table_view.setModel(self.model)
        self.table_view.setSortingEnabled(True)
        self.table_view.hideColumn(0)
        self.table_view.resizeColumnsToContents()

        self.model.dataChanged.connect(self.valtozott)
        gomb_layout = QVBoxLayout()
        main_layout.addLayout(gomb_layout)

        self.apply_button = QPushButton("Módosítások alkalmazása")
        self.cancel_button = QPushButton("Módosítások elvetése")

        gomb_layout.addWidget(self.apply_button)
        gomb_layout.addWidget(self.cancel_button)

        self.space = QSpacerItem(0, 0, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        gomb_layout.addItem(self.space)

        self.setFixedSize(400, 600)
        tb = self.addToolBar("File")

        exit = QAction(QIcon("images/door--arrow.png"), "Kilépés", self)
        tb.addAction(exit)

        tb.actionTriggered[QAction].connect(self.toolbarpressed)

        self.apply_button.clicked.connect(self.valtozas_mentese)
        self.cancel_button.clicked.connect(self.valtozas_elvetese)

    def toolbarpressed(self, a):
        if a.text() == "Kilépés":
            self.close()

    def valtozott(self):
        self.apply_button.setStyleSheet('background-color: green;')
        self.cancel_button.setStyleSheet('background-color: red;')

    def valtozas_mentese(self):
        self.model.submitAll()
        self.apply_button.setStyleSheet('')
        self.cancel_button.setStyleSheet('')

    def valtozas_elvetese(self):
        self.model.revertAll()
        self.apply_button.setStyleSheet('')
        self.cancel_button.setStyleSheet('')
Exemple #10
0
class DictWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__()

        self.view = QTableView()
        self.model = DictModel()
        self.proxy_model = QSortFilterProxyModel()
        self.search_bar = QLineEdit()
        self._show_loading = False

        self.proxy_model.setSourceModel(self.model)

        self.view.setModel(self.proxy_model)
        self.view.setAlternatingRowColors(True)
        self.view.horizontalHeader().setStretchLastSection(True)
        self.view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.view.setSortingEnabled(True)
        self.view.verticalHeader().hide()

        self.search_bar.textChanged.connect(
            self.proxy_model.setFilterRegularExpression)
        self.search_bar.setVisible(False)

        self._show_search_action = QAction("show search bar")
        self._show_search_action.setCheckable(True)
        self._show_search_action.setShortcutContext(Qt.WidgetShortcut)
        self._show_search_action.setShortcut(QKeySequence.Find)
        self._show_search_action.triggered.connect(self._on_show_search)

        self._close_search_action = QAction()
        self._close_search_action.setShortcut(QKeySequence(Qt.Key_Escape))
        self._close_search_action.setShortcutContext(Qt.WidgetShortcut)
        self._close_search_action.triggered.connect(self._on_close_search)

        self.view.addAction(self._show_search_action)
        self.search_bar.addAction(self._close_search_action)

        _layout = QVBoxLayout()
        _layout.addWidget(self.view)
        _layout.addWidget(self.search_bar)
        _layout.setContentsMargins(0, 0, 0, 0)

        self.setLayout(_layout)
        print("init")

    def set_dict(self, data: dict):

        self.model.set_dict(data)

    def _on_show_search(self):
        self.search_bar.setVisible(True)
        self.search_bar.setFocus(Qt.ShortcutFocusReason)

    def _on_close_search(self):
        self.search_bar.hide()
        self.search_bar.clear()
        self.view.setFocus(Qt.ShortcutFocusReason)

    def set_header_visible(self, visible=True):
        self.view.horizontalHeader().setVisible(visible)

    def clear(self):
        self.model.clear()

    def paintEvent(self, event: QPaintEvent):

        if self._show_loading:
            painter = QPainter(self)
            painter.drawText(self.rect(), Qt.AlignCenter,
                             self.tr("Loading ..."))
        else:
            super().paintEvent(event)

    def set_loading(self, show=True):
        self._show_loading = True
        self.view.setVisible(not show)
        self.update()
Exemple #11
0
class BaseList(BasePage):
    """
    Generic table viewer widget. Subclasses should set the model_class
    attribute to a subclass of BaseListModel.

    If a subclass defines an open_item method that accepts one argument, when
    an item in the table is clicked on, that method will be called with the ID
    of the clicked item. Alternatively, if the details_class attribute is set
    to a tab page widget class, that will be used to open the item.

    """
    def __init__(self, *args, **kwargs):
        self._model = self.model_class()
        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self._model)
        layout = QVBoxLayout()
        self.table_view = QTableView()
        self.table_view.setModel(self.proxy_model)
        self.table_view.setSortingEnabled(True)
        self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table_view.doubleClicked.connect(self.table_double_clicked)
        layout.addWidget(self.table_view)
        self.extra_data = dict()
        super().__init__(*args, **kwargs)
        self.setLayout(layout)

    def table_double_clicked(self, index):
        """
        Called when the QTableView is double clicked. If the open_item() method
        is defined, call it and pass the ID of the item that was clicked on.

        Args:
            The QModelIndex passed by the table_view.doubleClicked signal.

        """
        if hasattr(self, "open_item"):
            # TODO: Figure out a better way to get the ID besides assuming that
            # it's in the first (or any) column
            id_index = index.siblingAtColumn(0)
            try:
                data_id = int(index.model().itemData(id_index)[0])
                self.open_item(data_id)
            except ValueError:
                pass

    def open_item(self, data_id):
        """
        If the details_class attribute is defined, use it to open a Details tab
        for the specified item.

        """
        if hasattr(self, "details_class"):
            self.details_class.create_or_focus(self.gui, data_id)

    @property
    def data(self):
        """The page's current data set (a 2-dimensional sequence)."""
        return self._model.dataset

    @data.setter
    def data(self, data):
        self._model.populate(data)
        self.proxy_model.invalidate()

    @property
    def tab_name(self):
        """
        The name of the tab page. Determined by the tab_name_fmt attribute and
        the widget's current supplemental data set.

        """
        return self.tab_name_fmt.format(**self.extra_data)
class AddressWidget(QDialog):

    selectionChanged = Signal(QItemSelection)

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

        self.tableModel = TableModel()
        self.tableView = QTableView()
        self.setupTable()

        statusLabel = QLabel("Tabular data view demo")

        layout = QVBoxLayout()
        layout.addWidget(self.tableView)
        layout.addWidget(statusLabel)
        self.setLayout(layout)
        self.setWindowTitle("Address Book")
        self.resize(800, 500)

        # add test data
        self.populateTestData()

    def setupTable(self):
        proxyModel = QSortFilterProxyModel(self)
        proxyModel.setSourceModel(self.tableModel)
        proxyModel.setDynamicSortFilter(True)

        self.tableView.setModel(proxyModel)
        self.tableView.setSortingEnabled(True)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.horizontalHeader().setStretchLastSection(True)
        self.tableView.verticalHeader().hide()
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)

        proxyModel.setFilterKeyColumn(0)  # Filter on the "name" column
        proxyModel.sort(0, Qt.AscendingOrder)
        viewselectionmodel = self.tableView.selectionModel()
        self.tableView.selectionModel().selectionChanged.connect(
            self.selectionChanged)

    def populateTestData(self):
        addresses = [{
            "name": "John Doe",
            "address": "Alameda"
        }, {
            "name": "Alan Turing",
            "address": "San Deigo"
        }, {
            "name": "Bjarne Stroutsup",
            "address": "Columbia"
        }, {
            "name": "Herb Sutter",
            "address": "Seattle"
        }, {
            "name": "Micheal Konin",
            "address": "Colorado"
        }]

        for i in range(len(addresses)):
            self.tableModel.insertRows(0)
            ix = self.tableModel.index(0, 0, QModelIndex())
            self.tableModel.setData(ix, addresses[i]["name"], Qt.EditRole)

            ix = self.tableModel.index(0, 1, QModelIndex())
            self.tableModel.setData(ix, addresses[i]["address"], Qt.EditRole)

            self.tableView.resizeRowToContents(ix.row())
Exemple #13
0
class ManageMembers(QMainWindow):
    def __init__(self, parent):
        super(ManageMembers, self).__init__(parent)
        self.setWindowTitle("Tagok kezelése")
        widget = QWidget()
        main_layout = QHBoxLayout()
        widget.setLayout(main_layout)

        self.setCentralWidget(widget)
        self.table_view = QTableView()
        main_layout.addWidget(self.table_view)

        self.model = QSqlTableModel(db=db)
        self.model.setTable("members")
        self.model.select()
        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.model.setHeaderData(1, Qt.Horizontal, "Vezetéknév")
        self.model.setHeaderData(2, Qt.Horizontal, "Utónév")
        self.model.setHeaderData(3, Qt.Horizontal, "Született")
        self.model.setHeaderData(4, Qt.Horizontal, "Ir.szám")
        self.model.setHeaderData(5, Qt.Horizontal, "Helység")
        self.model.setHeaderData(6, Qt.Horizontal, "Cím")
        self.model.setHeaderData(7, Qt.Horizontal, "Telefon")
        self.model.setHeaderData(8, Qt.Horizontal, "E-mail")
        self.model.setHeaderData(9, Qt.Horizontal, "Tagság kezdete")
        self.model.setHeaderData(10, Qt.Horizontal, "Aktív")
        # self.model.setFilter('vezeteknev Like "Czi%"')

        self.table_view.setModel(self.model)
        self.table_view.hideColumn(0)
        self.table_view.resizeColumnsToContents()
        # Ha ez engedélyezve, akkor a model-nél beállított sort nem működik, ez felülírja
        # Enélkül működik a model-es beállítás
        self.table_view.setSortingEnabled(True)
        # Ha engedélyezve van a fejléc szerinti rendezés, akkor UTÁNA meg lehet adni az alap sorrendet
        self.table_view.sortByColumn(1, Qt.AscendingOrder)

        self.model.dataChanged.connect(self.valtozott)
        gomb_layout = QVBoxLayout()
        main_layout.addLayout(gomb_layout)

        self.delete_button = QPushButton("&Tag törlése")
        self.add_button = QPushButton("&Új tag")
        self.apply_button = QPushButton("Módosítások alkalmazása")
        self.cancel_button = QPushButton("Módosítások elvetése")

        gomb_layout.addWidget(self.delete_button)
        gomb_layout.addWidget(self.add_button)
        gomb_layout.addWidget(self.apply_button)
        gomb_layout.addWidget(self.cancel_button)

        self.space = QSpacerItem(0, 0, QSizePolicy.Minimum,
                                 QSizePolicy.Expanding)
        gomb_layout.addItem(self.space)

        self.setFixedSize(1000, 800)
        tb = self.addToolBar("File")

        exit = QAction(QIcon("images/door--arrow.png"), "Kilépés", self)
        tb.addAction(exit)

        excel = QAction(QIcon("images/excel.png"), "Excel", self)
        tb.addAction(excel)

        tb.actionTriggered[QAction].connect(self.toolbarpressed)

        self.delete_button.clicked.connect(self.tag_torles)
        self.add_button.clicked.connect(self.tag_hozzadas)
        self.apply_button.clicked.connect(self.valtozas_mentese)
        self.cancel_button.clicked.connect(self.valtozas_elvetese)

    def tag_hozzadas(self):
        self.form_window = UjtagFormDialog()
        self.form_window.setWindowTitle("Új tag felvétele")
        if self.form_window.exec_():
            record = self.model.record()
            record.remove(record.indexOf('id'))

            for i in range(len(self.form_window.mezo_ertekek)):
                record.setValue(i, self.form_window.mezo_ertekek[i].text())
                # print(i, record.value(i))
            if self.model.insertRecord(-1, record):
                self.model.submitAll()
                self.apply_button.setStyleSheet('')
                self.cancel_button.setStyleSheet('')
            else:
                db.rollback()

    def tag_torles(self):
        if len(self.table_view.selectedIndexes()) > 0:
            self.model.removeRow(self.table_view.selectedIndexes()[0].row())
            self.model.submitAll()
        else:
            reply = QMessageBox.question(None, 'Hiba!',
                                         'Törlés előtt jelöljön ki egy sort!',
                                         QMessageBox.Ok)

    def toolbarpressed(self, a):
        if a.text() == "Kilépés":
            self.close()
        if a.text() == "Excel":
            data = []
            for i in range(self.model.rowCount()):
                sor = []
                for j in range(self.model.columnCount()):
                    if isinstance(self.model.record(i).value(j), QDate):
                        sor.append(
                            self.model.record(i).value(j).toString(
                                "yyyy-MM-dd"))
                    else:
                        sor.append(self.model.record(i).value(j))
                data.append(sor)
            p.save_as(array=data, dest_file_name="tagok.xlsx")

    def valtozott(self):
        self.apply_button.setStyleSheet('background-color: green;')
        self.cancel_button.setStyleSheet('background-color: red;')

    def valtozas_mentese(self):
        self.model.submitAll()
        self.apply_button.setStyleSheet('')
        self.cancel_button.setStyleSheet('')

    def valtozas_elvetese(self):
        self.model.revertAll()
        self.apply_button.setStyleSheet('')
        self.cancel_button.setStyleSheet('')
Exemple #14
0
class RemoverDialog(QDialog):
    def __init__(self, parent=None):
        super(RemoverDialog, self).__init__(parent)

        self.setupUi()

    def setupUi(self):
        self.menuBar = QMenuBar()
        self.menuBar.show()

        self.pathInputBox = QLineEdit(self)
        self.pathInputBox.setEnabled(False)
        self.pathInputBox.setToolTip(
            'Input a path or drag a directory here...')

        self.openPathButton = QPushButton('Open...', self)
        self.openPathButton.clicked.connect(self.openPath)

        inputLayout = QHBoxLayout()
        inputLayout.addWidget(QLabel('Path:', self))
        inputLayout.addWidget(self.pathInputBox)
        inputLayout.addWidget(self.openPathButton)

        self.filterFolderCheckBox = QCheckBox('Folders', self)
        self.filterFolderCheckBox.setChecked(True)
        self.filterFolderCheckBox.toggled.connect(self.filter)
        self.filterFileCheckBox = QCheckBox('Files', self)
        self.filterFileCheckBox.setChecked(True)
        self.filterFileCheckBox.toggled.connect(self.filter)
        self.filterSuffixCheckBox = QCheckBox('Suffixes', self)
        self.filterSuffixCheckBox.setChecked(True)
        self.filterSuffixCheckBox.toggled.connect(self.filter)

        filterLayout = QHBoxLayout()
        filterLayout.addWidget(self.filterFolderCheckBox)
        filterLayout.addWidget(self.filterFileCheckBox)
        filterLayout.addWidget(self.filterSuffixCheckBox)
        filterLayout.addStretch()

        self.trashButton = QPushButton('Trash', self)
        self.trashButton.clicked.connect(self.trash)
        self.deleteButton = QPushButton('Delete', self)
        self.deleteButton.clicked.connect(self.delete)

        confirmLayout = QHBoxLayout()
        confirmLayout.addStretch()
        confirmLayout.addWidget(self.trashButton)
        confirmLayout.addWidget(self.deleteButton)

        layout = QVBoxLayout()
        layout.addLayout(inputLayout)
        layout.addLayout(filterLayout)
        layout.addWidget(self.createResultView())
        layout.addLayout(confirmLayout)

        self.setAcceptDrops(True)
        self.setLayout(layout)
        self.setMinimumWidth(600)
        self.setWindowTitle('Remover')
        self.setWindowIcon(QApplication.style().standardIcon(
            QStyle.SP_DirIcon))

    def createResultView(self):
        self.resultModel = ResultModel(self)
        self.resultView = QTableView(self)
        self.resultView.setSortingEnabled(True)
        self.resultView.setShowGrid(False)
        self.resultView.setAlternatingRowColors(True)
        self.resultView.verticalHeader().hide()
        self.resultView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.resultView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.sortFilterModel = SortFilterResultModel(self.resultModel, self)
        self.resultView.setModel(self.sortFilterModel)
        return self.resultView

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls() and len(event.mimeData().urls()) == 1:
            event.acceptProposedAction()

    def dropEvent(self, event):
        if event.mimeData().hasUrls() and len(event.mimeData().urls()) == 1:
            self.pathInputBox.setText(event.mimeData().urls()[0].toLocalFile())
            self.reloadPath(self.pathInputBox.text())

    def openPath(self):
        path = QFileDialog.getExistingDirectory(
            parent=self,
            caption='Open',
            options=QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
        if path:
            self.pathInputBox.setText(path)
            self.reloadPath(path)

    def filter(self):
        filters = []
        if self.filterFolderCheckBox.isChecked():
            filters.append('folder')
        if self.filterFileCheckBox.isChecked():
            filters.append('file')
        if self.filterSuffixCheckBox.isChecked():
            filters.append('suffix')
        self.sortFilterModel.setFilterRegularExpression('|'.join(filters))
        self.sortFilterModel.filterRegularExpression()
        self.resultView.resizeRowsToContents()

    def trash(self):
        folders, files = self.collectSelectedFolderFiles()

        try:
            for file in files:
                send2trash(file)
            for folder in folders:
                if QFile(folder).exists():
                    send2trash(folder)
        except:
            QMessageBox.warning(self, 'Failed',
                                'Failed to trash selected files/folders')
            return

        self.reloadPath(self.pathInputBox.text())

    def delete(self):
        folders, files = self.collectSelectedFolderFiles()

        try:
            for file in files:
                os.remove(file)
            for folder in folders:
                shutil.rmtree(folder)
        except:
            QMessageBox.warning(self, 'Failed',
                                'Failed to delete selected files/folders')
            return

        self.reloadPath(self.pathInputBox.text())

    def collectSelectedFolderFiles(self):
        folders, files, suffixes = [], [], []
        for index in self.resultView.selectedIndexes():
            if index.column() != 0:
                # 忽略第二列的selection
                continue
            item = self.sortFilterModel.data(index, Qt.UserRole)
            if 'folder' == item.type:
                folders.append(item.name)
            elif 'file' == item.type:
                files.append(item.name)
            elif 'suffix' == item.type:
                suffixes.append(item.name[2:])

        # 将后缀符合选中条件的文件添加到files中
        path = self.pathInputBox.text()
        iterator = QDirIterator(path,
                                filter=QDir.Files | QDir.Dirs | QDir.Hidden
                                | QDir.NoDotAndDotDot,
                                flags=QDirIterator.Subdirectories)
        folderPaths, filePaths = set(), set()
        while iterator.hasNext():
            file = iterator.next()
            if '.' == file[-1] or '..' == file[-2]:
                continue
            fileInfo = QFileInfo(file)
            if fileInfo.isDir():
                if fileInfo.fileName() in folders:
                    folderPaths.add(fileInfo.absoluteFilePath())
            if fileInfo.isFile():
                if fileInfo.fileName() in files:
                    filePaths.add(fileInfo.absoluteFilePath())
                if fileInfo.suffix() in suffixes:
                    filePaths.add(fileInfo.absoluteFilePath())
        return sorted(folderPaths), filePaths

    def reloadPath(self, path):
        self.resultModel.reload(path)
        self.resultView.horizontalHeader().setSectionResizeMode(
            0, QHeaderView.Stretch)
        self.resultView.horizontalHeader().setSectionResizeMode(
            1, QHeaderView.ResizeToContents)
        self.filter()
        self.resultView.sortByColumn(1, Qt.DescendingOrder)
Exemple #15
0
class SydTableWidget(QtWidgets.QWidget, Ui_SydTableWidget):
    table_reloaded = Signal()

    def __init__(self, filename, table_name, parent=None):
        super().__init__(parent)
        self.setupUi(self)

        # internal members
        self._filename = filename
        self._table_name = table_name
        self._db = None
        self._data = None
        self._model = None
        self._filter_proxy_model = None
        self._header = None
        self._toggle_width_menus = []
        self.button_reload.clicked.connect(self.slot_on_reload)
        self.button_view.hide()
        self.button_view.clicked.connect(self.slot_on_view)

        # initial UI
        # self.setAutoFillBackground(True)
        self.scrollArea.setVisible(False)
        self.button_view.setEnabled(False)

        # pop-up window
        self.w = None

    def table_name(self):
        return self._table_name

    def model(self):
        return self._model

    def set_data(self, data):
        self._data = data
        db = self._db
        table_name = self._table_name

        # define and set the model
        self._model = SydTableModel(self._filename, db, table_name, data)

        # remove previous widget
        self.table_view.setParent(None)
        del self.table_view

        # create new one
        self.table_view = QTableView(self)
        self.verticalLayout.addWidget(self.table_view)

        # define own header (with column filter)
        self._header = SydColumnFilterHeader(self.table_view)
        ncol = self._model.columnCount(0)

        # define and set the filter/sort proxy
        self._filter_proxy_model = SydTableSortFilterProxyModel(self._header)
        self._filter_proxy_model.setSourceModel(self._model)
        self._filter_proxy_model.setSortLocaleAware(True)
        self._filter_proxy_model.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.table_view.setModel(self._filter_proxy_model)

        # selection model for the button_view
        self.table_view.setSelectionBehavior(QTableView.SelectRows)
        selection = self.table_view.selectionModel()
        selection.selectionChanged.connect(self.on_selection_change)

        # set the columns filters
        self._header.set_filter_editors(ncol, self._filter_proxy_model)

        # setup the context menu
        self._header.setContextMenuPolicy(Qt.CustomContextMenu)
        self._header.customContextMenuRequested.connect(
            self.slot_on_column_header_popup)
        self._header.filterActivated.connect(self.slot_on_col_filter_changed)

        self.table_view.setHorizontalHeader(self._header)

        # remove previous col buttons
        c = self.layout_col_buttons.takeAt(0)
        while c and c.widget():
            c.widget().setParent(None)
            del c
            c = self.layout_col_buttons.takeAt(0)

        # create new col buttons
        def create_lambda(icol):
            return lambda: self.slot_on_col_button_clicked(icol)

        self.col_buttons = []
        for i in range(0, ncol):
            s = self._model._headers[i]
            b = QPushButton(s)  # , parent=self.layout_col_buttons)
            b.clicked.connect(create_lambda(i))
            b.setFlat(True)
            b.setVisible(False)
            self.layout_col_buttons.addWidget(b)
            self.col_buttons.append(b)
        h = QSpacerItem(878, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.layout_col_buttons.addItem(h)

        # create menu col width
        for i in range(0, ncol):
            b = QAction(self)
            b.setText('Toggle adjust width')
            b.setCheckable(True)
            b.setChecked(False)
            self._toggle_width_menus.append(b)
            # special case for first column ('id')
            if i == 0:
                b.setChecked(True)
                self.slot_on_auto_width_column(i)

        # make the area invisible first
        self.scrollArea.setVisible(False)
        # self.scrollArea.setAutoFillBackground(True)
        # self.table_view.setAutoFillBackground(True)
        self.table_view.setAlternatingRowColors(True)

        # initial nb of elements
        self.slot_on_col_filter_changed()

        # double click header
        self.table_view.horizontalHeader().sectionDoubleClicked. \
            connect(self.slot_on_toggle_auto_width_column)

        # global filter
        self.edit_filter.textChanged.connect(self.slot_on_filter_changed)
        self.edit_filter.setClearButtonEnabled(True)

        # allow sorting
        self.table_view.setSortingEnabled(True)
        self._filter_proxy_model.sort(0, Qt.AscendingOrder)
        self._filter_proxy_model.invalidateFilter()
        self._header.updateGeometries()

    def slot_on_column_header_popup(self, pos):
        idx = self.table_view.horizontalHeader().logicalIndexAt(pos)
        menu = QMenu(self.table_view)
        a = QAction(self)
        name = self._model._col_names[idx]
        a.setText(f'Hide {name}')
        a.triggered.connect(lambda col_name=idx: self.slot_on_hide_column(idx))
        b = self._toggle_width_menus[idx]
        b.triggered.connect(
            lambda col_name=idx: self.slot_on_auto_width_column(idx))
        menu.addAction(a)
        menu.addAction(b)
        menu.exec_(self.table_view.mapToGlobal(pos))

    def slot_on_hide_column(self, idx):
        # hide the column
        self.table_view.setColumnHidden(idx, True)
        # show the button
        self.scrollArea.setVisible(True)
        self.col_buttons[idx].setVisible(True)
        self._header.updateGeometries()

    def slot_on_col_button_clicked(self, idx):
        # show the column
        self.table_view.setColumnHidden(idx, False)
        # hide the button
        self.col_buttons[idx].setVisible(False)
        for b in self.col_buttons:
            if b.isVisible():
                return
        self.scrollArea.setVisible(False)
        self._header.updateGeometries()

    def slot_on_toggle_auto_width_column(self, idx):
        b = self._toggle_width_menus[idx]
        b.setChecked(not b.isChecked())
        self.slot_on_auto_width_column(idx)

    def slot_on_auto_width_column(self, idx):
        b = self._toggle_width_menus[idx]
        if b.isChecked():
            self._header.setSectionResizeMode(
                idx, QtWidgets.QHeaderView.ResizeToContents)
        else:
            self._header.setSectionResizeMode(
                idx, QtWidgets.QHeaderView.Interactive)
        self._header.updateGeometries()

    def slot_on_col_filter_changed(self):
        n = self._filter_proxy_model.rowCount()
        t = self._model.rowCount(None)
        self.label_tablename.setText(f'{self._table_name}')
        self.label_status.setText(f'{n}/{t}')
        if self._table_name == 'Image' or self._table_name == 'DicomSeries':
            self.button_view.show()
        elif self._table_name == "DicomSeries_default" or self._table_name == "Image_default":
            self.button_view.show()

    def slot_on_filter_changed(self):
        n = self._filter_proxy_model.rowCount()
        t = self._model.rowCount(None)
        self.label_status.setText(f'{n}/{t}')
        f = self.edit_filter
        self._filter_proxy_model.set_global_filter(f.text())

    def slot_on_reload(self):
        # later -> keep filters if the columns are identical.
        # not clear why I need to reopen the db here
        # (not needed for tables, needed for view)
        self._db = syd.open_db(self._filename)
        t = self._db.load_table(self._table_name)
        elements = syd.find_all(t)
        self.set_data(elements)
        # indicate that the table has been reloaded
        self.table_reloaded.emit()
        n = self._filter_proxy_model.rowCount()
        t = self._model.rowCount(None)
        self.label_status.setText(f'{n}/{t}')
        self.button_view.setText("view in vv")
        self.button_view.setEnabled(False)

    def slot_on_view(self):
        data = []
        path = []
        rows = set(index.row() for index in self.table_view.selectedIndexes())
        for row in rows:
            data.append(self._data[row])
        self.w = SydCTWindow(data, self._filename, self._table_name)
        self.w.button_ct_on.setEnabled(False)
        db = syd.open_db(self._filename)
        for d in data:
            e = self.w.get_ct_path(db, d)
            if e is not None and len(rows) == 1 and d['modality'] != 'CT':
                self.w.button_ct_on.setEnabled(True)
                self.w.show()
            else:
                if self._table_name == 'DicomSeries' or self._table_name == 'DicomSeries_default':
                    db = syd.open_db(self._filename)
                    dicom_file = syd.find_one(db['DicomFile'],
                                              dicom_series_id=d['id'])
                    file = syd.find_one(db['File'], id=dicom_file['file_id'])
                    tmp = db.absolute_data_folder + '/' + file[
                        'folder'] + '/' + file['filename']
                    path.append(tmp)
                elif self._table_name == 'Image' or self._table_name == 'Image_default':
                    db = syd.open_db(self._filename)
                    file = syd.find_one(db['File'], id=d['file_mhd_id'])
                    path.append(db.absolute_data_folder + '/' +
                                file['folder'] + '/' + file['filename'])
                else:
                    print('La table séléctionnée ne correspond pas')
        if path != []:
            path = ' '.join(path)
            cmd = f'vv {path}'
            os.system(cmd)
        else:
            print('Path to image has no corresponding file')

    def on_selection_change(self):
        rows = set(index.row() for index in self.table_view.selectedIndexes())
        if len(rows) == 0:
            self.button_view.setEnabled(False)
            self.button_view.setText("view in vv")
        else:
            t = self._model.rowCount(None)
            self.button_view.setText(f"view in vv {len(rows)}/{t}")
            self.button_view.setEnabled(True)