예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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 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)
예제 #5
0
class ObjListWindow(PBDialog):
    """Create a window managing a list (of bibtexs or of experiments)"""
    def __init__(self, parent=None, gridLayout=False):
        """Init using parent class and create common definitions

        Parameters:
            parent: the parent object
            gridLayout (boolean, default False):
                if True, use a QGridLayout, otherwise a QVBoxLayout
        """
        super(ObjListWindow, self).__init__(parent)
        self.tableWidth = None
        self.proxyModel = None
        self.gridLayout = gridLayout
        self.filterInput = None
        self.proxyModel = None
        self.tableview = None
        if gridLayout:
            self.currLayout = QGridLayout()
        else:
            self.currLayout = QVBoxLayout()
        self.setLayout(self.currLayout)

    def triggeredContextMenuEvent(self, row, col, event):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def handleItemEntered(self, index):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def cellClick(self, index):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def cellDoubleClick(self, index):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def createTable(self, *args, **kwargs):
        """Not implemented: requires a subclass"""
        raise NotImplementedError()

    def changeFilter(self, string):
        """Change the filter of the current view.

        Parameter:
            string: the filter string to be matched
        """
        self.proxyModel.setFilterRegExp(str(string))

    def addFilterInput(self, placeholderText, gridPos=(1, 0)):
        """Add a `QLineEdit` to change the filter of the list.

        Parameter:
            placeholderText: the text to be shown
                when no filter is present
            gridPos (tuple): if gridLayout is active,
                the position of the `QLineEdit` in the `QGridLayout`
        """
        self.filterInput = QLineEdit("", self)
        self.filterInput.setPlaceholderText(placeholderText)
        self.filterInput.textChanged.connect(self.changeFilter)

        if self.gridLayout:
            self.currLayout.addWidget(self.filterInput, *gridPos)
        else:
            self.currLayout.addWidget(self.filterInput)
        self.filterInput.setFocus()

    def setProxyStuff(self, sortColumn, sortOrder):
        """Prepare the proxy model to filter and sort the view.

        Parameter:
            sortColumn: the index of the column to use
                for sorting at the beginning
            sortOrder: the order for sorting
                (`Qt.AscendingOrder` or `Qt.DescendingOrder`)
        """
        self.proxyModel = QSortFilterProxyModel(self)
        self.proxyModel.setSourceModel(self.tableModel)
        self.proxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.proxyModel.setFilterKeyColumn(-1)

        self.tableview = PBTableView(self)
        self.tableview.setModel(self.proxyModel)
        self.tableview.setSortingEnabled(True)
        self.tableview.setMouseTracking(True)
        self.tableview.setSelectionBehavior(QAbstractItemView.SelectRows)
        try:
            self.tableview.sortByColumn(self.tableModel.header.index("bibkey"),
                                        Qt.AscendingOrder)
        except (IndexError, ValueError):
            pass
        self.tableview.sortByColumn(sortColumn, sortOrder)
        try:
            self.proxyModel.sort(self.tableModel.header.index("bibkey"),
                                 Qt.AscendingOrder)
        except (IndexError, ValueError):
            pass
        self.proxyModel.sort(sortColumn, sortOrder)
        self.currLayout.addWidget(self.tableview)

    def finalizeTable(self, gridPos=(1, 0)):
        """Resize the table to fit the contents,
        connect functions, add to layout

        Parameter:
            gridPos (tuple): if gridLayout is active,
            the position of the `QLineEdit` in the `QGridLayout`
        """
        self.tableview.resizeColumnsToContents()

        maxh = QDesktopWidget().availableGeometry().height()
        maxw = QDesktopWidget().availableGeometry().width()
        self.setMaximumHeight(maxh)
        self.setMaximumWidth(maxw)

        hwidth = self.tableview.horizontalHeader().length()
        swidth = self.tableview.style().pixelMetric(QStyle.PM_ScrollBarExtent)
        fwidth = self.tableview.frameWidth() * 2

        if self.tableWidth is None:
            if hwidth > maxw - (swidth + fwidth):
                self.tableWidth = maxw - (swidth + fwidth)
            else:
                self.tableWidth = hwidth + swidth + fwidth
        self.tableview.setFixedWidth(self.tableWidth)

        self.setMinimumHeight(600)

        self.tableview.resizeColumnsToContents()
        self.tableview.resizeRowsToContents()

        self.tableview.entered.connect(self.handleItemEntered)
        self.tableview.clicked.connect(self.cellClick)
        self.tableview.doubleClicked.connect(self.cellDoubleClick)

        if self.gridLayout:
            self.currLayout.addWidget(self.tableview, *gridPos)
        else:
            self.currLayout.addWidget(self.tableview)

    def recreateTable(self):
        """Delete the previous table widget and other layout items,
        then create new ones
        """
        self.cleanLayout()
        self.createTable()
예제 #6
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        hlayout = QHBoxLayout()

        layout = QVBoxLayout()

        self.filtert = QLineEdit()
        self.filtert.setPlaceholderText("Search...")
        self.table = QTableView()

        vlayout = QVBoxLayout()
        vlayout.addWidget(self.filtert)
        vlayout.addWidget(self.table)

        # Left/right pane.
        hlayout.addLayout(vlayout)
        hlayout.addLayout(layout)

        form = QFormLayout()

        self.track_id = QSpinBox()
        self.track_id.setDisabled(True)
        self.track_id.setRange(0, 2147483647)
        self.name = QLineEdit()
        self.album = QComboBox()
        self.media_type = QComboBox()
        self.genre = QComboBox()
        self.composer = QLineEdit()

        self.milliseconds = QSpinBox()
        self.milliseconds.setRange(0, 2147483647)
        self.milliseconds.setSingleStep(1)

        self.bytes = QSpinBox()
        self.bytes.setRange(0, 2147483647)
        self.bytes.setSingleStep(1)

        self.unit_price = QDoubleSpinBox()
        self.unit_price.setRange(0, 999)
        self.unit_price.setSingleStep(0.01)
        self.unit_price.setPrefix("$")

        form.addRow(QLabel("Track ID"), self.track_id)
        form.addRow(QLabel("Track name"), self.name)
        form.addRow(QLabel("Composer"), self.composer)
        form.addRow(QLabel("Milliseconds"), self.milliseconds)
        form.addRow(QLabel("Bytes"), self.bytes)
        form.addRow(QLabel("Unit Price"), self.unit_price)

        self.model = QSqlTableModel(db=db)

        self.proxy_model = QSortFilterProxyModel()
        self.proxy_model.setSourceModel(self.model)
        self.proxy_model.sort(1, Qt.AscendingOrder)
        self.proxy_model.setFilterKeyColumn(-1)  # all columns
        self.table.setModel(self.proxy_model)

        # Update search when filter changes.
        self.filtert.textChanged.connect(self.proxy_model.setFilterFixedString)

        self.mapper = QDataWidgetMapper()
        self.mapper.setModel(self.proxy_model)

        self.mapper.addMapping(self.track_id, 0)
        self.mapper.addMapping(self.name, 1)
        self.mapper.addMapping(self.composer, 5)
        self.mapper.addMapping(self.milliseconds, 6)
        self.mapper.addMapping(self.bytes, 7)
        self.mapper.addMapping(self.unit_price, 8)

        self.model.setTable("Track")
        self.model.select()

        # Change the mapper selection using the table.
        self.table.selectionModel().currentRowChanged.connect(
            self.mapper.setCurrentModelIndex)

        self.mapper.toFirst()

        # tag::controls[]
        self.setMinimumSize(QSize(800, 400))

        controls = QHBoxLayout()

        prev_rec = QPushButton("Previous")
        prev_rec.clicked.connect(self.mapper.toPrevious)

        next_rec = QPushButton("Next")
        next_rec.clicked.connect(self.mapper.toNext)

        save_rec = QPushButton("Save Changes")
        save_rec.clicked.connect(self.mapper.submit)

        controls.addWidget(prev_rec)
        controls.addWidget(next_rec)
        controls.addWidget(save_rec)

        layout.addLayout(form)
        layout.addLayout(controls)

        widget = QWidget()
        widget.setLayout(hlayout)
        self.setCentralWidget(widget)
예제 #7
0
class SmartSyncDialog(object):
    def __init__(self, parent):
        self._dialog = QDialog(parent)
        self._dialog.setWindowIcon(QIcon(':/images/icon.png'))
        self._ui = Ui_Dialog()
        self._ui.setupUi(self._dialog)

        self._ui.centralWidget.setFrameShape(QFrame.NoFrame)
        self._ui.centralWidget.setLineWidth(1)

        self._model = None
        self._proxy_model = QSortFilterProxyModel()

        self._view = self._ui.folder_list_view
        self._view.setModel(self._proxy_model)
        self._view.expanded.connect(self.on_item_expanded)

        self._offline_paths = None

        # for frameless window moving
        self._x_coord = 0
        self._y_coord = 0
        self._dialog.mousePressEvent = self.on_mouse_press_event
        self._dialog.mouseMoveEvent = self.on_mouse_move_event

        self._loader_movie = QMovie(":/images/loader.gif")
        self._ui.loader_label.setMovie(self._loader_movie)

    def on_mouse_press_event(self, ev):
        self._x_coord = ev.x()
        self._y_coord = ev.y()

    def on_mouse_move_event(self, ev):
        self._dialog.move(
            ev.globalX() - self._x_coord, ev.globalY() - self._y_coord)

    def on_item_expanded(self, index):
        if self._model:
            self._model.on_item_expanded(self._proxy_model.mapToSource(index))

    def show(self, root_path, hide_dotted=False):
        if LOGGING_ENABLED:
            logger.info(
                "Opening smart sync dialog for path '%s'...", root_path)

        self._model = TreeModel(
            root_path, hide_dotted=hide_dotted)

        self._proxy_model.setSourceModel(self._model)

        self.show_cursor_loading(show_movie=True)
        # Execute dialog
        result = self._dialog.exec_()
        if result == QDialog.Accepted:
            offline_dirs = self._model.get_added_to_offline_paths()
            new_online = list(self._model.get_removed_from_offline_paths())
            new_offline = list(offline_dirs - self._offline_paths)
            if LOGGING_ENABLED:
                logger.debug("new offline dirs %s, new online dirs %s",
                             new_offline, new_online)
            return new_offline, new_online
        else:
            return [], []

    def set_offline_paths(self, offline_paths):
        self._offline_paths = offline_paths
        logger.debug("offline paths %s", offline_paths)
        self._model.set_offline_dirs(offline_paths)
        self.show_cursor_normal()

        self._view.expand(self._proxy_model.mapFromSource(
            self._model.get_root_path_index()))
        self._proxy_model.sort(0, Qt.AscendingOrder)


    def show_cursor_loading(self, show_movie=False):
        if show_movie:
            self._ui.stackedWidget.setCurrentIndex(1)
            self._loader_movie.start()
        else:
            self._dialog.setCursor(Qt.WaitCursor)

    def show_cursor_normal(self):
        self._dialog.setCursor(Qt.ArrowCursor)
        if self._loader_movie.state() == QMovie.Running:
            self._loader_movie.stop()
        self._ui.stackedWidget.setCurrentIndex(0)