Understanding Widget Promotion in Qt
Widget promotion transforms standard Qt controls into custom widgets. This technique allows developers to create tailored UI components by redefining existing Qt classes. Since all UI classes inherit from QWidget, they function as indepednent windows for design purposes. Custom widget creation is essential when built-in controls lack required functionality.
Implementation Example: Icon-Text Button
This example demonstrates creating a button with an icon above text by promoting QPushButton.
UI Design Approach
- Direct Composition: Place QLabel elements for icon and text inside a QPushButton
- Promoted Customization: Create a specialized class inheriting from QPushButton
Step-by-Step Customization
-
Promote in Designer
- Right-click QPushButton in Qt Designer
- Select "Promote to..."
- Specify custom class name
IconTextButton
-
Create Custom Class
class IconTextButton : public QPushButton {
Q_OBJECT
public:
explicit IconTextButton(QWidget* parent = nullptr);
void setButtonIcon(const QString& path);
void setButtonText(const QString& text);
private:
QLabel* iconLabel;
QLabel* textLabel;
};
- Implement Class Logic
IconTextButton::IconTextButton(QWidget* parent)
: QPushButton(parent) {
setFixedSize(64, 88);
setText("");
iconLabel = new QLabel(this);
iconLabel->setFixedSize(64, 64);
iconLabel->setPixmap(QPixmap(":/default/icon.png"));
textLabel = new QLabel(this);
textLabel->setFixedSize(64, 24);
textLabel->setText(tr("Default"));
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(iconLabel);
layout->addWidget(textLabel);
layout->setContentsMargins(0, 0, 0, 0);
}
void IconTextButton::setButtonIcon(const QString& path) {
iconLabel->setPixmap(QPixmap(path));
}
void IconTextButton::setButtonText(const QString& text) {
textLabel->setText(text);
}
Signal Connection Example
MainWindow::MainWindow(QWidget* parent)
: QMainWindow(parent) {
setupUi(this);
controlButton = new QPushButton(this);
controlButton->setText(tr("Toggle"));
connect(controlButton, &QPushButton::pressed, [this]() {
customButton->setButtonText(tr("Cancel"));
});
connect(controlButton, &QPushButton::released, [this]() {
customButton->setButtonText(tr("Confirm"));
});
}
Key Considerations
- Always set layout margins to zero to avoid unwanted spacing
- Custom widgets function as independent containers
- Promotion enables complete behavioral and visual customization