Is there any way to determine if a QTableView
has an open editor in the current cell? I need to handle the following situation:
I see how to get the current item, and can get the delegate on that item, but I don't see any isEditMode()
property I was hoping to find.
Can someone point me in the right direction?
Just check whether the return value of
State QAbstractItemView::state () const
is
QTableView::EditingState
You can subclass QTableView
in order to be able to access the state()
function, which is unfortunately protected. However, I did not try that.
If you already have an QStyledItemDelegate
subclass, you can use it to track whether an editor is currently open. However, you can't just use setEditorData
/setModelData
, because setModelData
won't be called, when the user cancels editing. Instead, you can track the creation and destruction of the editor itself.
class MyItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
MyItemDelegate( QObject* parent = nullptr );
~MyItemDelegate();
QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
void setEditorData( QWidget* editor, const QModelIndex& index ) const;
void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;
bool isEditorOpen() const { return *m_editorCount > 0; }
protected:
int* m_editorCount;
protected slots:
void onEditorDestroyed( QObject* obj );
};
Implementation:
MyItemDelegate::MyItemDelegate( QObject* parent ) :
QStyledItemDelegate( parent )
{
m_editorCount = new int;
*m_editorCount = 0;
}
MyItemDelegate::~MyItemDelegate()
{
delete m_editorCount;
}
QWidget* MyItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
// create an editor, can be changed as needed
QWidget* editor = QStyledItemDelegate::createEditor( parent, option, index );
connect( editor, SIGNAL(destroyed(QObject*)), SLOT(onEditorDestroyed(QObject*)));
printf( "editor %p created\n", (void*) editor );
(*m_editorCount)++;
return editor;
}
void MyItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
...
}
void MyItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
...
}
void MyItemDelegate::onEditorDestroyed( QObject* obj )
{
printf( "editor %p destroyed\n", (void*) obj );
(*m_editorCount)--;
}
On some occasions, e.g. when moving to the next item in the tree using the cursor keys, Qt will create the new editor first and then destroy the old one. Hence, m_editorCount
must be an integer instead of a bool.
Unfortunately, createEditor()
is a const
function. Therefore, you cannot create an int
-member. Instead, create a pointer to an int
and use that.
If you know the index of the item being edited, you can call indexWidget()
and attempt to cast it. If it's valid, you not only know you're editing, but you also have your editor widget handy.
EditWidget *editWidget = qobject_cast<EditWidget*>(tableView->indexWidget(tableView->currentIndex()));
if(editWidget)
{
//yep, ur editing bro
}
Subclass your delegate so that it includes an accessor that tells you when it's editing:
void MyDelegate::setEditorData ( QWidget * editor, const QModelIndex & index ) const {
// _isEditing will have to be mutable because this method is const
_isEditing = true;
QStyledItemDelegate::setEditorData(editor, index);
}
void MyDelegate::setModelData ( QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const {
QStyledItemDelegate::setModelData(editor, model, index);
_isEditing = false;
}
bool MyDelegate::isEditing() const { return _isEditing; }
Then you can just check the delegate to see what's going on. Alternatively and/or if you don't like the mutable
, you can emit signals so you know what state the delegate is in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With