On Qt, how to change the icon of an action in the toolbar at runtime?

帅比萌擦擦* 提交于 2019-12-03 21:27:10

I would subclass QAction and add some logic for the states in which it can be. It is never a good idea to hardcode the color of something into the name of a method. By subclassing QAction, the look and feel of it is encapsulated.

This could be something like this:

Header file:

class StateAction : public QAction
{
    Q_OBJECT
public:
    explicit StateAction(QObject *parent = 0);

public slots:
    void start();
    void stop();
    void pause();
};

Implementation file:

StateAction::StateAction(QObject *parent) :
    QAction(parent)
{
    this->stop();
}

void StateAction::start()
{
    this->setIcon(QIcon(":/states/start.png"));
}

void StateAction::stop()
{
    this->setIcon(QIcon(":/states/stop.png"));
}

void StateAction::pause()
{
    this->setIcon(QIcon(":/states/pause.png"));
}

Now, in your MainWindow you can use that custom QAction simply by connecting its slots to the right signals:

Header file:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

signals:
    void startedComputing();
    void finishedComputing();
    void pausedComputing();

private:
    void createActions();
    void createToolbars();
    void createConnections();
    StateAction *m_stateAction;
};

Implementation file:

...

void MainWindow::createConnections()
{
    connect(this, SIGNAL(startedComputing()), m_stateAction, SLOT(start()));
    connect(this, SIGNAL(finishedComputing()), m_stateAction, SLOT(stop()));
    connect(this, SIGNAL(pausedComputing()), m_stateAction, SLOT(pause()));
}

I've found a solution using QToolButton here it is:

Header : FenPrincipale.h

#ifndef FENPRINCIPALE_H
#define FENPRINCIPALE_H

#include <QWidget>
#include <QVBoxLayout>
#include <QToolButton>
#include <QToolBar>
#include <QAction>
#include <QTextEdit>

class FenPrincipale : public QWidget {
    Q_OBJECT
public:
    FenPrincipale();

private slots:
    void goComputing();
    void stopComputing();

private:

    QAction* actionDemarrer;    // Start computing
    QAction* actionArreter;     // Stop computing
    QToolBar* toolBarActions;

    QToolButton* boutonAction;  // this button holds the appropriate action
    QVBoxLayout* layoutPrincipale;
    QTextEdit* resultat;        // show result
};

...

Implementation : FenPrincipale.cpp

#include "FenPrincipale.h"

FenPrincipale::FenPrincipale() : QWidget()
{
    this->setFixedSize(400, 200);

    // create actions
    actionDemarrer = new QAction(QIcon("bouton-vert.png"), "demarrer", this);
    actionArreter = new QAction(QIcon("bouton-rouge.png"), "arreter", this);
    boutonAction = new QToolButton;
    boutonAction->setDefaultAction(actionDemarrer);

    // create toolbar
    toolBarActions = new QToolBar(this);
    toolBarActions->addWidget(boutonAction);

    // create result widget
    resultat = new QTextEdit(this);

    // create layout
    layoutPrincipale = new QVBoxLayout(this);
    layoutPrincipale->addWidget(toolBarActions);
    layoutPrincipale->addWidget(resultat);
    this->setLayout(layoutPrincipale);


    // make connections
    QObject::connect(actionDemarrer, SIGNAL(triggered()), this, SLOT(goComputing()));
    QObject::connect(actionArreter, SIGNAL(triggered()), this, SLOT(stopComputing()));
}

void FenPrincipale::goComputing()
{
    resultat->setText("Computing...");
    boutonAction->setDefaultAction(actionArreter);
}

void FenPrincipale::stopComputing()
{
    resultat->setText("Partial result : {?}");
    boutonAction->setDefaultAction(actionDemarrer);
}

...

Main

#include <QApplication>
#include "FenPrincipale.h"

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    FenPrincipale fenetre;

    fenetre.show();
    return app.exec();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!