PDA

View Full Version : Howto get font of widget set by stylesheet



swaczin
27th June 2013, 10:01
Hi,

I want to get the font of a QWidget which is set by a stylesheet. The font() method always returns the global system font or the font set by setFont, but not the font which is set by setStyleSheet() and is used for painting in the widget. I need the font to do some calculations based on the fontsize.

Example code


FontTest::FontTest(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);

QTextEdit *edit = new QTextEdit(this);
setCentralWidget(edit);
edit->setStyleSheet("font-family: Arial;font-style: normal;font-size: 12pt;font-weight: bold;");
edit->setPlainText("Hello World");
qDebug() << "Font: " << edit->font().family() << edit->font().pointSize();
}

Painting is done with Arial, 12pt but qDebug() prints "Font: "MS Shell Dlg 2" 8 "

This is just a small example. In real life I have no knowledge about the font of the stylesheet because it comes from a qss file supplied at runtime and is set at application level.

I use Qt 4.8.1 under Win7

Thanks for any help

Helmut

sonulohani
27th June 2013, 13:34
You have to specify the element name like this:-


edit->setStyleSheet("QTextEdit{font-family: Arial;font-style: normal;font-size: 12pt;font-weight: bold;};");

swaczin
28th June 2013, 08:57
Thanks for the answer but that's not the problem.


qDebug() << "Font: " << edit->font().family() << edit->font().pointSize();

still prints "Font: "MS Shell Dlg 2" 8 ".

Lykurg
28th June 2013, 17:27
Just a guess, maybe the font is not set before the edit shows up. So just for checking. Move the qDebug in a custom slot and call it after the window has shown up. (E.g. use QTimer::singleShot() for that)

swaczin
8th July 2013, 11:42
Yes, I get the font after the edit is shown.
Thanks!

Kryzon
30th September 2015, 23:11
Warning: resurrected thread.

- - - - -

I just faced the same problem. I wanted to point out that instead of using QTimer::singleShot, you can simply call ensurePolished() (http://doc.qt.io/qt-5/qwidget.html#ensurePolished) right before querying any elements of the widget style that are set by the custom style sheet, like a custom font.

Like Lykurg guessed, it's exactly what happens the first time the widget is shown, it is polished.

Additionally, if you're interested in setting a 'minimum width' for a QLineEdit so that it always fits the placeholder text, you can use the following.
Subclass QLineEdit and declare a public function 'void setPlaceholderText( const QString& placeholder ).' This will shadow the original function from QLineEdit.
Then the code for the shadowing function is:

#include <QStyleOptionFrameV2>

void SubclassedQLineEdit::setPlaceholderText( const QString& placeholder )
{
if ( placeholder.isEmpty() )
return;

QLineEdit::setPlaceholderText( placeholder ); // Original function.

// Set a minimum size if the widget has valid placeholder text, so
// the placeholder text isn't truncated at the end.

ensurePolished(); // Updates the widget from the default font to the style-sheet font.

QStyleOptionFrameV2 frame;
initStyleOption( &frame );
const QSize contentsSize( fontMetrics().width( text ), fontMetrics().height() );
const int width = style()->sizeFromContents( QStyle::CT_LineEdit, &frame, contentsSize, this ).width();

setMinimumWidth( width );
}There's always some empty space left, but the line edit is guaranteed to display all the placeholder text without truncating it (as in, "placehold...").