Close the editor widget of QStyledItemDelegate correctly...
-
Hi,
What do you want to do with that information ?
-
That's what should happen by default when your editor loses focus.
How did you implement it ?
-
@SGaist That's what should happen by default when your editor loses focus.
Yes I found the problem -> when I click and focus into the textEdit, and then loses focus on it, Editor does not closed...like this:
How did you implement it ?
/** * @brief The itemTextEditStyle class * Create a textEdit with advanced settings like the spell checker, HTML... */ class itemTextEditStyle : public QStyledItemDelegate { Q_OBJECT public: itemTextEditStyle(QLocale &lang, mDico *myDico, bool spellCheck, QObject *parent ) : QStyledItemDelegate(parent) { m_lang = lang; m_dico = myDico; m_spellCheck = spellCheck; mTableWidget = qobject_cast<QTableWidget *>(parent); } // Paint html with render void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem mOption = option; initStyleOption(&mOption, index); QStyle *style = mOption.widget? mOption.widget->style() : QApplication::style(); /// Painting item without text mOption.text = QString(); style->drawControl(QStyle::CE_ItemViewItem, &mOption, painter); /// Paint html QTextDocument HtmlTxt; QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &mOption); HtmlTxt.setHtml( index.data().toString() ); HtmlTxt.setTextWidth(option.rect.width()-20);// - width of Ico painter->save(); painter->translate(textRect.topLeft()); painter->setClipRect(textRect.translated(-textRect.topLeft())); HtmlTxt.drawContents(painter); painter->restore(); } // Create complex widget QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& style, const QModelIndex& index) const { Q_UNUSED(style);Q_UNUSED(index); QLocale lang = m_lang; McTextEditRich *mEditor = new McTextEditRich(lang, m_spellCheck, m_dico, parent); // Connection signal of keypressReturn of Editor MCTextEdit *txtEditor = mEditor->findChild<MCTextEdit*>("mTextEditRich"); connect(txtEditor,SIGNAL(keyPressReturn(const QString&, const int&)), this, SLOT(keyPressEvent(const QString&, const int&))); return mEditor; } // Set Data to the editor void setEditorData(QWidget *editor,const QModelIndex &index) const { MCTextEdit *txtEditor = editor->findChild<MCTextEdit*>("mTextEditRich"); if (txtEditor) { txtEditor->setHtml(index.data().toString()); return; } else QStyledItemDelegate::setEditorData(editor, index); } // Set Data into the model void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { MCTextEdit *txtEditor = editor->findChild<MCTextEdit*>("mTextEditRich"); if (txtEditor) { model->setData(index, txtEditor->toHtml()); return; } else QStyledItemDelegate::setModelData(editor, model, index); } private slots: // Set the height of row according to the editor void keyPressEvent(const QString& textContent, const int& widthEditor) { QTextDocument HtmlTxt; HtmlTxt.setHtml(textContent); HtmlTxt.setTextWidth(widthEditor); mTableWidget->setRowHeight(mTableWidget->currentRow(), int(HtmlTxt.size().height()) + 40); } private: QLocale m_lang; mDico *m_dico; bool m_spellCheck; QTableWidget *mTableWidget; };
An idea ? :(
-
Not knowing how MCTextEdit is implemented, I can't really comment.
Take a look a the Star Delegate Example. That might give you some additional clue.
-
@SGaist said in Close the editor widget of QStyledItemDelegate correctly...:
MCTextEdit
Your right, I have tried with simple QTextEdit, in my McTextEditRich QWidget, the result is the same...
I inspired me by the example "the Star Delegate Example." ;)I have install an eventFilter on editor to debug this,
// Install Event filter on mEditor debug mEditor->installEventFilter(const_cast<itemTextEditStyle*>(this)); ... bool eventFilter(QObject *object, QEvent *event) { if(qobject_cast<McTextEditRich*>(object)) { if((event->type() == QEvent::FocusAboutToChange) || (event->type() == QEvent::FocusOut)) qDebug() << "eventFilter " << event->type(); } return QStyledItemDelegate::eventFilter(object, event); }
And apparently the QEvent::Type(FocusOut) is emit if I enter in QTextedit...
When I enter in QTextedit : QEvent::Type(FocusAboutToChange) QEvent::Type(FocusOut)
And after when I focus on other widgets outsite of my editor, QEvent::Type(FocusOut) is not emit and editor stay open... like the gif above.
-
One thing you could try is to handle the leaveEvent and put the focus on the "whole editor".
-
@SGaist Nice!
I had tested with commitData() et closeEditor() but this crash sometime my app.So I finally keep the eventFilter function like this :
// Set focus on editor if leave Editor ! bool eventFilter(QObject *object, QEvent *event) { McTextEditRich *mEditor = qobject_cast<McTextEditRich*>(object); if(mEditor) { // if leave Editor if((event->type() == QEvent::Leave)){ // Set focus on editor to allow after, the emit of QEvent::Type(FocusOut) normally mEditor->setFocus(); return true; } } return QStyledItemDelegate::eventFilter(object, event); }
Thanks for your time @SGaist ;) ++
-
I had the same problem and for me, the cause was that my editor had a focus proxy set. This prevents that
FocusIn
,FocusOut
andFocusAboutToChange
events are delivered to the editor (they are delivered to the focus proxy instead). ButQStyledItemDelegate
relies on those events to commit the editor when it loses focus.To fix it, I installed an event filter on the focus proxy and used
QCoreApplication::sendEvent()
to forward the focus events to the editor:bool MyEditor::eventFilter( QObject* eventTarget, QEvent* event ) override { switch( event->type() ) { case QEvent::FocusIn: case QEvent::FocusOut: case QEvent::FocusAboutToChange: if( eventTarget == focusProxy() ) { // Forward focus events to editor because the QStyledItemDelegate relies on them QCoreApplication::sendEvent( this, event ); } break; default: break; } return BaseClass::eventFilter( eventTarget, event ); }