There are different ways to solve this. Creating a custom widget is one of them.
So, I have modified the Elided Label Example
according to your specifications:
- It supports one-line text only
- It lets you set the elide mode via
ElidedLabel::setElideMode
Here are the files:
ElidedLabel.h
#ifndef ELIDEDLABEL_H
#define ELIDEDLABEL_H
#include <QFrame>
class ElidedLabelPrivate;
class ElidedLabel : public QFrame
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QFlags<Qt::AlignmentFlag> alignment READ alignment
WRITE setAlignment NOTIFY alignmentChanged)
Q_PROPERTY(Qt::TextElideMode elideMode READ elideMode WRITE setElideMode
NOTIFY elideModeChanged)
public:
explicit ElidedLabel(QWidget *parent = nullptr);
explicit ElidedLabel(const QString &text, QWidget *parent = nullptr);
~ElidedLabel();
QString text() const;
void setText(const QString &str);
QFlags<Qt::AlignmentFlag> alignment() const;
void setAlignment(QFlags<Qt::AlignmentFlag> flags);
Qt::TextElideMode elideMode() const;
void setElideMode(Qt::TextElideMode mode);
protected:
void paintEvent(QPaintEvent *event) override;
private:
ElidedLabelPrivate *m_ptr;
signals:
void textChanged();
void alignmentChanged();
void elideModeChanged();
};
#endif // ELIDEDLABEL_H
ElidedLabel_p.h
#ifndef ELIDEDLABEL_P_H
#define ELIDEDLABEL_P_H
#include <Qt>
#include <QString>
class ElidedLabel;
class ElidedLabelPrivate {
Q_DISABLE_COPY(ElidedLabelPrivate)
explicit ElidedLabelPrivate();
QString text;
QFlags<Qt::AlignmentFlag> alignment;
Qt::TextElideMode elideMode;
friend class ElidedLabel;
};
#endif // ELIDEDLABEL_P_H
ElidedLabel.cpp
#include "ElidedLabel.h"
#include "ElidedLabel_p.h"
#include <QPaintEvent>
#include <QPainter>
ElidedLabel::ElidedLabel(QWidget *parent) :
QFrame(parent),
m_ptr(new ElidedLabelPrivate)
{
}
ElidedLabel::ElidedLabel(const QString &text, QWidget *parent) :
ElidedLabel(parent)
{
m_ptr->text = text;
}
ElidedLabel::~ElidedLabel()
{
delete m_ptr;
}
QString ElidedLabel::text() const
{
return m_ptr->text;
}
void ElidedLabel::setText(const QString &str)
{
m_ptr->text = str;
update();
emit textChanged();
}
QFlags<Qt::AlignmentFlag> ElidedLabel::alignment() const
{
return m_ptr->alignment;
}
void ElidedLabel::setAlignment(QFlags<Qt::AlignmentFlag> flags)
{
m_ptr->alignment = flags;
update();
emit alignmentChanged();
}
Qt::TextElideMode ElidedLabel::elideMode() const
{
return m_ptr->elideMode;
}
void ElidedLabel::setElideMode(Qt::TextElideMode mode)
{
m_ptr->elideMode = mode;
update();
emit elideModeChanged();
}
void ElidedLabel::paintEvent(QPaintEvent *event)
{
QFrame::paintEvent(event);
QPainter painter(this);
painter.setPen(QPalette().windowText().color());
painter.setClipRect(event->rect());
painter.setFont(font());
painter.drawText(contentsRect(), m_ptr->alignment | Qt::TextSingleLine,
painter.fontMetrics().elidedText(m_ptr->text,
m_ptr->elideMode,
contentsRect().width(),
1));
}
ElidedLabelPrivate::ElidedLabelPrivate() :
alignment(Qt::AlignLeft | Qt::AlignVCenter),
elideMode(Qt::ElideRight)
{
}
This is too much code, I know, and it might looks scary. However its usage is not that difficult. Just add the given files to your project and use it like any other widget.
Here is an example main.cpp
:
#include "ElidedLabel.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFont f = QGuiApplication::font();
f.setPointSize(11);
QGuiApplication::setFont(f);
ElidedLabel label;
label.setText(QObject::tr("Hello Elided World! We have a very very very"
" long one-line text here."));
label.setContentsMargins(10, 10, 10, 10);
label.setElideMode(Qt::ElideMiddle);
label.show();
label.resize(200, 100);
return a.exec();
}