def fetchMore(self, index=QtCore.QModelIndex()): n_rows = len(self._dataFrame.index) remainder = n_rows - self.rowsLoaded itemsToFetch = min(remainder, DataFrameModel._row_batch_count) self.beginInsertRows(QtCore.QModelIndex(), self.rowsLoaded, self.rowsLoaded + itemsToFetch - 1) self.rowsLoaded += itemsToFetch self.endInsertRows() return
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)
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 self.dataChanged.emit() if errorOccured: return False else: return True
def canFetchMore(self, index=QtCore.QModelIndex()): n_rows = len(self._dataFrame.index) if n_rows > self.rowsLoaded: return True else: return False
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
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)
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)
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)
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()
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)
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
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
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 = QtGui.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).toPyObject() assert ret == numpy.dtype(numpy.int64) # check translation / display text assert (index.data().toPyObject() == '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'
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 # In [14]: %timeit df.__len__() # 1000000 loops, best of 3: 215 ns per loop n_rows = len(self._dataFrame.index) if n_rows <= self.rowsLoaded: return n_rows else: return self.rowsLoaded
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
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
def test_invalidIndex(self, model): assert model.setData(QtCore.QModelIndex(), None) == False
def test_invalidIndex(self, model): assert model.data(QtCore.QModelIndex()) is None