ejoty
ejoty

Reputation: 3

Changing color of a pushButton in QT

I want to Change the Color of a pushButton in QT after the button is clicked. The Problem is that when I have multiple Buttons all the pushbButton`s Colors Change. How can I make only the one i clicked on Change? PS: I am a beginner so it would be really nice if you could explain your solution in Detail, sry :D.

My Code:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

int i=1;

void MainWindow::on_pushButton_clicked()
{
    if((i==1))
    {
        setStyleSheet("QPushButton { background-color: grey; }\n"
                      "QPushButton:enabled { background-color: rgb(200,0,0); }\n");
        i=i+1;

    }
    else
    {
        if((i==2))
        {
            setStyleSheet("QPushButton { background-color: grey; }\n"
                          "QPushButton:enabled { background-color: rgb(0,200,0); }\n");
         i=i+1;
        }
        else
        {
            setStyleSheet("QPushButton { background-color: grey; }\n"
                          "QPushButton:enabled { background-color: rgb(0,0,200); }\n");
            i=i-2;
        }
    }

}

Upvotes: 0

Views: 9645

Answers (2)

How can I make only the one i clicked on Change? you set the property to the button instance then:

call the set style in that button: ui->pushButton->

like doing:

void MainWindow::on_pushButton_clicked()
{
    if((i==1))
    {
        ui->pushButton->setStyleSheet("QPushButton { background-color: grey; }\n"
                      "QPushButton:enabled { background-color: rgb(200,0,0); }\n");
        i=i+1;
    }
    ....
    ...

Upvotes: 0

MasterAler
MasterAler

Reputation: 1653

Short answer: your QSS is wrong for your purpose, QPushButton {} is a style for everything of QPushButton class (and it's ancestors), that's why the current result. Use #yourButtonName {} and it will work.

The code and explanations:

Getting the button's name in a slot is possible via sender() but using it the same way as you do now would be ugly a bit, look yourself:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->myPushButton, &QPushButton::clicked, this, &MainWindow::onClicked);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onClicked()
{
    QPushButton* target = qobject_cast<QPushButton*>(sender());
    if (target != nullptr)
    {
        target->setStyleSheet(QString("#%1 { background-color: red; }").arg(target->objectName()));
    }
}

Note: connect is used instead of the designer-generated slot and sender() is used, so that you can reuse this slot for other buttons.

Well, sometimes you'd want to write less style-generating code, because it quickly becomes unreadable, then dynamic properties become of use:

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QStyle>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->myPushButton, &QPushButton::clicked, this, &MainWindow::onClicked);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onClicked()
{
    QPushButton* target = qobject_cast<QPushButton*>(sender());
    target->setProperty("clicked", true);
    target->style()->unpolish(target);
    target->style()->polish(target);
}

This way you make the widget "remember" some state in a property, a neater way, IMHO. Also, that small hack with QStyle becomes mandatory. The style itself for the clicked buttons can be added just once to the MainWindow's stylesheet (I've done it in Qt Designer, you can do it in the constructor as well):

QPushButton[clicked=true]
{
    background-color: green;
}

Upvotes: 2

Related Questions