Improve reliability of validation error tooltips in UI

Enhance validation error tooltip handling by introducing a 100 ms delay before display to prevent premature dismissal from key events. Ensure tooltips are shown at the correct widget position and only when visible. Also, improve removal of error icons and support for composite editor widgets. These changes make error feedback more consistent and user-friendly.
This commit is contained in:
Magne Sjaastad committed 2026-02-16 16:54:22 +01:00
1 parent ba4752e005
commit 945dd574bf
1 file changed
+34 -1
@@ -48,6 +48,8 @@
#include <QLineEdit>
#include <QMenu>
#include <QStyle>
#include <QTimer>
#include <QToolTip>
namespace caf
{
@@ -338,8 +340,13 @@ void PdmUiFieldEditorHandle::applyValidationStyling( QWidget* widget, const QStr
// Valid - remove error icon if present
if ( m_validationErrorAction )
{
widget->removeAction( m_validationErrorAction );
if ( auto* parentWidget = qobject_cast<QWidget*>( m_validationErrorAction->parent() ) )
{
parentWidget->removeAction( m_validationErrorAction );
}
delete m_validationErrorAction;
m_validationErrorAction = nullptr;
QToolTip::hideText();
}
}
else
@@ -353,6 +360,11 @@ void PdmUiFieldEditorHandle::applyValidationStyling( QWidget* widget, const QStr
// For QLineEdit, use TrailingPosition to show icon inside the widget
QLineEdit* lineEdit = qobject_cast<QLineEdit*>( widget );
if ( !lineEdit )
{
// Search for a QLineEdit child in composite editor widgets (e.g. checkbox + line edit)
lineEdit = widget->findChild<QLineEdit*>();
}
if ( lineEdit )
{
m_validationErrorAction = lineEdit->addAction( warningIcon, QLineEdit::TrailingPosition );
@@ -363,6 +375,27 @@ void PdmUiFieldEditorHandle::applyValidationStyling( QWidget* widget, const QStr
widget->addAction( m_validationErrorAction );
}
m_validationErrorAction->setToolTip( errorMessage );
// Defer tooltip display until after all UI updates and pending key events are processed.
// A 100 ms delay is used because Qt dismisses tooltips on any key event. When the user
// presses Enter, both a key press and key release event are generated. A 0 ms delay would
// show the tooltip between these events, and the key release would immediately dismiss it.
QWidget* tooltipWidget = lineEdit ? static_cast<QWidget*>( lineEdit ) : widget;
if ( tooltipWidget->isVisible() )
{
QPointer<QWidget> safeWidget( tooltipWidget );
QString msg = errorMessage;
QTimer::singleShot( 100,
tooltipWidget,
[safeWidget, msg]()
{
if ( safeWidget )
{
QPoint pos = safeWidget->mapToGlobal( QPoint( safeWidget->width(), 0 ) );
QToolTip::showText( pos, msg, safeWidget );
}
} );
}
}
else
{