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")
class ConfigureUsersDialog(QDialog):
    def __init__(self, users):
        super().__init__()
        self.setWindowTitle("Configure Users")
        self.model = TableModel(users)

        self.layout = QVBoxLayout()
        self.table_layout = QHBoxLayout()
        self.users_table = QTableView()
        self.users_table.setModel(self.model)
        self.users_table.horizontalHeader().setStretchLastSection(True)
        self.table_layout.addWidget(self.users_table)

        self.table_buttons_layout = QVBoxLayout()
        self.add_user_button = QPushButton()
        self.add_user_button.setText("Add User")
        self.add_user_button.clicked.connect(self._add_user_clicked)
        self.delete_user_button = QPushButton()
        self.delete_user_button.setText("Delete User")
        self.delete_user_button.clicked.connect(self._delete_user_clicked)
        self.table_buttons_layout.addSpacerItem(
            QSpacerItem(0, 0, vData=QSizePolicy.Expanding))
        self.table_buttons_layout.addWidget(self.add_user_button)
        self.table_buttons_layout.addWidget(self.delete_user_button)
        self.table_buttons_layout.addSpacerItem(
            QSpacerItem(0, 0, vData=QSizePolicy.Expanding))
        self.table_layout.addLayout(self.table_buttons_layout)

        self.layout.addLayout(self.table_layout)

        self.error_text = QLabel()
        self.error_text.setStyleSheet("color: red;")
        self.layout.addWidget(self.error_text)

        self.button_box = QDialogButtonBox(QDialogButtonBox.Ok
                                           | QDialogButtonBox.Cancel)
        self.button_box.accepted.connect(self._on_accepted_clicked)
        self.button_box.rejected.connect(self.reject)
        self.layout.addWidget(self.button_box)
        self.setLayout(self.layout)

        self.resize(600, 400)

    def _on_accepted_clicked(self):
        self._complete_table()
        if not self.model.are_users_unique():
            self.error_text.setText("Name must be unique for each user")
            return

        self.error_text.setText("")
        self.accept()

    def _complete_table(self):
        # The currently selected cell only updates the model when 'return' is
        # pressed or another cell is selected. If the user is updating a value
        # then clicks 'OK' without pressing 'return' then the change is lost.
        # This is a Qt thing - the workaround is to take focus from the table.
        self.button_box.button(self.button_box.Ok).setFocus()

    def _add_user_clicked(self):
        self.users_table.model().insertRow(self.model.num_rows)

    def _delete_user_clicked(self):
        rows_to_remove = set()
        for index in self.users_table.selectedIndexes():
            rows_to_remove.add(index.row())
        self.users_table.model().removeRows(list(rows_to_remove))

    def get_users(self):
        return self.model.users
class VfsNodeTableWidget(QWidget):
    def __init__(self, vfs_view, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)

        self.vnode_2click_selected = None

        # Getting the Model
        self.model = VfsNodeTableModel()

        # Creating a QTableView
        self.table_view = QTableView()
        self.table_view.clicked.connect(self.clicked)
        self.table_view.doubleClicked.connect(self.double_clicked)
        font = self.table_view.font()
        font.setPointSize(8)
        self.table_view.setFont(font)
        # self.table_view.setSortingEnabled(True)
        self.table_view.setModel(self.model)

        # QTableView Headers
        self.horizontal_header = self.table_view.horizontalHeader()
        self.vertical_header = self.table_view.verticalHeader()
        self.horizontal_header.setSectionResizeMode(QHeaderView.Interactive)
        self.vertical_header.setSectionResizeMode(QHeaderView.Interactive)
        self.horizontal_header.setStretchLastSection(True)

        # QWidget Layout
        self.main_layout = QHBoxLayout()
        size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)

        # Left layout
        size.setHorizontalStretch(1)
        self.table_view.setSizePolicy(size)
        self.main_layout.addWidget(self.table_view)

        # Set the layout to the QWidget
        self.setLayout(self.main_layout)

        self.model.vfs_view_set(vfs_view)

    def show_all_set(self, v):
        self.model.show_all = v
        self.model.update_model()

    def vfs_view_get(self):
        return self.model.vfs_view_get()

    def clicked(self, index):
        if index.isValid():
            if self.model.vfs_view is not None:
                items = list(
                    set([
                        self.model.uid_table[idx.row()]
                        for idx in self.table_view.selectedIndexes()
                    ]))
                items = [self.model.vfs_view.node_where_uid(i) for i in items]
                self.model.vfs_view.paths_set(items)

    def double_clicked(self, index):
        if index.isValid():
            if self.vnode_2click_selected is not None:
                uids = [self.model.uid_table[index.row()]]
                self.vnode_2click_selected(uids)
Exemple #4
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 #5
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 #6
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)