Example #1
0
    def startDrag(self, index):
        """start a drag operation with a PandasCellPayload on defined index.
        
        Args:
            index (QModelIndex): model index you want to start the drag operation.
        """

        if not index.isValid():
            return

        dataFrame = self.model().dataFrame()

        # get all infos from dataFrame
        dfindex = dataFrame.iloc[[index.row()]].index
        columnName = dataFrame.columns[index.column()]
        dtype = dataFrame[columnName].dtype
        value = dataFrame[columnName][dfindex]

        # create the mime data
        mimePayload = PandasCellPayload(dfindex, columnName, value, dtype,
                                        hex(id(self.model())))
        mimeData = MimeData()
        mimeData.setData(mimePayload)

        # create the drag icon and start drag operation
        drag = QtGui.QDrag(self)
        drag.setMimeData(mimeData)
        pixmap = QtGui.QPixmap(":/icons/insert-table.png")
        drag.setHotSpot(QtCore.QPoint(pixmap.width() / 3, pixmap.height() / 3))
        drag.setPixmap(pixmap)
        result = drag.start(Qt.MoveAction)
Example #2
0
    def removeDataFrameColumns(self, columns):
        if not self.editable:
            return False

        if columns:
            deleted = 0
            errorOccured = False
            for (position, name) in columns:
                position = position - deleted
                if position < 0:
                    position = 0
                self.beginRemoveColumns(QtCore.QModelIndex(), position,
                                        position)
                try:
                    self._dataFrame.drop(name, axis=1, inplace=True)
                except ValueError, e:
                    errorOccured = True
                    continue
                self.endRemoveColumns()
                deleted += 1

            if errorOccured:
                return False
            else:
                return True
Example #3
0
    def test_setDelegates(self, qtbot, tableView, index, value, singleStep):
        dlg = createDelegate(numpy.dtype(value), 0, tableView)
        assert dlg is not None

        data = pandas.DataFrame([value], columns=['A'])
        data['A'] = data['A'].astype(value.dtype)
        model = tableView.model()
        model.setDataFrame(data)
        for i, delegate in enumerate([dlg]):
            assert tableView.itemDelegateForColumn(i) == delegate

            option = QtGui.QStyleOptionViewItem()
            option.rect = QtCore.QRect(0, 0, 100, 100)
            editor = delegate.createEditor(tableView, option, index)
            delegate.setEditorData(editor, index)
            assert editor.value() == index.data()
            delegate.setModelData(editor, model, index)

            delegate.updateEditorGeometry(editor, option, index)

            dtype = value.dtype
            if dtype in DataFrameModel._intDtypes:
                info = numpy.iinfo(dtype)
                assert isinstance(delegate, BigIntSpinboxDelegate)
            elif dtype in DataFrameModel._floatDtypes:
                info = numpy.finfo(dtype)
                assert isinstance(delegate, CustomDoubleSpinboxDelegate)
                assert delegate.decimals == DataFrameModel._float_precisions[
                    str(value.dtype)]
            assert delegate.maximum == info.max
            assert editor.maximum() == info.max
            assert delegate.minimum == info.min
            assert editor.minimum() == info.min
            assert delegate.singleStep == singleStep
            assert editor.singleStep() == singleStep

        def clickEvent(index):
            assert index.isValid()

        tableView.clicked.connect(clickEvent)
        with qtbot.waitSignal(tableView.clicked) as blocker:
            qtbot.mouseClick(tableView.viewport(),
                             QtCore.Qt.LeftButton,
                             pos=QtCore.QPoint(10, 10))
        assert blocker.signal_triggered
Example #4
0
    def columnCount(self, index=QtCore.QModelIndex()):
        """returns number of columns

        Args:
            index (QtCore.QModelIndex, optional): Index to define column and row. defaults to empty QModelIndex

        Returns:
            number of columns
        """
        return len(self.headers)
Example #5
0
    def rowCount(self, index=QtCore.QModelIndex()):
        """returns number of rows

        Args:
            index (QtCore.QModelIndex, optional): Index to define column and row. defaults to empty QModelIndex

        Returns:
            number of rows
        """
        return len(self._dataFrame.columns)
Example #6
0
    def __init__(self, parent=None):
        """Constructs the object with the given parent.

        Args:
            parent (QObject, optional): Causes the objected to be owned
                by `parent` instead of Qt. Defaults to `None`.

        """
        super(DelimiterValidator, self).__init__(parent)
        re = QtCore.QRegExp('\S{1}')
        self.setRegExp(re)
Example #7
0
    def __init__(self, parent=None, iconSize=QtCore.QSize(36, 36)):
        """Constructs the object with the given parent.

        Args:
            parent (QObject, optional): Causes the objected to be owned
                by `parent` instead of Qt. Defaults to `None`.
            iconSize (QSize, optional): Size of edit buttons. Defaults to QSize(36, 36).

        """
        super(DataTableWidget, self).__init__(parent)
        self._iconSize = iconSize
        self.initUi()
Example #8
0
    def columnCount(self, index=QtCore.QModelIndex()):
        """returns number of columns

        Args:
            index (QtCore.QModelIndex, optional): Index to define column and row. defaults to empty QModelIndex

        Returns:
            number of columns
        """
        # speed comparison:
        # In [23]: %timeit len(df.columns)
        # 10000000 loops, best of 3: 108 ns per loop

        # In [24]: %timeit df.shape[1]
        # 1000000 loops, best of 3: 440 ns per loop
        return len(self._dataFrame.columns)
Example #9
0
    def rowCount(self, index=QtCore.QModelIndex()):
        """returns number of rows

        Args:
            index (QtCore.QModelIndex, optional): Index to define column and row. defaults to empty QModelIndex

        Returns:
            number of rows
        """
        # len(df.index) is faster, so use it:
        # In [12]: %timeit df.shape[0]
        # 1000000 loops, best of 3: 437 ns per loop
        # In [13]: %timeit len(df.index)
        # 10000000 loops, best of 3: 110 ns per loop
        # %timeit df.__len__()
        # 1000000 loops, best of 3: 215 ns per loop
        return len(self._dataFrame.index)
Example #10
0
def createThread(parent, worker, deleteWorkerLater=False):
    """Create a new thread for given worker.
    
    Args:
        parent (QObject): parent of thread and worker.
        worker (ProgressWorker): worker to use in thread.
        deleteWorkerLater (bool, optional): delete the worker if thread finishes.

    Returns:
        QThread

    """
    thread = QtCore.QThread(parent)
    thread.started.connect(worker.doWork)
    worker.finished.connect(thread.quit)
    if deleteWorkerLater:
        thread.finished.connect(worker.deleteLater)
    
    worker.moveToThread(thread)
    worker.setParent(parent)
    return thread
Example #11
0
    def addDataFrameColumn(self, columnName, dtype, defaultValue):
        if not self.editable or dtype not in SupportedDtypes.allTypes():
            return False

        elements = self.rowCount()
        columnPosition = self.columnCount()

        newColumn = pandas.Series([defaultValue] * elements,
                                  index=self._dataFrame.index,
                                  dtype=dtype)

        self.beginInsertColumns(QtCore.QModelIndex(), columnPosition - 1,
                                columnPosition - 1)
        try:
            self._dataFrame.insert(columnPosition,
                                   columnName,
                                   newColumn,
                                   allow_duplicates=False)
        except ValueError, e:
            # columnName does already exist
            return False
Example #12
0
    def __init__(self, parent=None):
        """the __init__ method.

        Args:
            parent (QObject): defaults to None. If parent is 0, the new widget becomes a window.
                If parent is another widget, this widget becomes a child window inside parent.
                The new widget is deleted when its parent is deleted.

        """
        super(BigIntSpinbox, self).__init__(parent)

        self._singleStep = 1
        self._minimum = -18446744073709551616
        self._maximum = 18446744073709551615

        rx = QtCore.QRegExp("[0-9]\\d{0,20}")
        validator = QtGui.QRegExpValidator(rx, self)

        self._lineEdit = QtWidgets.QLineEdit(self)
        self._lineEdit.setText('0')
        self._lineEdit.setValidator(validator)
        self.setLineEdit(self._lineEdit)
    def test_data(self, dataframe):
        model = ColumnDtypeModel(dataFrame=dataframe)
        index = model.index(0, 0)

        # get data for display role
        ret = index.data()
        assert ret == 'Foo'

        # edit role does the same as display role
        ret = index.data(Qt.EditRole)
        assert ret == 'Foo'

        # datatype only defined for column 1
        ret = index.data(DTYPE_ROLE)
        assert ret == None

        # datatype column
        index = index.sibling(0, 1)
        ret = index.data(DTYPE_ROLE)
        assert ret == numpy.dtype(numpy.int64)
        # check translation / display text
        assert index.data(
        ) == 'integer (64 bit)' == SupportedDtypes.description(ret)

        # column not defined
        index = index.sibling(0, 2)
        assert index.data(DTYPE_ROLE) == None

        # invalid index
        index = QtCore.QModelIndex()
        assert model.data(index) == None

        index = model.index(2, 0)

        # get data for display role
        ret = index.data()
        assert ret == 'Spam'
Example #14
0
    def addDataFrameRows(self, count=1):
        # don't allow any gaps in the data rows.
        # and always append at the end

        if not self.editable:
            return False

        position = self.rowCount()

        if count < 1:
            return False

        if len(self.dataFrame().columns) == 0:
            # log an error message or warning
            return False

        # Note: This function emits the rowsAboutToBeInserted() signal which
        # connected views (or proxies) must handle before the data is
        # inserted. Otherwise, the views may end up in an invalid state.
        self.beginInsertRows(QtCore.QModelIndex(), position,
                             position + count - 1)

        defaultValues = []
        for dtype in self._dataFrame.dtypes:
            if dtype.type == numpy.dtype('<M8[ns]'):
                val = pandas.Timestamp('')
            elif dtype.type == numpy.dtype(object):
                val = ''
            else:
                val = dtype.type()
            defaultValues.append(val)

        for i in xrange(count):
            self._dataFrame.loc[position + i] = defaultValues
        self._dataFrame.reset_index()
        self.endInsertRows()
        return True
Example #15
0
    def removeDataFrameRows(self, rows):
        if not self.editable:
            return False

        if rows:
            position = min(rows)
            count = len(rows)
            self.beginRemoveRows(QtCore.QModelIndex(), position,
                                 position + count - 1)

            removedAny = False
            for idx, line in self._dataFrame.iterrows():
                if idx in rows:
                    removedAny = True
                    self._dataFrame.drop(idx, inplace=True)

            if not removedAny:
                return False

            self._dataFrame.reset_index(inplace=True, drop=True)

            self.endRemoveRows()
            return True
        return False
Example #16
0
 def test_invalidIndex(self, model):
     assert model.data(QtCore.QModelIndex()) is None
Example #17
0
 def test_invalidIndex(self, model):
     assert model.setData(QtCore.QModelIndex(), None) == False
Example #18
0
    def initUi(self):
        """Initalizes the Uuser Interface with all sub widgets.

        """
        self.gridLayout = QtWidgets.QGridLayout(self)

        self.buttonFrame = QtWidgets.QFrame(self)
        self.buttonFrame.setMinimumSize(QtCore.QSize(250, 50))
        self.buttonFrame.setMaximumSize(QtCore.QSize(250, 50))
        self.buttonFrame.setFrameShape(QtWidgets.QFrame.NoFrame)

        self.buttonFrameLayout = QtWidgets.QGridLayout(self.buttonFrame)
        self.buttonFrameLayout.setContentsMargins(0, 6, 0, 6)

        self.editButton = QtWidgets.QToolButton(self.buttonFrame)
        self.editButton.setObjectName('editbutton')
        icon = QtGui.QIcon(QtGui.QPixmap(_fromUtf8(':/icons/document-edit.png')))

        self.editButton.setIcon(icon)

        self.addColumnButton = QtWidgets.QToolButton(self.buttonFrame)
        self.addColumnButton.setObjectName('addcolumnbutton')
        icon = QtGui.QIcon(QtGui.QPixmap(_fromUtf8(':/icons/edit-table-insert-column-right.png')))

        self.addColumnButton.setIcon(icon)

        self.addRowButton = QtWidgets.QToolButton(self.buttonFrame)
        self.addRowButton.setObjectName('addrowbutton')
        icon = QtGui.QIcon(QtGui.QPixmap(_fromUtf8(':/icons/edit-table-insert-row-below.png')))

        self.addRowButton.setIcon(icon)

        self.removeColumnButton = QtWidgets.QToolButton(self.buttonFrame)
        self.removeColumnButton.setObjectName('removecolumnbutton')
        icon = QtGui.QIcon(QtGui.QPixmap(_fromUtf8(':/icons/edit-table-delete-column.png')))

        self.removeColumnButton.setIcon(icon)

        self.removeRowButton = QtWidgets.QToolButton(self.buttonFrame)
        self.removeRowButton.setObjectName('removerowbutton')
        icon = QtGui.QIcon(QtGui.QPixmap(_fromUtf8(':/icons/edit-table-delete-row.png')))

        self.removeRowButton.setIcon(icon)

        self.buttons = [self.editButton, self.addColumnButton, self.addRowButton, self.removeColumnButton, self.removeRowButton]

        for index, button in enumerate(self.buttons):
            button.setMinimumSize(QtCore.QSize(36, 36))
            button.setMaximumSize(QtCore.QSize(36, 36))
            button.setIconSize(QtCore.QSize(36, 36))
            button.setCheckable(True)
            self.buttonFrameLayout.addWidget(button, 0, index, 1, 1)

        for button in self.buttons[1:]:
            button.setEnabled(False)

        self.tableView = QtWidgets.QTableView(self)
        self.tableView.setAlternatingRowColors(True)
        self.tableView.setSortingEnabled(True)

        self.gridLayout.addWidget(self.buttonFrame, 0, 0, 1, 1)
        self.gridLayout.addWidget(self.tableView, 1, 0, 1, 1)

        self.editButton.toggled.connect(self.enableEditing)
        self.addColumnButton.toggled.connect(self.showAddColumnDialog)
        self.addRowButton.toggled.connect(self.addRow)
        self.removeRowButton.toggled.connect(self.removeRow)
        self.removeColumnButton.toggled.connect(self.showRemoveColumnDialog)