Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Change QAction icon on QAction Trigger



  • Hi,

    I have a MainWindow with a toolbar. The toolbar has 2 actions on it.

    1. actionConnect (Connect)
    2. actionCheck (Check Status)
    MainWindow::MainWindow(QWidget *parent)
    	: QMainWindow(parent)
    	, ui(new Ui::MainWindow)
    {
    	ui->setupUi(this);
    	m_Connect = 0;
    }
    
    MainWindow::~MainWindow()
    {
    	delete ui;
    }
    
    
    void MainWindow::on_actionConnect_triggered()
    {
    	qDebug() << "Connect triggered";
    	m_Connect = 1;
    }
    
    void MainWindow::on_actionCheck_triggered()
    {
    	qDebug() << "Check Status, triggered";
    	if (m_Connect) {
    		qDebug() << "Connected, Can check Status now.";
    	}
    }
    
    

    QAction.PNG

    actionCheck can be done only after a successful connection;
    in the ActionEditor, I've set Disabled Off for the icon, so that it appears disabled.

    DisabledOff.PNG

    After a successful connection, I would like to change the icon, so that it looks enabled now.

    But, that said, I wonder how to change the icon associated with actionCheck within ui->toolBar

    Any thoughts, on how to do this ?

    Thanks,


  • Lifetime Qt Champion

    QAction has an icon property. Apart from this - when an action is disabled, Qt automatically shows the icon greyed out.



  • @Christian-Ehrlicher said in Change QAction icon on QAction Trigger:

    QAction has an icon property. Apart from this - when an action is disabled, Qt automatically shows the icon greyed out.

    Thanks for the reponse.

    I see that QAction has the setIcon() property with which you can set change the icon.

    Maybe it is a stupid question. How to set setIcon() ?
    I can access toolBar from ui->toolBar, but how to access the QAction members in toolBar ?

    Thanks,


  • Lifetime Qt Champion

    The signal actionTriggered() has the triggered action as first parameter.



  • @Christian-Ehrlicher said in Change QAction icon on QAction Trigger:

    The signal actionTriggered() has the triggered action as first parameter.

    I didnt think of that; But, that said, Action Editor was used from QT designer to create those actions. As a result, I do feel blind how to get access to QAction.

    I am no QT expert by any chance, hence all the dumb questions probably.

    void MainWindow::on_actionConnect_triggered()
    {
    	qDebug() << "Connect triggered";
    	m_Connect = 1;
    }
    
    void MainWindow::on_actionCheck_triggered()
    {
    	qDebug() << "Check Status, triggered";
    	if (m_Connect) {
    		qDebug() << "Connected, Can check Status now.";
    	}
    }
    

    Thanks,


  • Lifetime Qt Champion

    Please read about signals and slots and change your slot to get QAction* as parameter.



  • @Christian-Ehrlicher said in Change QAction icon on QAction Trigger:

    Please read about signals and slots and change your slot to get QAction* as parameter.

    I did the following:

    MainWindow::MainWindow(QWidget *parent)
    	: QMainWindow(parent)
    	, ui(new Ui::MainWindow)
    {
    	ui->setupUi(this);
    	m_Connect = 0;
    
    	QPixmap pix_Conn = QPixmap(":/connect.png");
    	QPixmap pix_Status = QPixmap(":/check_disabled.png");
    	QToolBar *toolbar = ui->toolBar;
    	QAction *conn = new QAction(QIcon(pix_Conn), "Connect");
    	toolbar->addAction(conn);
    
    	QAction *check = new QAction(QIcon(pix_Status), "Status");
    	toolbar->addAction(check);
    
    	connect(conn, SIGNAL(triggered()), this, SLOT(on_actionConnect_triggered(conn)));
    	connect(check, SIGNAL(triggered()), this, SLOT(on_actionCheck_triggered(check)));
    }
    
    MainWindow::~MainWindow()
    {
    	delete ui;
    }
    
    void MainWindow::on_actionConnect_triggered(QAction *action)
    {
    	(void) action;
    	qDebug() << "Connect triggered";
    	m_Connect = 1;
    }
    
    void MainWindow::on_actionCheck_triggered(QAction *action)
    {
    	QPixmap pix_Status = QPixmap(":/check.png");
    
    	qDebug() << "Check Status, triggered";
    	if (m_Connect) {
    		qDebug() << "Connected, Can check Status now.";
    		action->setIcon(pix_Status);
    	}
    }
    

    Likely, I am doing something incorrect ..

    Somehow, that does not seem to work, as

    1. it gives out a runtime error.
    QMetaObject::connectSlotsByName: No matching signal for on_actionConnect_triggered(QAction*)
    QMetaObject::connectSlotsByName: No matching signal for on_actionCheck_triggered(QAction*)
    QObject::connect: No such slot MainWindow::on_actionConnect_triggered(conn) in ..\QActionTest\mainwindow.cpp:28
    QObject::connect:  (receiver name: 'MainWindow')
    QObject::connect: No such slot MainWindow::on_actionCheck_triggered(check) in ..\QActionTest\mainwindow.cpp:29
    QObject::connect:  (receiver name: 'MainWindow')
    
    1. Adding QAction programatically brings another TextLabel to the ToolBar.

    ToolBar.PNG

    I am slightly lost in here ...



  • @codeaway said in Change QAction icon on QAction Trigger:

    it gives out a runtime error.

    Exactly the same advice as I just put in another thread, https://forum.qt.io/topic/119502/emit-signal-from-a-static-method-and-connect-it-to-a-setvalue-slot-on-a-progress-bar/3, and others. Really suggest you act on that....



  • @JonB said in Change QAction icon on QAction Trigger:

    @codeaway said in Change QAction icon on QAction Trigger:

    it gives out a runtime error.

    Exactly the same advice as I just put in another thread, https://forum.qt.io/topic/119502/emit-signal-from-a-static-method-and-connect-it-to-a-setvalue-slot-on-a-progress-bar/3, and others. Really suggest you act on that....

    Did change to the new SIGNAL/SLOT methods. I guess, this is correct ..

    class MainWindow : public QMainWindow
    {
    	Q_OBJECT
    
    public:
    	MainWindow(QWidget *parent = nullptr);
    	~MainWindow();
    
    private slots:
    	void on_actionConnect_triggered();
    
    	void on_actionCheck_triggered();
    
    private:
    	Ui::MainWindow *ui;
    
    	QAction *conn;
    	QAction *check;
    
    	bool m_Connect;
    };
    #endif // MAINWINDOW_H
    
    
    
    MainWindow::MainWindow(QWidget *parent)
    	: QMainWindow(parent)
    	, ui(new Ui::MainWindow)
    {
    	ui->setupUi(this);
    	m_Connect = 0;
    
    	QPixmap pix_Conn = QPixmap(":/icons/connect.png");
    	QPixmap pix_Status = QPixmap(":/icons/check_disabled.png");
    	QToolBar *toolbar = ui->toolBar;
    
    	conn = new QAction(QIcon(pix_Conn), "Connect");
    	toolbar->addAction(conn);
    
    	check = new QAction(QIcon(pix_Status), "Status");
    	toolbar->addAction(check);
    
    	connect(conn, &QAction::triggered, this, &MainWindow::on_actionConnect_triggered);
    	connect(check, &QAction::triggered, this, &MainWindow::on_actionCheck_triggered);
    }
    
    MainWindow::~MainWindow()
    {
    	delete ui;
    }
    
    void MainWindow::on_actionConnect_triggered()
    {
    	qDebug() << "Connect triggered";
    	m_Connect = 1;
    }
    
    void MainWindow::on_actionCheck_triggered()
    {
    	QPixmap pix_Status = QPixmap(":/icons/check.png");
    
    	qDebug() << "Check Status, triggered";
    	if (m_Connect) {
    		qDebug() << "Connected, Can check Status now.";
    		conn->setIcon(pix_Status);
    	}
    }
    

    There are no runtime errors... Phew..
    The same issue does exist, what I wrote previously.

    ToolBar.PNG

    The signals/slots do work.. :-)

    I can see the triggers being called..

    I guess there exists 4 QAction methods in toolbar ?
    (2 of them added, using action editor .. ?)

    The icons do not seem to change .. Sigh!


Log in to reply