Qt Snippet: QPushButton with word wrap feature

Qt have two main classes to use as button widget, QPushButton and QToolButton. These classes made the job in a very good way but both miss the word wrap feature. If the button width is not enough for show the entire button text the string is cutted out on sides and this is not a good effect. Word wrap feature allow the control to automatically move part of the text in a new line for allow full view.

Unfortunately, as already said, the Qt button classes natively miss this feature but it can be added by simply use a bit of code. The first solution would be to develop a control delegate able to add this feature by manage the button's content as requested. However here will be proposed an alternative solution required minimal efforts. Basically is necessary to assign to the button a new layout with inside a QLabel control with set the WordWrap feature to true. The advantage of this solution will be to make some combination with text only and icon with text as following examples will show. The first example refer to a button with text only:

QHBoxLayout *pLayout = new QHBoxLayout();
QLabel *pTextLabel = new QLabel();

pTextLabel->setText("This is a very very very long text");
pTextLabel->setAlignment(Qt::AlignCenter);
pTextLabel->setWordWrap(true);
pTextLabel->setTextInteractionFlags(Qt::NoTextInteraction);
pTextLabel->setMouseTracking(false);
pTextLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

pLayout->addWidget(pTextLabel);
pLayout->setSpacing(0);
pLayout->setMargin(0);
pLayout->setContentsMargins(5, 5, 5, 5);

MyButton->setText("");
MyButton->setLayout(pLayout);

Just some notes about the code. The layer is applied "over" the original button text, this mean you have to "clean" the button text for avoid the double text of both button text and label text. You can make it by simply set the button text string to empty using MyButton->setText(""). The QLabel control have an internal management of mouse events and this will "interpose" with the button click "functionality". For avoid such problem you need to disable the QLabel mouse and text interaction as showed. Second example will create a button with icon on the left side and text on other side. Please note that using this way you can make some combinations regarding the text label by set the text with left or centered alignment:

QHBoxLayout *pLayout = new QHBoxLayout();
QLabel *pIconLabel = new QLabel();
QLabel *pTextLabel = new QLabel();

pIconLabel->setPixmap(QPixmap(":/Img/qt_logo_icon.png"));
pIconLabel->setAlignment(Qt::AlignCenter);
pIconLabel->setMouseTracking(false);
pIconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

pTextLabel->setText("This is a very very very long text");
pTextLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
pTextLabel->setWordWrap(true);
pTextLabel->setTextInteractionFlags(Qt::NoTextInteraction);
pTextLabel->setMouseTracking(false);
pTextLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

pLayout->addWidget(pIconLabel);
pLayout->addWidget(pTextLabel);
pLayout->setSpacing(20);
pLayout->setMargin(0);
pLayout->setContentsMargins(5, 5, 5, 5);

MyButton->setText("");
MyButton->setLayout(pLayout);

Next example is similar to the previous but modify the layout for set the icon on top of the text. Please note that also for QLabel containing the icon the mouse text interaction has been disabled. Same advises for the combination about the label text alignment:
 
QVBoxLayout *pLayout = new QVBoxLayout();
QLabel *pIconLabel = new QLabel();
QLabel *pTextLabel = new QLabel();

pIconLabel->setPixmap(QPixmap(":/Img/qt_logo_icon.png"));
pIconLabel->setAlignment(Qt::AlignCenter);
pIconLabel->setMouseTracking(false);
pIconLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

pTextLabel->setText("This is a very very very long text");
pTextLabel->setAlignment(Qt::AlignCenter);
pTextLabel->setWordWrap(true);
pTextLabel->setTextInteractionFlags(Qt::NoTextInteraction);
pTextLabel->setMouseTracking(false);
pTextLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

pLayout->addWidget(pIconLabel);
pLayout->addWidget(pTextLabel);
pLayout->setSpacing(5);
pLayout->setMargin(0);
pLayout->setContentsMargins(5, 5, 5, 5);

MyButton->setText("");
MyButton->setLayout(pLayout);

The result of the examples is showed below:

Comments

Popular posts from this blog

Access GPIO from Linux user space

Android: adb push and read-only file system error

Tree in SQL database: The Nested Set Model