Charitoo
Charitoo

Reputation: 1872

Change the icon of QPushbutton or QToolbutton

Icons for various states of QPushbutton etc.

How do set the icon for a QPushButton or QToolbutton for when it is off and for when it is toggled.

btn1 = QPushButton("Test")
icon1 = QIcon("normal.png")
icon2 = QIcon("toggled.png")
# set the icon for when btn1.toggled returns True
# and when btn1.toggled returns False

Creating a QPushbutton with three states

I want to create a qpushbutton that can have three states. I am using the button in a media player I am creating. These are the states I want the button to have:

  1. normal (repeat off)
  2. toggled state 1 (repeat all)
  3. toggled state 2 (repeat one)

Upon research I've realised I may have to override QAbstractButton.nextCheckState. The trouble is that the is no signature for the method in the documentation. I therefore have no idea on how to override it or even if the is a state property to set or modify.

Any help will be appreciated.

Upvotes: 2

Views: 6820

Answers (2)

Praneeth Peiris
Praneeth Peiris

Reputation: 2088

You can use a simple way of checking the checked flag of a pushbutton on the clicked() signal.

connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(buttonClicked(bool)));

And in your code, define a slot as buttonClicked(bool checked) and implement it as:

void MainWindow::buttonClicked(bool checked)
{
    if ( checked )
        ui->pushButton->setIcon(QIcon(":/on.png"));
    else
        ui->pushButton->setIcon(QIcon(":/off.png"));
}

This can be implemented for a QToolbutton as well accordingly.

And please note the icons in here are used from the resources. So, it's better to add your icons to the resources file.

Upvotes: 2

Stanley F.
Stanley F.

Reputation: 1998

I don't know about QAbstractButton.nextCheckState, but I suggest making use of Qt's signal/slot mechanism.

Whenever the state of repeat mode changes in the model, emit a signal like notifyModeChanged. Connect a slot to that signal in which the state (e.g. the icon) of the button is set as required.

I put together a quick example with everything contained in the MainWindow class. In a real application one would divide the code at least into model and view. The example is based on the auto-generated project of QtCreator's new project wizard. In Design view, I added a QPushButton.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "ui_mainwindow.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0)  :
        QMainWindow(parent),
        ui(new Ui::MainWindow),
        icon1("icon1.png"),
        icon2("icon2.png"),
        icon3("icon3.png")
    {
        ui->setupUi(this);
        ui->pushButton->setIcon(icon2);

        connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::changeMode);
        connect(this, &MainWindow::notifyModeChanged, this, &MainWindow::modeChanged);
    }

    ~MainWindow() {
        delete ui;
    }

signals:
    void notifyModeChanged();

public slots:
    void changeMode() {
        mode = (mode + 1) % 3;
        emit notifyModeChanged();
    }

    void modeChanged() {
        switch (mode) {
            case 0: ui->pushButton->setIcon(icon1); break;
            case 1: ui->pushButton->setIcon(icon2); break;
            case 2: ui->pushButton->setIcon(icon3); break;
        }
    }

private:
    Ui::MainWindow *ui;

    QIcon icon1;
    QIcon icon2;
    QIcon icon3;

    int mode{0};
};

#endif // MAINWINDOW_H

Upvotes: 0

Related Questions