Elided Label: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
m (Point out that the current code contains bugs)
 
(8 intermediate revisions by 5 users not shown)
Line 1: Line 1:
Just call this function and you're good to go.
[[Category:Snippets::Misc]]
{{LangSwitch}}
{{Note|This code is problematic: setText() is called inside paintEvent(), which triggers another repaint, making the widget repainting forever!}}


<code><br />//! Set the elide mode used for displaying text.<br /> void setElideMode(Qt::TextElideMode elideMode) {<br /> elideMode_ = elideMode;<br /> updateGeometry();<br /> }<br /></code>
Make sure to set the horizontal size policy to minimum and just call this function and you're good to go:


<code>#ifndef ELIDEDLABEL_H<br />#define ELIDEDLABEL_H
<syntaxhighlight lang="c++">
// Set the elide mode used for displaying text.
void ElidedLabel::setElideMode(Qt::TextElideMode elideMode)
{
    m_elideMode = elideMode;
    m_cachedText.clear();
    update();
}
</syntaxhighlight>


#include &lt;QLabel&amp;gt;
<syntaxhighlight lang="c++">
#ifndef ELIDEDLABEL_H
#define ELIDEDLABEL_H


/*<br />MIT - Yash : Speedovation.com [ Picked from internet and modified. if owner needs to add or change license do let me know.]<br />*/
#include <QLabel>


class ElidedLabel : public QLabel {<br /> Q_OBJECT
// MIT - Yash : Speedovation.com [ Picked from internet and modified. if owner needs to add or change license do let me know.]


public:<br /> ElidedLabel(QWidget '''parent = 0, Qt::WindowFlags f = 0);<br /> ElidedLabel(const QString &amp;txt, QWidget''' parent = 0, Qt::WindowFlags f = 0);<br /> ElidedLabel(const QString &amp;txt,<br /> Qt::TextElideMode elideMode = Qt::ElideRight,<br /> QWidget * parent = 0,<br /> Qt::WindowFlags f = 0);
class ElidedLabel : public QLabel
{
    Q_OBJECT
public:
    using QLabel::QLabel;
    // Set the elide mode used for displaying text.
    void setElideMode(Qt::TextElideMode elideMode);
    // Get the elide mode currently used to display text.
    Qt::TextElideMode elideMode() const { return m_elideMode; }


public:<br /> //! Set the elide mode used for displaying text.<br /> void setElideMode(Qt::TextElideMode elideMode) {<br /> elideMode_ = elideMode;<br /> updateGeometry();<br /> }
protected:
    void paintEvent(QPaintEvent *e) override;
    void resizeEvent(QResizeEvent *e) override;


//! Get the elide mode currently used to display text.<br /> Qt::TextElideMode elideMode() const { return elideMode_; }
private:
    void updateCachedTexts();


public: // QLabel overrides<br /> void setText(const QString &amp;);
private:
    Qt::TextElideMode m_elideMode = Qt::ElideRight;
    QString m_cachedElidedText;
    QString m_cachedText;
};


protected: // QLabel overrides<br /> void paintEvent(QPaintEvent ''');<br /> void resizeEvent(QResizeEvent''');
#endif // ELIDEDLABEL_HPP
</syntaxhighlight>


protected:<br /> //! Cache the elided text so as to not recompute it every paint event<br /> void cacheElidedText(int w);
<syntaxhighlight lang="c++">
#include "ElidedLabel.h"


private:<br /> Qt::TextElideMode elideMode_;<br /> QString cachedElidedText;<br />};
#include <QPaintEvent>
#include <QResizeEvent>


#endif // ELIDEDLABEL_HPP<br /></code>
void ElidedLabel::setElideMode(Qt::TextElideMode elideMode)
{
    m_elideMode = elideMode;
    m_cachedText.clear();
    update();
}


<code>#include &quot;ElidedLabel.h&amp;quot;
void ElidedLabel::resizeEvent(QResizeEvent *e)
{
    QLabel::resizeEvent(e);
    m_cachedText.clear();
}


#include &lt;QDebug&amp;gt;<br />#include &lt;QPainter&amp;gt;<br />#include &lt;QResizeEvent&amp;gt;
void ElidedLabel::paintEvent(QPaintEvent *e)
{
    if (m_elideMode == Qt::ElideNone)
        return QLabel::paintEvent(e);


ElidedLabel::ElidedLabel(QWidget *parent, Qt::WindowFlags f)<br /> : QLabel(parent, f) , elideMode_(Qt::ElideRight)<br />{<br /> // setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);<br />}
    updateCachedTexts();
    QLabel::setText(m_cachedElidedText);
    QLabel::paintEvent(e);
    QLabel::setText(m_cachedText);
}


ElidedLabel::ElidedLabel(const QString &amp;txt, QWidget *parent, Qt::WindowFlags f)<br /> : QLabel(txt, parent, f) , elideMode_(Qt::ElideRight)<br />{<br />}
void ElidedLabel::updateCachedTexts()
 
{
ElidedLabel::ElidedLabel(const QString &amp;txt, Qt::TextElideMode elideMode,<br /> QWidget *parent, Qt::WindowFlags f) : QLabel(txt, parent, f)<br /> , elideMode_(elideMode)<br />{<br />}
    // setText() is not virtual ... :/
 
    const auto txt = text();
void ElidedLabel::setText(const QString &amp;txt) {<br /> QLabel::setText(txt);<br /> cacheElidedText(geometry().width());<br />}
    if (m_cachedText == txt)
 
        return;
void ElidedLabel::cacheElidedText(int w) {<br /> cachedElidedText = fontMetrics().elidedText(text(), elideMode_, w, Qt::TextShowMnemonic);<br />}
    m_cachedText = txt;
 
    const QFontMetrics fm(fontMetrics());
void ElidedLabel::resizeEvent(QResizeEvent *e) {<br /> QLabel::resizeEvent(e);<br /> cacheElidedText(e-&gt;size().width());<br />}
    m_cachedElidedText = fm.elidedText(text(),
 
                                      m_elideMode,
void ElidedLabel::paintEvent(QPaintEvent *e) {<br /> if(elideMode_ == Qt::ElideNone) {<br /> QLabel::paintEvent(e);<br /> } else {<br /> QPainter p(this);<br /> p.drawText(0, 0,<br /> geometry().width(),<br /> geometry().height(),<br /> alignment(),<br /> cachedElidedText);<br /> }<br />}
                                      width(),
 
                                      Qt::TextShowMnemonic);
</code>
    // make sure to show at least the first character
    if (!m_cachedText.isEmpty())
    {
      const QString showFirstCharacter = m_cachedText.at(0) + QStringLiteral("...");
      setMinimumWidth(fm.horizontalAdvance(showFirstCharacter) + 1);
    }
}
</syntaxhighlight>

Latest revision as of 09:04, 27 November 2025

En Ar Bg De El Es Fa Fi Fr Hi Hu It Ja Kn Ko Ms Nl Pl Pt Ru Sq Th Tr Uk Zh

  Note: This code is problematic: setText() is called inside paintEvent(), which triggers another repaint, making the widget repainting forever!

Make sure to set the horizontal size policy to minimum and just call this function and you're good to go:

// Set the elide mode used for displaying text.
void ElidedLabel::setElideMode(Qt::TextElideMode elideMode)
{
    m_elideMode = elideMode;
    m_cachedText.clear();
    update();
}
#ifndef ELIDEDLABEL_H
#define ELIDEDLABEL_H

#include <QLabel>

// MIT - Yash : Speedovation.com [ Picked from internet and modified. if owner needs to add or change license do let me know.]

class ElidedLabel : public QLabel 
{
    Q_OBJECT
public:
    using QLabel::QLabel;
    // Set the elide mode used for displaying text.
    void setElideMode(Qt::TextElideMode elideMode);
    // Get the elide mode currently used to display text.
    Qt::TextElideMode elideMode() const { return m_elideMode; }

protected:
    void paintEvent(QPaintEvent *e) override;
    void resizeEvent(QResizeEvent *e) override;

private:
    void updateCachedTexts();

private:
    Qt::TextElideMode m_elideMode = Qt::ElideRight;
    QString m_cachedElidedText;
    QString m_cachedText;
};

#endif // ELIDEDLABEL_HPP
#include "ElidedLabel.h"

#include <QPaintEvent>
#include <QResizeEvent>

void ElidedLabel::setElideMode(Qt::TextElideMode elideMode)
{
    m_elideMode = elideMode;
    m_cachedText.clear();
    update();
}

void ElidedLabel::resizeEvent(QResizeEvent *e)
{
    QLabel::resizeEvent(e);
    m_cachedText.clear();
}

void ElidedLabel::paintEvent(QPaintEvent *e)
{
    if (m_elideMode == Qt::ElideNone)
        return QLabel::paintEvent(e);

    updateCachedTexts();
    QLabel::setText(m_cachedElidedText);
    QLabel::paintEvent(e);
    QLabel::setText(m_cachedText);
}

void ElidedLabel::updateCachedTexts()
{
    // setText() is not virtual ... :/
    const auto txt = text();
    if (m_cachedText == txt)
        return;
    m_cachedText = txt;
    const QFontMetrics fm(fontMetrics());
    m_cachedElidedText = fm.elidedText(text(),
                                       m_elideMode,
                                       width(),
                                       Qt::TextShowMnemonic);
    // make sure to show at least the first character
    if (!m_cachedText.isEmpty())
    {
      const QString showFirstCharacter = m_cachedText.at(0) + QStringLiteral("...");
      setMinimumWidth(fm.horizontalAdvance(showFirstCharacter) + 1);
    }
}