The problem
There unfortunately is no short and simple solution for this. There's a Qt feature request about this (see QTBUG-5370), but it's pending for 13 (!) years now, so it probably will never be implemented.
So we have to implement this on our own. The clean way is to handle the resizeEvent
within a custom QRadioButton
subclass in order to perform the necessary line wrapping there. In addition to that, you must also use setSizePolicy
and override the minimumSizeHint
of the radio button.
The complete implementation of a LineWrappedRadioButton
is given below.
LineWrappedRadioButton.h
#include <QRadioButton>
class LineWrappedRadioButton : public QRadioButton {
Q_OBJECT
private:
void wrapLines(int width);
protected:
virtual void resizeEvent(QResizeEvent *event);
public:
LineWrappedRadioButton(QWidget *parent = nullptr) : LineWrappedRadioButton(QString(), parent) { }
LineWrappedRadioButton(const QString &text, QWidget *parent = nullptr);
virtual QSize minimumSizeHint() const { return QSize(QRadioButton().minimumSizeHint().width(), sizeHint().height()); }
};
LineWrappedRadioButton.cpp
#include "LineWrappedRadioButton.h"
#include <QRadioButton>
#include <QResizeEvent>
#include <QStyle>
void LineWrappedRadioButton::wrapLines(int width) {
QString word, line, result;
for (QChar c : text().replace('\n', ' ') + ' ') {
word += c;
if (c.isSpace()) {
if (!line.isEmpty() && fontMetrics().width(line + word.trimmed()) > width) {
result += line.trimmed() + '\n';
line = word;
} else {
line += word;
}
word.clear();
}
}
result += line.trimmed();
setText(result.trimmed());
}
void LineWrappedRadioButton::resizeEvent(QResizeEvent *event) {
int controlElementWidth = sizeHint().width() - style()->itemTextRect(fontMetrics(), QRect(), Qt::TextShowMnemonic, false, text()).width();
wrapLines(event->size().width() - controlElementWidth);
QRadioButton::resizeEvent(event);
}
LineWrappedRadioButton::LineWrappedRadioButton(const QString &text, QWidget *parent) : QRadioButton(text, parent) {
QSizePolicy policy = sizePolicy();
policy.setHorizontalPolicy(QSizePolicy::Preferred);
setSizePolicy(policy);
updateGeometry();
}
Use it like this
int main(int argc, char **argv) {
QApplication app(argc, argv);
LineWrappedRadioButton button("Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua.");
button.show();
return app.exec();
}
This will produce the following result:
