How to create a vertical (rotated) button in Qt with C++

939 views c++
-3

I'd like to create a vertical button in Qt (using C++, not Python), with text rotated 90º either clockwise or counterclockwise. It doesn't seem to be possible with a standard QPushButton.

How could I do it?

answered question

1 Answer

0

In order to create a vertical button in Qt, you can subclass QPushButton so that the dimensions reported by the widget are transposed, and also modify the drawing event to paint the button with the proper alignment.

Here's a class called OrientablePushButton that can be used as a drop-in replacement of the traditional QPushButton but also supports vertical orientation through the usage of setOrientation.

Aspect:

Vertical button

Sample usage:

auto anotherButton = new OrientablePushButton("Hello world world world world", this);
anotherButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
anotherButton->setOrientation(OrientablePushButton::VerticalTopToBottom);

Header file:

class OrientablePushButton : public QPushButton
{
    Q_OBJECT
public:
    enum Orientation {
        Horizontal,
        VerticalTopToBottom,
        VerticalBottomToTop
    };

    OrientablePushButton(QWidget * parent = nullptr);
    OrientablePushButton(const QString & text, QWidget *parent = nullptr);
    OrientablePushButton(const QIcon & icon, const QString & text, QWidget *parent = nullptr);

    QSize sizeHint() const;

    OrientablePushButton::Orientation orientation() const;
    void setOrientation(const OrientablePushButton::Orientation &orientation);

protected:
    void paintEvent(QPaintEvent *event);

private:
    Orientation mOrientation = Horizontal;
};

Source file:

#include <QPainter>
#include <QStyleOptionButton>
#include <QDebug>
#include <QStylePainter>

OrientablePushButton::OrientablePushButton(QWidget *parent)
    : QPushButton(parent)
{ }

OrientablePushButton::OrientablePushButton(const QString &text, QWidget *parent)
    : QPushButton(text, parent)
{ }

OrientablePushButton::OrientablePushButton(const QIcon &icon, const QString &text, QWidget *parent)
    : QPushButton(icon, text, parent)
{ }

QSize OrientablePushButton::sizeHint() const
{
    QSize sh = QPushButton::sizeHint();

    if (mOrientation != OrientablePushButton::Horizontal)
    {
        sh.transpose();
    }

    return sh;
}

void OrientablePushButton::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QStylePainter painter(this);
    QStyleOptionButton option;
    initStyleOption(&option);

    if (mOrientation == OrientablePushButton::VerticalTopToBottom)
    {
        painter.rotate(90);
        painter.translate(0, -1 * width());
        option.rect = option.rect.transposed();
    }

    else if (mOrientation == OrientablePushButton::VerticalBottomToTop)
    {
        painter.rotate(-90);
        painter.translate(-1 * height(), 0);
        option.rect = option.rect.transposed();
    }

    painter.drawControl(QStyle::CE_PushButton, option);
}

OrientablePushButton::Orientation OrientablePushButton::orientation() const
{
    return mOrientation;
}

void OrientablePushButton::setOrientation(const OrientablePushButton::Orientation &orientation)
{
    mOrientation = orientation;
}

posted this

Have an answer?

JD

Please login first before posting an answer.