mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-08-13 10:04:13 +02:00
Commit font/color edits immediately instead of waiting for an unrelated click
plc-user on PR #693: the crash is fixed, but the color/font field and
the on-diagram text no longer update until you leave the properties
list and click in the diagram -- previously it updated as soon as you
clicked OK.
That's a side effect of the crash fix itself. The old, crashing code
returned a *live* QColorDialog as the item view's editor; clicking its
OK button called accept()/hide() on it, and hiding the active editor
happens to trip the base delegate's own focus-lost commit path -- so
the value applied immediately, racily, as a side effect of the same
mechanism that crashed on Enter. The fix (commit 4bd9b6b21) replaced
that with running the dialog synchronously inside createEditor() and
returning an inert placeholder with the result stashed in a property.
Correct for the crash, but it also removed that accidental commit
trigger: the placeholder never had focus to lose, so nothing tells
the view to read the value back until some unrelated interaction
(clicking away) incidentally triggers it.
Fix: explicitly emit commitData()/closeEditor() for the resolved
editor, deferred via QTimer::singleShot(0, ...) since the view only
registers createEditor()'s return value as "the active editor" after
createEditor() itself returns -- emitting synchronously, before
returning, would target a widget the view doesn't know about yet.
Applied to both font and color, since both share the exact same
"resolve synchronously in createEditor(), return an inert
placeholder" shape and thus the exact same gap; font just hadn't been
reported.
Verified with the same standalone harness from the crash fix (real
QTreeView + DynamicTextItemDelegate + QAbstractItemView::edit()),
this time deliberately *not* sending the synthetic Enter keypress the
crash-fix verification needed: clicks the dialog's real OK button,
lets the event loop run, and confirms the picked color lands in the
model on its own. Also reconfirmed the crash fix itself still holds
(clean exit, no synthetic-Enter needed either way now) and did a full
Release build (504/504) with no new warnings.
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <QStandardItem>
|
#include <QStandardItem>
|
||||||
|
#include <QTimer>
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
|
|
||||||
static int src_txt_row = 0;
|
static int src_txt_row = 0;
|
||||||
@@ -1595,6 +1596,15 @@ DynamicTextItemDelegate::DynamicTextItemDelegate(QObject *parent) :
|
|||||||
QStyledItemDelegate(parent)
|
QStyledItemDelegate(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void DynamicTextItemDelegate::commitAndCloseDeferred(QWidget *editor) const
|
||||||
|
{
|
||||||
|
auto *self = const_cast<DynamicTextItemDelegate *>(this);
|
||||||
|
QTimer::singleShot(0, self, [self, editor]() {
|
||||||
|
emit self->commitData(editor);
|
||||||
|
emit self->closeEditor(editor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *DynamicTextItemDelegate::createEditor(
|
QWidget *DynamicTextItemDelegate::createEditor(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const QStyleOptionViewItem &option,
|
const QStyleOptionViewItem &option,
|
||||||
@@ -1682,6 +1692,7 @@ QWidget *DynamicTextItemDelegate::createEditor(
|
|||||||
w->setProperty("ok", ok);
|
w->setProperty("ok", ok);
|
||||||
}
|
}
|
||||||
w->setObjectName("font_dialog");
|
w->setObjectName("font_dialog");
|
||||||
|
commitAndCloseDeferred(w);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
case DynamicElementTextModel::color:
|
case DynamicElementTextModel::color:
|
||||||
@@ -1716,6 +1727,7 @@ QWidget *DynamicTextItemDelegate::createEditor(
|
|||||||
w->setProperty("ok", true);
|
w->setProperty("ok", true);
|
||||||
}
|
}
|
||||||
w->setObjectName("color_dialog");
|
w->setObjectName("color_dialog");
|
||||||
|
commitAndCloseDeferred(w);
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
case DynamicElementTextModel::pos:
|
case DynamicElementTextModel::pos:
|
||||||
|
|||||||
@@ -155,6 +155,21 @@ class DynamicTextItemDelegate : public QStyledItemDelegate
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList availableInfo(DynamicElementTextItem *deti) const;
|
QStringList availableInfo(DynamicElementTextItem *deti) const;
|
||||||
|
/**
|
||||||
|
@brief commitAndCloseDeferred
|
||||||
|
Schedule commitData()/closeEditor() for @a editor on the next
|
||||||
|
event loop iteration. For editors resolved synchronously inside
|
||||||
|
createEditor() (font/color, both run their picker dialog before
|
||||||
|
returning) there is no user interaction left to drive the base
|
||||||
|
QStyledItemDelegate::eventFilter()'s usual Enter/focus-out commit
|
||||||
|
path, so without this the value sits picked-but-uncommitted
|
||||||
|
until something unrelated (e.g. clicking elsewhere) happens to
|
||||||
|
trigger it. Deferred rather than called immediately: the view
|
||||||
|
only registers the widget createEditor() returns as "the active
|
||||||
|
editor" *after* createEditor() itself returns, so emitting here
|
||||||
|
would target an editor the view doesn't know about yet.
|
||||||
|
*/
|
||||||
|
void commitAndCloseDeferred(QWidget *editor) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DYNAMICELEMENTTEXTMODEL_H
|
#endif // DYNAMICELEMENTTEXTMODEL_H
|
||||||
|
|||||||
Reference in New Issue
Block a user