user2652023
user2652023

Reputation: 207

Calculate max length of QLineEdit to suit its width

I created some QLineEdit, which have different sizes.

I want to set the max length of those to suit the width of them.

To be more specific: for example, with a width of 50, I will only allow to enter about 7 characters, because the size of each character is different.

How can I exactly calculate the maximum length needed?

Upvotes: 2

Views: 3193

Answers (2)

Nicolas Holthaus
Nicolas Holthaus

Reputation: 8313

You can set a limit based on the width of myLineEdit such that it will be able to fit all characters up to that limit by doing this:

#include <QFontMetrics>
#include <QLineEdit>

QLineEdit myLineEdit;

// get max character width of the line edit's font
int maxWidth = QFontMetrics(myLineEdit->font()).maxWidth();

// find the character limit based on the max width
int charlimit = myLineEdit.width() / maxWidth;

// set the character limit on the line edit
myLineEdit->setMaxLength(charlimit);

However, here are some reasons you probably don't want to in production code:

  1. Stylesheets - what happenes when your designer gives the edit a 14px border?
  2. Resizing - you'll have to adjust this on every resize, and I've found that in practice it's a very difficult thing to keep track of. It's not a useful feature if it breaks whenever the GUI gets resized.
  3. Content - the width of the line edit, especially one that a user can enter text into, is not logically related to the length of text the user may need to enter. This could become an arbitrary constraint that frustrates your users. No one likes horizontal scrolling, but sometimes there are use cases.

Upvotes: 2

Tomas
Tomas

Reputation: 2210

Use a QFontMetrics:

QFontMetrics fm(QApplication::font());  // You can use any font here.

int stringWidth = fm.width("Some string");

EDIT:

At first you have to know when your QLineEdit is resized. So you can either derive your own class and reimplement the resizeEvent() method, or you can use an event filter.

Then create a special validator:

class CLengthValidator : public  QValidator
{
public:
    CLenghtValidator(QObject* parent, const QFont & font) 
        :    QValidator(parent), m_maxw(0), m_fm(font)
    {}

    void setMaxValidWidth(int width)
    {
        m_maxw = width;
    }

    State validate(QString & input, int & pos) const override
    {
        int stringWidth = m_fm.width(input);
        if (stringWidth <= m_maxw)
            return Acceptable;
        else
            return Invalid;
    }

private:
    int m_maxw;
    QFontMetrics m_fm;
}

Set the validator to your line edit (using the QLineEdit::setValidator() method):

lineEdit->setValidator(new CLengthValidator(lineEdit, lineEdit->font()));

Now, every time the line edit is resized, you have to call CLengthValidator::setMaxValidWidth() method with the current line edit width as a parameter. You will do that in your reimplemented QLineEdit::resizeEvent() method or in your event filter.

This way you will get a line edit accepting only string which width is not greater than width of actual line edit.

Upvotes: 2

Related Questions