Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to gracefully AlignHCenter QLineEdit text with clearButtonEnabled?



  • Hello.
    I'm developing a cross-platform desktop application with QtWidgets.
    I implemented a QLineEdit with horizontally centered text and clearButtonEnabled property set to true. The thing is that the position of displayed text center depends on whether the clearButton is visible i.e. whether some text is present. I need the center of the text and the corresponding cursor position to depend only on QLineEdit frame borders and I don't want it to move when clearButton changes its visibility.
    How should I achieve that?

    • 1st idea. I could switch between padding-left: <some>px when the button is visible and padding-left: 0px when it's not, but I'm not sure about how to calculate the proper size of button (hence, the padding) for every target platform.
    • 2nd idea. I tried to subclass QStyle and reimplement subElementRect for QStyle::SE_LineEditContents, but it didn't help.


  • After a couple hours of browsing Qt sources I finally found my solution:

    SmartLineEdit::SmartLineEdit(QWidget* parent) : QLineEdit(parent)
    {
        ...
        _button = findChild<QToolButton*>();
        _button->installEventFilter(this);
        auto iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
        auto margin = iconSize / 4;
        auto widgetWidth = iconSize + 6;
        _textMargin = margin+widgetWidth;
    }
    
    bool SmartLineEdit::eventFilter(QObject *watched, QEvent *event)
    {
        if (watched == _button)
        {
            if (event->type() == QEvent::Show)
                setTextMargins(_textMargin, 0, 0, 0);
            if (event->type() == QEvent::Hide)
                setTextMargins(0, 0, 0, 0);
        }
        return false;
    }
    

    Event filter is needed because ClearButton doesn't appear/disappear immediately, it takes some time to perform its animation.



  • QLineEdit horizontal size will increase when clear button is enabled. Is it an option to align the text to the left? If yes, the problem is gone. You can add some padding if your prefer.



  • After a couple hours of browsing Qt sources I finally found my solution:

    SmartLineEdit::SmartLineEdit(QWidget* parent) : QLineEdit(parent)
    {
        ...
        _button = findChild<QToolButton*>();
        _button->installEventFilter(this);
        auto iconSize = style()->pixelMetric(QStyle::PM_SmallIconSize, 0, this);
        auto margin = iconSize / 4;
        auto widgetWidth = iconSize + 6;
        _textMargin = margin+widgetWidth;
    }
    
    bool SmartLineEdit::eventFilter(QObject *watched, QEvent *event)
    {
        if (watched == _button)
        {
            if (event->type() == QEvent::Show)
                setTextMargins(_textMargin, 0, 0, 0);
            if (event->type() == QEvent::Hide)
                setTextMargins(0, 0, 0, 0);
        }
        return false;
    }
    

    Event filter is needed because ClearButton doesn't appear/disappear immediately, it takes some time to perform its animation.


Log in to reply