In many application development scenarios, there's a common requirement to change a button's appearance based on different application states or logic.
Approach 1: Directly Setting Stylesheets in Code
The most straightforward method is to call setStyleSheet() whenever the button's state changes. This approach is simple but can lead to code duplication and makes styling difficult to manage centrally.
// Set style for the normal state
myButton->setStyleSheet("QPushButton { background-color: #27a9e3; }"
"QPushButton:hover { background-color: #66c011; }"
"QPushButton:pressed { background-color: yellow; }");
// Set style for the selected state
myButton->setStyleSheet("QPushButton { background-color: red; }");
Approach 2: Using QSS Property Selectors
A more organized approach involves defining all possible styles in a separate QSS file and then switching between them by setting or unsetting a custom property on the widget. This separates the presentation (styles) from the logic.
First, define the styles in a .qss file, including a custom property selector:
/* Default button style */
QPushButton {
color: white;
background-color: #27a9e3;
border-width: 0px;
border-radius: 3px;
}
/* Hover state */
QPushButton:hover {
color: white;
background-color: #66c011;
border-width: 0px;
border-radius: 3px;
}
/* Pressed state */
QPushButton:pressed {
color: white;
background-color: yellow;
border-width: 0px;
border-radius: 3px;
}
/* Custom 'active' state, triggered by the 'pagematches' property */
QPushButton[pagematches="true"] {
color: white;
background-color: red;
border-width: 0px;
border-radius: 3px;
}
Next, load this stylesheet and implement the logic to change the button's state by modifying its properties:
#include <QVariant>
// A helper function to update a widget's style based on a property change
void updateWidgetStyle(QWidget *widget, const QString &property, const QVariant &value) {
if (!widget) {
return;
}
widget->setProperty(property.toLatin1().constData(), value);
widget->style()->unpolish(widget); // Unapply the old style
widget->style()->polish(widget); // Reapply the style with the new property
widget->update(); // Trigger a repaint
}
// Example slot to handle a state change, e.g., from a QStackedWidget's index change
void handleStackIndexChanged(int index) {
// First, reset all buttons to the default state
updateWidgetStyle(buttonA, "pagematches", false);
updateWidgetStyle(buttonB, "pagematches", false);
updateWidgetStyle(buttonC, "pagematches", false);
// Then, set the active button based on the new index
switch (index) {
case 0:
updateWidgetStyle(buttonA, "pagematches", true);
break;
case 1:
updateWidgetStyle(buttonB, "pagematches", true);
break;
// Add more cases for other indices as needed
}
}
This second method centralizes styling in a .qss file, making it much easier to maintain and modify. As the application matures, this approach also facilitates more advanced features like dynamic theming by loading different QSS files at runtime.