PDA

View Full Version : Crash using custom ElidedLabel class in Qt5



jiveaxe
23rd December 2013, 14:04
Hi, I'm porting my application to Qt5. In the project I'm using a custom QLabel providing text elision (http://gedgedev.blogspot.it/2010/12/elided-labels-in-qt.html). While in Qt4 it works fine, in Qt5 is causing a crash:

http://paste.opensuse.org/91142495

This is the code of the class:

ElidedLabel.h

class ElidedLabel : public QLabel
{
Q_OBJECT

public:
explicit ElidedLabel(QWidget* parent = 0, Qt::WindowFlags f = 0);
explicit ElidedLabel(const QString& text, QWidget* parent = 0, Qt::WindowFlags f = 0);
explicit ElidedLabel(const QString &txt, Qt::TextElideMode elideMode = Qt::ElideRight, QWidget * parent = 0, Qt::WindowFlags f = 0);

//! Set the elide mode used for displaying text.
void setElideMode(Qt::TextElideMode elideMode) {
elideMode_ = elideMode;
updateGeometry();
}

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

// QLabel overrides
void setText(const QString &);

protected:
virtual void paintEvent(QPaintEvent* );
virtual void resizeEvent(QResizeEvent* );

//! Cache the elided text so as to not recompute it every paint event
void cacheElidedText(int w);

private:
Qt::TextElideMode elideMode_;
QString cachedElidedText_;
};

ElidedLabel.cpp

ElidedLabel::ElidedLabel(QWidget* parent, Qt::WindowFlags f):
QLabel(parent, f),
elideMode_(Qt::ElideRight)
{
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
}

ElidedLabel::ElidedLabel(const QString& text, QWidget* parent, Qt::WindowFlags f):
QLabel(text, parent, f),
elideMode_(Qt::ElideRight)
{
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
}

ElidedLabel::ElidedLabel(const QString& text, Qt::TextElideMode elideMode, QWidget* parent, Qt::WindowFlags f) :
QLabel(text, parent, f),
elideMode_(elideMode)
{
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
}

void ElidedLabel::setText(const QString& text)
{
QLabel::setText(text);
cacheElidedText(geometry().width());
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred);
}

void ElidedLabel::cacheElidedText(int w)
{
cachedElidedText_ = fontMetrics().elidedText(text(), elideMode_, w, Qt::TextShowMnemonic);
}

void ElidedLabel::paintEvent(QPaintEvent* e)
{
if(elideMode_ == Qt::ElideNone) {
QLabel::paintEvent(e);
} else {
QPainter p(this);
p.drawText(0, 0,
geometry().width(),
geometry().height(),
alignment(),
cachedElidedText_);
}
}

void ElidedLabel::resizeEvent(QResizeEvent* e)
{
QLabel::resizeEvent(e);
cacheElidedText(e->size().width());
}

Demoting widgets to plain QLabel solves the issue. I dunno if it is a bug in Qt5 or anything changed in the api, though the project compiles without warnings.

Any idea?

Very thanks.

anda_skoa
24th December 2013, 13:49
The code looks OK as far as I can tell, i.e. I see no reason why this wouldn't also work on Qt5.

The crash seems to be in QPainter's constructor, which is very strange.
Often that means that the problem is elsewhere, e.g. that the crash is a result of memory corruption, etc.

You could try to install the debug symbols for Qt5 and see if the backtrace gets more interesting details.

Btw, just to make sure: you are aware that QLabel::setText() is not virtual, right?

Cheers,
_