【问题标题】:How to change the icon's 'on' state color?如何更改图标的“开启”状态颜色?
【发布时间】:2021-12-26 19:01:02
【问题描述】:

我无法在 Qt 中更改图标的“开启”状态颜色。我有以下测试代码:

头文件:

#pragma once

#include <QtWidgets/QMainWindow>
#include <QApplication>
#include <QPushButton>
#include <QPainter>
#include <QIcon>
#include <QPixmap>
#include <QStyleFactory>
#include <QIconEngine>
#include "ui_mainwindow.h"

class MainWindow: public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = Q_NULLPTR);

private:
    Ui::MainWindowClass ui;
};

实现文件:

#include "mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
{
    qApp->setStyle(QStyleFactory::create("Fusion"));
    ui.setupUi(this);
    QWidgetList allWidgets = qApp->allWidgets();
    for (QWidget* wid : allWidgets) {
        QString str = wid->metaObject()->className();
        if (str == "QPushButton") {
            auto btn = dynamic_cast<QPushButton*>(wid);
            if (!btn->icon().isNull()) {
                QIcon btnIcon = btn->icon();
                QPixmap pixOff = btnIcon.pixmap(QSize(1024, 1024));
                QPixmap pixOn = btnIcon.pixmap(QSize(1024, 1024));
                QPixmap pixDisOff = btnIcon.pixmap(QSize(1024, 1024));
                QPixmap pixDisOn = btnIcon.pixmap(QSize(1024, 1024));

                QPainter paintOff(&pixOff);
                paintOff.setCompositionMode(QPainter::CompositionMode_SourceIn);
                paintOff.fillRect(pixOff.rect(), Qt::green);

                QPainter paintOn(&pixOn);
                paintOn.setCompositionMode(QPainter::CompositionMode_SourceIn);
                paintOn.fillRect(pixOn.rect(), Qt::red);

                QPainter paintDisOff(&pixDisOff);
                paintDisOff.setCompositionMode(QPainter::CompositionMode_SourceIn);
                paintDisOff.fillRect(pixDisOff.rect(), Qt::yellow);

                QPainter paintDisOn(&pixDisOn);
                paintDisOn.setCompositionMode(QPainter::CompositionMode_SourceIn);
                paintDisOn.fillRect(pixDisOn.rect(), Qt::blue);

                btnIcon.addPixmap(pixOff, QIcon::Normal, QIcon::Off);
                btnIcon.addPixmap(pixDisOff, QIcon::Disabled, QIcon::Off);
                btnIcon.addPixmap(pixOff, QIcon::Active, QIcon::Off);
                btnIcon.addPixmap(pixOff, QIcon::Selected, QIcon::Off);
                btnIcon.addPixmap(pixOn, QIcon::Normal, QIcon::On);
                btnIcon.addPixmap(pixDisOn, QIcon::Disabled, QIcon::On);
                btnIcon.addPixmap(pixOn, QIcon::Active, QIcon::On);
                btnIcon.addPixmap(pixOn, QIcon::Selected, QIcon::On);

                btn->setIcon(btnIcon);
            }
        }
    }
}

在我的.ui 文件中,我添加了一些QPushButton 并将像素图应用为它们的图标:

从左到右:禁用按钮、可检查按钮、不可检查按钮。

这些按钮被放置在一个可勾选的QGroupBox 中,以便我可以同时启用/禁用它们。

当我运行我的代码时,它是这样显示的(禁用的颜色是黄色,所以不太明显):

这里中间QPushButton的颜色应该是Qt::red,因为它处于选中(即QIcon::On)状态,但它不是红色。

当我取消选中分组框时,所有按钮都被禁用,图标变为QIcon::Disabled, QIcon::Off

QIcon::Disabled, QIcon::On的颜色是Qt::blue,中间的按钮处于选中和禁用状态,这意味着它应该是蓝色的但不是。

图标永远不会改变颜色为QIcon::Normal, QIcon::On 或任何其他QIcon::On 状态。这意味着QIcon::Off 状态颜色被正确应用,但QIcon::On 状态颜色未被应用。有关如何解决此问题的任何想法?

【问题讨论】:

  • QPushButton::checkable() 的值是多少?如果false 那么这是正常的(阅读文档)。
  • 顺便说一句if (auto btn = qobject_cast&lt;QPushButton*&gt;(wid)) {
  • QPushButton::checkable() 是真的。我有多个QPushButton,其中一些是可检查的,有些是不可检查的,有些处于禁用状态。每个都有自己的图标。
  • 请准备一个minimal reproducible example
  • @scopchanov 以上是最小的可重现示例。它是整个 CPP 文件,还有头文件,但它是默认的。我将更新我的问题以包含所有详细信息。

标签: c++ qt icons


【解决方案1】:

准备一个最小的可重复的示例始终是解决问题的正确方法。这是我为你写的,它正在工作:

#include <QApplication>
#include <QBoxLayout>
#include <QPushButton>
#include <QPainter>

class MainWindow : public QWidget
{
public:
    MainWindow(QWidget *parent = nullptr) : QWidget(parent)
    {
        auto *l = new QVBoxLayout(this);
        auto *button = new QPushButton(tr("Click Me"), this);

        QPixmap pixOff(":/pix/images/save.png");
        QPixmap pixOn(pixOff);

        QPainter painter;

        painter.begin(&pixOn);
        painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
        painter.fillRect(pixOn.rect(), Qt::red);
        painter.end();

        painter.begin(&pixOff);
        painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
        painter.fillRect(pixOff.rect(), Qt::green);
        painter.end();

        QIcon icon;

        icon.addPixmap(pixOff, QIcon::Normal, QIcon::Off);
        icon.addPixmap(pixOn, QIcon::Normal, QIcon::On);

        button->setIcon(icon);
        button->setCheckable(true);
        button->setChecked(true);

        l->addWidget(button);
        l->addStretch();

        resize(200, 100);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    w.show();

    return a.exec();
}

注意:该示例使用资源中的 16x16 png 图像。您应该用您自己的图像替换它。

该示例产生以下结果:

【讨论】:

  • 谢谢!是的,它可以工作,但只能在默认的 WindowsVista 样式中使用。一旦我应用 Fusion 样式,它就会停止工作。
  • 感谢您的帮助,我发现这是 Qt 5.15 版本中的一个错误:bugreports.qt.io/browse/QTBUG-86736
  • @Chaitanya,看,minimal reproducible example 确实可以帮助确定问题 - 您的案例中的融合风格。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 1970-01-01
  • 2018-02-18
  • 2017-08-16
  • 2018-11-30
  • 2021-10-13
相关资源
最近更新 更多