Search code examples
c++qtrotationqt4

Rotate QLabel and keep its functionality/stylesheet


For a while now I am searching for an adequate method to rotate a QLabel - and most important to keep its functionality and stylesheets.

I've found a pretty interesting approach here: Vertical QLabel, or the equivalent?

First I was satisfied because it efficiently rotated the label. Unfortunately the Stylesheet I've added (using a bigger font and other color) was completely lost and the alignment is gone as well (myLabel_->setAlignment(Qt::AlignTop); has no effect).

I've read QPainter::drawStaticText would provide more functionality but for me it doesn't work at all (I'm using the same code as in the solution before mentioned, just with the difference:

QStaticText qs = "Test1";
painter.drawStaticText(0,0,qs);

)

Using deprecated HTML ("<b>...</b>") instead of Stylesheets is also no use... Same as returning to a regular QLabel and using modern transformation stylesheets (http://snook.ca/archives/html_and_css/css-text-rotation).

I'm pretty much running out of ideas now how I am able to keep the former properties of the QLabel and still be able to rotate it...


Solution

  • There's no easy way to do that.

    QStylePainter may help with the style:

    #include<QStylePainter>
    // ......
    void LabelWidget::paintEvent(QPaintEvent* event) {
        QStylePainter painter(this);
        painter.rotate(90);
        painter.drawText(0, 0, text());
    }
    

    This will draw text with properties defined by stylesheet, but this does not solve the alignment problem.


    If your drawStaticText code use rotate(90) and doesn't show any thing, it is beacuse the text is rotated around the top-left point and rotate(90) will move the text out of the widget(Try rotate(45), you will find part of the text is out of the widget). A simple solution is using QPainter::translate to move to the center.

    Here is my code that support alignment:

    #include<QStylePainter>
    // ......
    void LabelWidget::paintEvent(QPaintEvent* event) {
        QStylePainter painter(this);
    
        // rotate at center
        painter.translate(rect().center());
        painter.rotate(90);
        painter.translate(-rect().center());
    
        painter.drawText(rect(), alignment(), text());
    }
    

    To support more features like word-wrapping:

    #include<QStylePainter>
    #include<QTextOption>
    // ......
    void LabelWidget::paintEvent(QPaintEvent* event) {
        QStylePainter painter(this);
    
        // rotate at center
        painter.translate(rect().center());
        painter.rotate(90);
        painter.translate(-rect().center());
    
        QTextOption textOption;
        textOption.setAlignment(alignment());
        if (wordWrap()) {
            textOption.setWrapMode(QTextOption::WordWrap);
        } else {
            textOption.setWrapMode(QTextOption::NoWrap);
        }
        painter.drawText(rect(), text(), textOption);
    }
    

    You will have to add more features if you want other properties of the QLabel, there is no simple solution.

    PS: If you want use QStaticText , make it a member variable.

    The QStaticText class enables optimized drawing of text when the text and its layout is updated rarely.

    QStaticText provides a way to cache layout data for a block of text so that it can be drawn more efficiently than by using QPainter::drawText() in which the layout information is recalculated with every call.