def setDataFrame(self, dataFrame): self.df = dataFrame dataModel = DataFrameModel() dataModel.setDataFrame(self.df) self.dataModel = dataModel self.dataListView.setModel(dataModel) self.dataTableView.setViewModel(dataModel) self.dataComboBox.setModel(dataModel) # self.dataTableView.resizeColumnsToContents() # create a simple item model for our choosing combobox columnModel = QtGui.QStandardItemModel() for column in self.df.columns: columnModel.appendRow(QtGui.QStandardItem(column)) self.chooseColumnComboBox.setModel(columnModel) self.tableViewColumnDtypes.setModel(dataModel.columnDtypeModel()) self.tableViewColumnDtypes.horizontalHeader().setDefaultSectionSize( 200) self.tableViewColumnDtypes.setItemDelegateForColumn( 1, DtypeComboDelegate(self.tableViewColumnDtypes)) dataModel.changingDtypeFailed.connect(self.changeColumnValue)
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 initUI(self): self.setGeometry(100, 100, 300, 300) self.vlayout = QtGui.QVBoxLayout(self) self.imgContainer = QtGui.QLabel(self) img = QtGui.QPixmap(':/europe.png') self.imgContainer.setPixmap(img) size = img.size() self.imgContainer.resize(size.width(), self.height()) self.vlayout.addWidget(self.imgContainer) self.vlayout.addWidget(QtGui.QLabel('FOOO', self)) threads = [] worker1 = ExampleWorker('foo', 10) worker2 = ExampleWorker('bar', 13) worker3 = ExampleWorker('spam', 25) workers = [worker1, worker2, worker3] for worker in workers: thread = createThread(self, worker) threads.append(thread) worker.finished.connect(self.debugPrint) self.pgFrame = OverlayProgressWidget(self.imgContainer, workers=workers) for t in threads: t.start()
def initUi(self): self.sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding) self._pbHeight = 30 self.setMinimumWidth(self._width) #self.setMaximumWidth(self._width) self.setMinimumHeight(self._minHeight) self.glayout = QtGui.QGridLayout(self) self.totalProgressBar = QtGui.QProgressBar(self) self.totalProgressBar.setMinimumHeight(self._pbHeight) self.totalProgressBar.setMaximumHeight(self._pbHeight) self.toggleButton = QtGui.QPushButton('Details', self) self.toggleButton.setCheckable(True) self.toggleButton.toggled.connect(self.showDetails) self.glayout.addWidget(self.totalProgressBar, 0, 0, 1, 1) self.glayout.addWidget(self.toggleButton, 0, 1, 1, 1) #styleSheet = """.QProgressBar { #border: none; #border-radius: 3px; #text-align: center; #background-color: rgba(37, 37, 37, 50%); #color: white; #margin: 1px; #border-bottom-left-radius:5px; #border-top-left-radius:5px; #} #.QProgressBar::chunk { #background-color: #05B8CC; #border-radius: 3px; #} #.OverlayProgressWidget { #background-color: white; #} #""" ## set stylesheet for all progressbars in this widget #self.setStyleSheet(styleSheet) parent = self.parent() xAnchor = parent.width() - self._width - self._margin yAnchor = self._margin self.setGeometry(xAnchor, yAnchor, self._width, self._minHeight)
def test_editing(self, dataFrame, qtbot): model = DataFrameModel(dataFrame) tableView = QtGui.QTableView() qtbot.addWidget(tableView) tableView.setModel(model) delegate = TextDelegate(tableView) createDelegate(numpy.dtype('O'), 0, tableView) tableView.show() index = model.index(0, 0) preedit_data = index.data() assert not model.editable model.enableEditing(True) tableView.edit(index) editor = tableView.findChildren(QtGui.QLineEdit)[0] qtbot.keyPress(editor, QtCore.Qt.Key_F) qtbot.keyPress(editor, QtCore.Qt.Key_Enter) QtGui.QApplication.processEvents() # with qtbot.waitSignal(timeout=100): # print index.data(QtCore.Qt.DisplayRole).toPyObject() assert index.data(QtCore.Qt.DisplayRole).toPyObject() == 'f'
def _addProgressBar(self, worker): progressBar = QtGui.QProgressBar(self) progressBar.setMinimumHeight(self._pbHeight - 5) progressBar.setMaximumHeight(self._pbHeight - 5) label = QtGui.QLabel(worker.name, self) if not self.toggleButton.isChecked(): progressBar.hide() label.hide() row = self._addedBars + 1 self.glayout.addWidget(progressBar, row, 0, 1, 1) self.glayout.addWidget(label, row, 1, 1, 1) self._addedBars += 1 self._detailProgressBars.append((progressBar, label)) worker.progressChanged.connect(progressBar.setValue) worker.progressChanged.connect(self.calculateTotalProgress) worker.progressChanged.connect(self.debugProgressChanged)
def initUi(self): self.setWindowTitle(self.tr('Remove Attributes')) self.setModal(True) self.resize(366, 274) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding) self.setSizePolicy(sizePolicy) self.gridLayout = QtGui.QGridLayout(self) self.dialogHeading = QtGui.QLabel( self.tr('Select the attribute column(s) which shall be removed'), self) self.listView = QtGui.QListView(self) model = QtGui.QStandardItemModel() for column in self.columns: item = QtGui.QStandardItem(column) model.appendRow(item) self.listView.setModel(model) self.listView.setSelectionMode(QtGui.QListView.MultiSelection) self.buttonBox = QtGui.QDialogButtonBox(self) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok) self.gridLayout.addWidget(self.dialogHeading, 0, 0, 1, 1) self.gridLayout.addWidget(self.listView, 1, 0, 1, 1) self.gridLayout.addWidget(self.buttonBox, 2, 0, 1, 1) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject)
def test_tableViewMissing(self, widgetClass, qtbot, model, exception, exceptionContains): widget = widgetClass() qtbot.addWidget(widget) with pytest.raises(exception) as excinfo: if model: widget.setModel(QtGui.QStandardItemModel()) createDelegate('foo', 'bar', widget) assert exceptionContains in str(excinfo.value)
def test_input(self, qtbot): widget = QtGui.QLineEdit() widget.setValidator(DelimiterValidator()) qtbot.addWidget(widget) widget.show() qtbot.keyPress(widget, ' ') assert widget.text() == '' qtbot.keyPress(widget, 'a') assert widget.text() == 'a'
def createEditor(self, parent, option, index): """Returns the widget used to edit the item specified by index for editing. The parent widget and style option are used to control how the editor widget appears. Args: parent (QWidget): parent widget. option (QStyleOptionViewItem): controls how editor widget appears. index (QModelIndex): model data index. """ editor = QtGui.QLineEdit(parent) return editor
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 createEditor(self, parent, option, index): """Returns the widget used to edit the item specified by index for editing. The parent widget and style option are used to control how the editor widget appears. Args: parent (QWidget): parent widget. option (QStyleOptionViewItem): controls how editor widget appears. index (QModelIndex): model data index. """ editor = QtGui.QDoubleSpinBox(parent) try: editor.setMinimum(self.minimum) editor.setMaximum(self.maximum) editor.setSingleStep(self.singleStep) editor.setDecimals(self.decimals) except TypeError, err: # initiate the spinbox with default values. pass
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 test_editing(self, dataframe, qtbot): model = ColumnDtypeModel(dataFrame=dataframe) model.setEditable(True) tableView = QtGui.QTableView() qtbot.addWidget(tableView) tableView.setModel(model) delegate = DtypeComboDelegate(tableView) tableView.setItemDelegateForColumn(1, delegate) tableView.show() index = model.index(0, 1) preedit_data = index.data(DTYPE_ROLE) tableView.edit(index) editor = tableView.findChildren(QtGui.QComboBox)[0] selectedIndex = editor.currentIndex() editor.setCurrentIndex(selectedIndex + 1) postedit_data = index.data(DTYPE_ROLE) assert preedit_data != postedit_data
def createEditor(self, parent, option, index): """Creates an Editor Widget for the given index. Enables the user to manipulate the displayed data in place. An editor is created, which performs the change. The widget used will be a `QComboBox` with all available datatypes in the `pandas` project. Args: parent (QtCore.QWidget): Defines the parent for the created editor. option (QtGui.QStyleOptionViewItem): contains all the information that QStyle functions need to draw the items. index (QtCore.QModelIndex): The item/index which shall be edited. Returns: QtGui.QWidget: he widget used to edit the item specified by index for editing. """ combo = QtGui.QComboBox(parent) combo.addItems(SupportedDtypes.names()) combo.currentIndexChanged.connect(self.currentIndexChanged) return combo
def _initUI(self): """Creates the inital layout with all subwidgets. The layout is a `QHBoxLayout`. Each time a radio button is selected or unselected, a slot `DelimiterSelectionWidget._delimiter` is called. Furthermore the `QLineEdit` widget has a custom regex validator `DelimiterValidator` enabled. """ #layout = QtGui.QHBoxLayout(self) self.semicolonRadioButton = QtGui.QRadioButton(u'Semicolon') self.commaRadioButton = QtGui.QRadioButton(u'Comma') self.tabRadioButton = QtGui.QRadioButton(u'Tab') self.otherRadioButton = QtGui.QRadioButton(u'Other') self.semicolonRadioButton.setChecked(True) self.otherSeparatorLineEdit = QtGui.QLineEdit(self) self.otherSeparatorLineEdit.setEnabled(False) self.semicolonRadioButton.toggled.connect(self._delimiter) self.commaRadioButton.toggled.connect(self._delimiter) self.tabRadioButton.toggled.connect(self._delimiter) self.otherRadioButton.toggled.connect(self._enableLine) self.otherSeparatorLineEdit.textChanged.connect( lambda: self._delimiter(True)) self.otherSeparatorLineEdit.setValidator(DelimiterValidator(self)) currentLayout = self.layout() # unset and delete the current layout in order to set a new one if currentLayout is not None: del currentLayout layout = QtGui.QHBoxLayout() layout.addWidget(self.semicolonRadioButton) layout.addWidget(self.commaRadioButton) layout.addWidget(self.tabRadioButton) layout.addWidget(self.otherRadioButton) layout.addWidget(self.otherSeparatorLineEdit) self.setLayout(layout)
def initUi(self, edit_rows, edit_cols, edit_cells=False): """Initalizes the Uuser Interface with all sub widgets. """ self.gridLayout = QtGui.QGridLayout(self) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.buttonFrame = QtGui.QFrame(self) #self.buttonFrame.setMinimumSize(QtCore.QSize(250, 50)) #self.buttonFrame.setMaximumSize(QtCore.QSize(250, 50)) self.buttonFrame.setFrameShape(QtGui.QFrame.NoFrame) spacerItemButton = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) if edit_rows: self.addRowButton = QtGui.QToolButton(self.buttonFrame) self.addRowButton.setObjectName('addrowbutton') self.addRowButton.setText(self.tr(u'+row')) self.addRowButton.setToolTip(self.tr(u'add new row')) icon = QtGui.QIcon( QtGui.QPixmap( _fromUtf8(':/icons/edit-table-insert-row-below.png'))) self.addRowButton.setIcon(icon) self.addRowButton.toggled.connect(self.addRow) self.removeRowButton = QtGui.QToolButton(self.buttonFrame) self.removeRowButton.setObjectName('removerowbutton') self.removeRowButton.setText(self.tr(u'-row')) self.removeRowButton.setToolTip(self.tr(u'remove selected rows')) icon = QtGui.QIcon( QtGui.QPixmap(_fromUtf8(':/icons/edit-table-delete-row.png'))) self.removeRowButton.setIcon(icon) self.removeRowButton.toggled.connect(self.removeRow) row_buttons = [self.addRowButton, self.removeRowButton] if edit_cols: self.addColumnButton = QtGui.QToolButton(self.buttonFrame) self.addColumnButton.setObjectName('addcolumnbutton') self.addColumnButton.setText(self.tr(u'+col')) self.addColumnButton.setToolTip(self.tr(u'add new column')) icon = QtGui.QIcon( QtGui.QPixmap( _fromUtf8(':/icons/edit-table-insert-column-right.png'))) self.addColumnButton.setIcon(icon) self.addColumnButton.toggled.connect(self.showAddColumnDialog) self.removeColumnButton = QtGui.QToolButton(self.buttonFrame) self.removeColumnButton.setObjectName('removecolumnbutton') self.removeColumnButton.setText(self.tr(u'-col')) self.removeColumnButton.setToolTip(self.tr(u'remove a column')) icon = QtGui.QIcon( QtGui.QPixmap( _fromUtf8(':/icons/edit-table-delete-column.png'))) self.removeColumnButton.setIcon(icon) self.removeColumnButton.toggled.connect( self.showRemoveColumnDialog) col_buttons = [self.addColumnButton, self.removeColumnButton] if edit_rows or edit_cols or edit_cells: self.buttonFrameLayout = QtGui.QGridLayout(self.buttonFrame) self.buttonFrameLayout.setContentsMargins(0, 0, 0, 0) self.editButton = QtGui.QToolButton(self.buttonFrame) self.editButton.setObjectName('editbutton') self.editButton.setText(self.tr(u'edit')) self.editButton.setToolTip(self.tr(u'toggle editing mode')) icon = QtGui.QIcon( QtGui.QPixmap(_fromUtf8(':/icons/document-edit.png'))) self.editButton.setIcon(icon) self.editButton.toggled.connect(self.enableEditing) edit_buttons = [self.editButton] if edit_rows and edit_cols: for x in zip(row_buttons, col_buttons): edit_buttons.extend(x) elif edit_rows: edit_buttons.extend(row_buttons) elif edit_cols: edit_buttons.extend(col_buttons) elif not edit_cells: errStr = "Ack! Ack! Ack!" raise SystemError(errStr) self.buttons = edit_buttons for index, button in enumerate(self.buttons): button.setMinimumSize(self._iconSize) button.setMaximumSize(self._iconSize) button.setIconSize(self._iconSize) button.setCheckable(True) self.buttonFrameLayout.addWidget(button, 0, index, 1, 1) self.buttonFrameLayout.addItem(spacerItemButton, 0, index + 1, 1, 1) for button in self.buttons[1:]: button.setEnabled(False) else: self.buttons = None #self.tableView = QtGui.QTableView(self) self.tableView = DragTable(self) self.tableView.setAlternatingRowColors(True) self.tableView.setSortingEnabled(True) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) self.tableView.setSizePolicy(sizePolicy) self.tableView.installEventFilter(self) self.gridLayout.addWidget(self.buttonFrame, 0, 0, 1, 1) self.gridLayout.addWidget(self.tableView, 1, 0, 1, 1) return
def initUi(self): """Initalizes the Uuser Interface with all sub widgets. """ self.gridLayout = QtGui.QGridLayout(self) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.buttonFrame = QtGui.QFrame(self) #self.buttonFrame.setMinimumSize(QtCore.QSize(250, 50)) #self.buttonFrame.setMaximumSize(QtCore.QSize(250, 50)) self.buttonFrame.setFrameShape(QtGui.QFrame.NoFrame) spacerItemButton = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) self.buttonFrameLayout = QtGui.QGridLayout(self.buttonFrame) self.buttonFrameLayout.setContentsMargins(0, 0, 0, 0) self.editButton = QtGui.QToolButton(self.buttonFrame) self.editButton.setObjectName('editbutton') self.editButton.setText(self.tr(u'edit')) self.editButton.setToolTip(self.tr(u'toggle editing mode')) icon = QtGui.QIcon( QtGui.QPixmap(_fromUtf8(':/icons/document-edit.png'))) self.editButton.setIcon(icon) self.addColumnButton = QtGui.QToolButton(self.buttonFrame) self.addColumnButton.setObjectName('addcolumnbutton') self.addColumnButton.setText(self.tr(u'+col')) self.addColumnButton.setToolTip(self.tr(u'add new column')) icon = QtGui.QIcon( QtGui.QPixmap( _fromUtf8(':/icons/edit-table-insert-column-right.png'))) self.addColumnButton.setIcon(icon) self.addRowButton = QtGui.QToolButton(self.buttonFrame) self.addRowButton.setObjectName('addrowbutton') self.addRowButton.setText(self.tr(u'+row')) self.addRowButton.setToolTip(self.tr(u'add new row')) icon = QtGui.QIcon( QtGui.QPixmap( _fromUtf8(':/icons/edit-table-insert-row-below.png'))) self.addRowButton.setIcon(icon) self.removeColumnButton = QtGui.QToolButton(self.buttonFrame) self.removeColumnButton.setObjectName('removecolumnbutton') self.removeColumnButton.setText(self.tr(u'-col')) self.removeColumnButton.setToolTip(self.tr(u'remove a column')) icon = QtGui.QIcon( QtGui.QPixmap(_fromUtf8(':/icons/edit-table-delete-column.png'))) self.removeColumnButton.setIcon(icon) self.removeRowButton = QtGui.QToolButton(self.buttonFrame) self.removeRowButton.setObjectName('removerowbutton') self.removeRowButton.setText(self.tr(u'-row')) self.removeRowButton.setToolTip(self.tr(u'remove selected rows')) 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(self._iconSize) button.setMaximumSize(self._iconSize) button.setIconSize(self._iconSize) button.setCheckable(True) self.buttonFrameLayout.addWidget(button, 0, index, 1, 1) self.buttonFrameLayout.addItem(spacerItemButton, 0, index + 1, 1, 1) for button in self.buttons[1:]: button.setEnabled(False) #self.tableView = QtGui.QTableView(self) self.tableView = DragTable(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)
def initUi(self): self.setModal(True) self.resize(303, 168) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) self.setSizePolicy(sizePolicy) self.verticalLayout = QtGui.QVBoxLayout(self) self.dialogHeading = QtGui.QLabel( self.tr('Add a new attribute column'), self) self.gridLayout = QtGui.QGridLayout() self.columnNameLineEdit = QtGui.QLineEdit(self) self.columnNameLabel = QtGui.QLabel(self.tr('Name'), self) self.dataTypeComboBox = QtGui.QComboBox(self) self.dataTypeComboBox.addItems(SupportedDtypes.names()) self.columnTypeLabel = QtGui.QLabel(self.tr('Type'), self) self.defaultValueLineEdit = QtGui.QLineEdit(self) self.lineEditValidator = DefaultValueValidator(self) self.defaultValueLineEdit.setValidator(self.lineEditValidator) self.defaultValueLabel = QtGui.QLabel(self.tr('Inital Value(s)'), self) self.gridLayout.addWidget(self.columnNameLabel, 0, 0, 1, 1) self.gridLayout.addWidget(self.columnNameLineEdit, 0, 1, 1, 1) self.gridLayout.addWidget(self.columnTypeLabel, 1, 0, 1, 1) self.gridLayout.addWidget(self.dataTypeComboBox, 1, 1, 1, 1) self.gridLayout.addWidget(self.defaultValueLabel, 2, 0, 1, 1) self.gridLayout.addWidget(self.defaultValueLineEdit, 2, 1, 1, 1) self.buttonBox = QtGui.QDialogButtonBox(self) self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok) self.verticalLayout.addWidget(self.dialogHeading) self.verticalLayout.addLayout(self.gridLayout) self.verticalLayout.addWidget(self.buttonBox) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.dataTypeComboBox.currentIndexChanged.connect( self.updateValidatorDtype) self.updateValidatorDtype(self.dataTypeComboBox.currentIndex())
class TestCustomDelegates(object): @pytest.fixture def emptyTableView(self, qtbot): widget = DemoTableView() qtbot.addWidget(widget) return widget @pytest.fixture def dataFrame(self): return pandas.DataFrame(['abc'], columns=['A']) @pytest.fixture def model(self, dataFrame): return DataFrameModel(dataFrame) @pytest.fixture def tableView(self, model, emptyTableView): emptyTableView.setModel(model) return emptyTableView @pytest.fixture def index(self, model): index = model.index(0, 0) assert index.isValid() return index @pytest.mark.parametrize( "widgetClass, model, exception, exceptionContains", [ (QtGui.QWidget, None, AttributeError, "has no attribute 'model'"), (DemoTableView, None, ValueError, "no model set for the current view"), (DemoTableView, QtGui.QStandardItemModel(), TypeError, 'model is not of type DataFrameModel'), ]) def test_tableViewMissing(self, widgetClass, qtbot, model, exception, exceptionContains): widget = widgetClass() qtbot.addWidget(widget) with pytest.raises(exception) as excinfo: if model: widget.setModel(QtGui.QStandardItemModel()) createDelegate('foo', 'bar', widget) assert exceptionContains in str(excinfo.value) @pytest.mark.parametrize( "value, singleStep", [ (numpy.int8(1), 1), (numpy.int16(1), 1), (numpy.int32(1), 1), (numpy.int64(1), 1), (numpy.uint8(1), 1), (numpy.uint16(1), 1), (numpy.uint32(1), 1), (numpy.uint64(1), 1), (numpy.float16(1.11111), 0.1), (numpy.float32(1.11111111), 0.1), (numpy.float64(1.1111111111111111), 0.1), #(numpy.float128(1.11111111111111111111), 0.1), ]) 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 data(self, index, role=Qt.DisplayRole): """return data depending on index, Qt::ItemDataRole and data type of the column. Args: index (QtCore.QModelIndex): Index to define column and row you want to return role (Qt::ItemDataRole): Define which data you want to return. Returns: None if index is invalid None if role is none of: DisplayRole, EditRole, CheckStateRole, DATAFRAME_ROLE if role DisplayRole: unmodified _dataFrame value if column dtype is object (string or unicode). _dataFrame value as int or long if column dtype is in _intDtypes. _dataFrame value as float if column dtype is in _floatDtypes. Rounds to defined precision (look at: _float16_precision, _float32_precision). None if column dtype is in _boolDtypes. QDateTime if column dtype is numpy.timestamp64[ns]. Uses timestampFormat as conversion template. if role EditRole: unmodified _dataFrame value if column dtype is object (string or unicode). _dataFrame value as int or long if column dtype is in _intDtypes. _dataFrame value as float if column dtype is in _floatDtypes. Rounds to defined precision (look at: _float16_precision, _float32_precision). _dataFrame value as bool if column dtype is in _boolDtypes. QDateTime if column dtype is numpy.timestamp64[ns]. Uses timestampFormat as conversion template. if role CheckStateRole: Qt.Checked or Qt.Unchecked if dtype is numpy.bool_ otherwise None for all other dtypes. if role DATAFRAME_ROLE: unmodified _dataFrame value. raises TypeError if an unhandled dtype is found in column. """ if not index.isValid(): return None def convertValue(row, col, columnDtype): value = None if columnDtype == object: value = self._dataFrame.iloc[row, col] elif columnDtype in self._floatDtypes: value = round(float(self._dataFrame.iloc[row, col]), self._float_precisions[str(columnDtype)]) elif columnDtype in self._intDtypes: value = int(self._dataFrame.iloc[row, col]) elif columnDtype in self._boolDtypes: # TODO this will most likely always be true # See: http://stackoverflow.com/a/715455 # well no: I am mistaken here, the data is already in the dataframe # so its already converted to a bool value = bool(self._dataFrame.iloc[row, col]) elif columnDtype in self._dateDtypes: #print numpy.datetime64(self._dataFrame.ix[row, col]) value = pandas.Timestamp(self._dataFrame.iloc[row, col]) value = QtCore.QDateTime.fromString(str(value), self.timestampFormat) #print value # else: # raise TypeError, "returning unhandled data type" return value rowi = index.row() coli = index.column() columnDtype = self._dataFrame.dtypes[coli] if role == Qt.DisplayRole: # return the value if you wanne show True/False as text if columnDtype == numpy.bool: result = self._dataFrame.iloc[rowi, coli] else: result = convertValue(rowi, coli, columnDtype) elif role == Qt.EditRole: result = convertValue(rowi, coli, columnDtype) elif role == Qt.CheckStateRole: if columnDtype == numpy.bool_: if convertValue(rowi, coli, columnDtype): result = Qt.Checked else: result = Qt.Unchecked else: result = None elif role == DATAFRAME_ROLE: result = self._dataFrame.iloc[rowi, coli] elif role == Qt.BackgroundRole: if self.freeze_first and coli == 0: return QtGui.QBrush(Qt.lightGray) else: return QtGui.QBrush(Qt.white) elif role == Qt.FontRole: if self.freeze_first and coli == 0: font = QtGui.QFont() font.setBold(True) return font else: return QtGui.QFont elif role == Qt.TextAlignmentRole: if self.freeze_first and coli == 0: return Qt.AlignCenter else: return Qt.AlignLeft | QtCore.Qt.AlignVCenter else: result = None return result
def _initUI(self): """Initiates the user interface with a grid layout and several widgets. """ self.setModal(self._modal) self.setWindowTitle(self._windowTitle) layout = QtGui.QGridLayout() self._filenameLabel = QtGui.QLabel(u'Choose File', self) self._filenameLineEdit = QtGui.QLineEdit(self) self._filenameLineEdit.textEdited.connect(self._updateFilename) chooseFileButtonIcon = QtGui.QIcon( QtGui.QPixmap(':/icons/document-open.png')) self._chooseFileAction = QtGui.QAction(self) self._chooseFileAction.setIcon(chooseFileButtonIcon) self._chooseFileAction.triggered.connect(self._openFile) self._chooseFileButton = QtGui.QToolButton(self) self._chooseFileButton.setDefaultAction(self._chooseFileAction) layout.addWidget(self._filenameLabel, 0, 0) layout.addWidget(self._filenameLineEdit, 0, 1, 1, 2) layout.addWidget(self._chooseFileButton, 0, 3) self._encodingLabel = QtGui.QLabel(u'File Encoding', self) encoding_names = map(lambda x: x.upper(), sorted(list(set(_encodings.viewvalues())))) self._encodingComboBox = QtGui.QComboBox(self) self._encodingComboBox.addItems(encoding_names) self._encodingComboBox.activated.connect(self._updateEncoding) layout.addWidget(self._encodingLabel, 1, 0) layout.addWidget(self._encodingComboBox, 1, 1, 1, 1) self._hasHeaderLabel = QtGui.QLabel(u'Header Available?', self) self._headerCheckBox = QtGui.QCheckBox(self) self._headerCheckBox.toggled.connect(self._updateHeader) layout.addWidget(self._hasHeaderLabel, 2, 0) layout.addWidget(self._headerCheckBox, 2, 1) self._delimiterLabel = QtGui.QLabel(u'Column Delimiter', self) self._delimiterBox = DelimiterSelectionWidget(self) self._delimiter = self._delimiterBox.currentSelected() self._delimiterBox.delimiter.connect(self._updateDelimiter) layout.addWidget(self._delimiterLabel, 3, 0) layout.addWidget(self._delimiterBox, 3, 1, 1, 3) self._tabWidget = QtGui.QTabWidget(self) self._previewTableView = QtGui.QTableView(self) self._datatypeTableView = QtGui.QTableView(self) self._tabWidget.addTab(self._previewTableView, u'Preview') self._tabWidget.addTab(self._datatypeTableView, u'Change Column Types') layout.addWidget(self._tabWidget, 4, 0, 3, 4) self._datatypeTableView.horizontalHeader().setDefaultSectionSize(200) self._datatypeTableView.setItemDelegateForColumn( 1, DtypeComboDelegate(self._datatypeTableView)) self._loadButton = QtGui.QPushButton(u'Load Data', self) #self.loadButton.setAutoDefault(False) self._cancelButton = QtGui.QPushButton(u'Cancel', self) # self.cancelButton.setDefault(False) # self.cancelButton.setAutoDefault(True) self._buttonBox = QtGui.QDialogButtonBox(self) self._buttonBox.addButton(self._loadButton, QtGui.QDialogButtonBox.AcceptRole) self._buttonBox.addButton(self._cancelButton, QtGui.QDialogButtonBox.RejectRole) self._buttonBox.accepted.connect(self.accepted) self._buttonBox.rejected.connect(self.rejected) layout.addWidget(self._buttonBox, 9, 2, 1, 2) self._loadButton.setDefault(False) self._filenameLineEdit.setFocus() self._statusBar = QtGui.QStatusBar(self) self._statusBar.setSizeGripEnabled(False) layout.addWidget(self._statusBar, 8, 0, 1, 4) self.setLayout(layout)
def _initUI(self): """Initiates the user interface with a grid layout and several widgets. """ self.setModal(self._modal) self.setWindowTitle(self._windowTitle) layout = QtGui.QGridLayout() self._filenameLabel = QtGui.QLabel(u'Output File', self) self._filenameLineEdit = QtGui.QLineEdit(self) chooseFileButtonIcon = QtGui.QIcon( QtGui.QPixmap(':/icons/document-save-as.png')) self._chooseFileAction = QtGui.QAction(self) self._chooseFileAction.setIcon(chooseFileButtonIcon) self._chooseFileAction.triggered.connect(self._createFile) self._chooseFileButton = QtGui.QToolButton(self) self._chooseFileButton.setDefaultAction(self._chooseFileAction) layout.addWidget(self._filenameLabel, 0, 0) layout.addWidget(self._filenameLineEdit, 0, 1, 1, 2) layout.addWidget(self._chooseFileButton, 0, 3) self._encodingLabel = QtGui.QLabel(u'File Encoding', self) encoding_names = map(lambda x: x.upper(), sorted(list(set(_encodings.viewvalues())))) self._encodingComboBox = QtGui.QComboBox(self) self._encodingComboBox.addItems(encoding_names) self._idx = encoding_names.index('UTF_8') self._encodingComboBox.setCurrentIndex(self._idx) #self._encodingComboBox.activated.connect(self._updateEncoding) layout.addWidget(self._encodingLabel, 1, 0) layout.addWidget(self._encodingComboBox, 1, 1, 1, 1) self._hasHeaderLabel = QtGui.QLabel(u'Header Available?', self) self._headerCheckBox = QtGui.QCheckBox(self) #self._headerCheckBox.toggled.connect(self._updateHeader) layout.addWidget(self._hasHeaderLabel, 2, 0) layout.addWidget(self._headerCheckBox, 2, 1) self._delimiterLabel = QtGui.QLabel(u'Column Delimiter', self) self._delimiterBox = DelimiterSelectionWidget(self) layout.addWidget(self._delimiterLabel, 3, 0) layout.addWidget(self._delimiterBox, 3, 1, 1, 3) self._exportButton = QtGui.QPushButton(u'Export Data', self) self._cancelButton = QtGui.QPushButton(u'Cancel', self) self._buttonBox = QtGui.QDialogButtonBox(self) self._buttonBox.addButton(self._exportButton, QtGui.QDialogButtonBox.AcceptRole) self._buttonBox.addButton(self._cancelButton, QtGui.QDialogButtonBox.RejectRole) self._buttonBox.accepted.connect(self.accepted) self._buttonBox.rejected.connect(self.rejected) layout.addWidget(self._buttonBox, 5, 2, 1, 2) self._exportButton.setDefault(False) self._filenameLineEdit.setFocus() self._statusBar = QtGui.QStatusBar(self) self._statusBar.setSizeGripEnabled(False) layout.addWidget(self._statusBar, 4, 0, 1, 4) self.setLayout(layout)
def _showMessageBox(text): errorbox = QtGui.QMessageBox() errorbox.setText(text) errorbox.exec_()
errmsg = u'{0}: \n{1}'.format(excType, excValueStr) sections = [ u'\n', separator, timeString, separator, errmsg, separator, tbinfo ] msg = u'\n'.join(sections) try: f = codecs.open(logFile, "a+", encoding='utf-8') f.write(msg) f.close() except IOError, e: msgbox(u"unable to write to {0}".format(logFile), u"Writing error") # always show an error message try: if not _isQAppRunning(): app = QtGui.QApplication([]) _showMessageBox(unicode(notice) + unicode(msg)) except: msgbox(unicode(notice) + unicode(msg), u"Error") def _isQAppRunning(): if QtGui.QApplication.instance() is None: return False else: return True def _showMessageBox(text): errorbox = QtGui.QMessageBox() errorbox.setText(text)
def goToColumn(self): print "go to column 7" index = self.dataTableView.view().model().index(7, 0) self.dataTableView.view().setCurrentIndex(index) def changeColumnValue(self, columnName, index, dtype): print "failed to change", columnName, "to", dtype print index.data(), index.isValid() self.dataTableView.view().setCurrentIndex(index) def setFilter(self): #filterIndex = eval(self.lineEditFilterCondition.text()) search = DataSearch("Test", self.lineEditFilterCondition.text()) self.dataTableView.view().model().setFilter(search) #raise NotImplementedError def clearFilter(self): self.dataTableView.view().model().clearFilter() if __name__ == '__main__': app = QtGui.QApplication(sys.argv) widget = TestWidget() widget.show() widget.setDataFrame(getCsvData()) #widget.setDataFrame( getRandomData(2, 2) ) app.exec_()
def __init__(self, parent=None): super(TestWidget, self).__init__(parent) self.resize(1680, 756) self.move(0, 0) self.df = pandas.DataFrame() self.dataModel = None # init the data view's self.dataTableView = DataTableWidget(self) # self.dataTableView.setSortingEnabled(True) # self.dataTableView.setAlternatingRowColors(True) self.dataListView = QtGui.QListView(self) self.dataListView.setAlternatingRowColors(True) self.dataComboBox = QtGui.QComboBox(self) # make combobox to choose the model column for dataComboBox and dataListView self.chooseColumnComboBox = QtGui.QComboBox(self) self.buttonCsvData = QtGui.QPushButton("load csv data") self.buttonRandomData = QtGui.QPushButton("load random data") importDialog = CSVImportDialog(self) importDialog.load.connect(self.updateModel) self.buttonCsvData.clicked.connect(lambda: importDialog.show()) self.buttonRandomData.clicked.connect( lambda: self.setDataFrame(getRandomData(rows=100, columns=100))) self.exportDialog = CSVExportDialog(self) self.buttonCSVExport = QtGui.QPushButton("export to csv") self.buttonCSVExport.clicked.connect(self._exportModel) self.buttonLayout = QtGui.QHBoxLayout() self.buttonLayout.addWidget(self.buttonCsvData) self.buttonLayout.addWidget(self.buttonCSVExport) self.buttonLayout.addWidget(self.buttonRandomData) self.mainLayout = QtGui.QVBoxLayout() self.setLayout(self.mainLayout) self.mainLayout.addLayout(self.buttonLayout) self.mainLayout.addWidget(self.dataTableView) self.spinbox = QtGui.QSpinBox() self.mainLayout.addWidget(self.spinbox) self.spinbox.setMaximum(99999999999) self.spinbox.setValue(99999999999) self.rightLayout = QtGui.QVBoxLayout() self.chooseColumLayout = QtGui.QHBoxLayout() self.mainLayout.addLayout(self.rightLayout) self.rightLayout.addLayout(self.chooseColumLayout) self.chooseColumLayout.addWidget(QtGui.QLabel("Choose column:")) self.chooseColumLayout.addWidget(self.chooseColumnComboBox) self.rightLayout.addWidget(self.dataListView) self.rightLayout.addWidget(self.dataComboBox) self.tableViewColumnDtypes = QtGui.QTableView(self) self.rightLayout.addWidget(QtGui.QLabel('dtypes')) self.rightLayout.addWidget(self.tableViewColumnDtypes) self.buttonGoToColumn = QtGui.QPushButton("go to column") self.rightLayout.addWidget(self.buttonGoToColumn) self.buttonGoToColumn.clicked.connect(self.goToColumn) self.buttonSetFilter = QtGui.QPushButton("set filter") self.rightLayout.addWidget(self.buttonSetFilter) self.buttonSetFilter.clicked.connect(self.setFilter) self.buttonClearFilter = QtGui.QPushButton("clear filter") self.rightLayout.addWidget(self.buttonClearFilter) self.buttonClearFilter.clicked.connect(self.clearFilter) self.lineEditFilterCondition = QtGui.QLineEdit("freeSearch('am')") self.rightLayout.addWidget(self.lineEditFilterCondition) self.chooseColumnComboBox.currentIndexChanged.connect( self.setModelColumn) self.dataListView.mouseReleaseEvent = self.mouseReleaseEvent self.dropLineEdit = DropLineEdit("drop data from table here", self) self.rightLayout.addWidget(self.dropLineEdit) self.dropWidget = ComplexDropWidget(self) self.dropWidget.dropRecieved.connect(self.processDataDrops) self.rightLayout.addWidget(self.dropWidget)