qt - 如何在按钮单击时切换 svg 图标 - 使用 QT C++
问题描述
我对 svg + QT 概念比较陌生。我创建了一个具有 2 个状态的 svg 图标。我想将此 svg 图标添加到 QPushButton。单击按钮时,应切换图标(显示其他状态)。
谁能告诉我如何在 QT 中做到这一点?QT 与 C++!
编辑:
我尝试使用 svg 图标并在单击按钮时切换它。我已经实现了预期的行为,但我想知道这是否是正确的做法。
我在下面粘贴代码文件和 svg 图标内容
我已经尝试过使用 QSvgRenderer 和 QIcon。我已经实现了我一直在寻找的东西。
但我不确定这是否应该这样做。请看一下,让我知道这是否是首选方式。
我从https://nucleoapp.com/tool/icon-transition创建了一个 svg 图标(使用 2 个其他 svg 图标) svg 图标嵌入了 2 个 svg 图标。我现在的目标是在单击按钮时切换图标。
在下面查看我的文件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSvgRenderer>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
bool isDefaultIconLoaded;
QString otherIconSvgContent;
QString defaultIconSvgContent;
QSvgRenderer m_svgRenderer;
void loadCurrentSvgIcon(QByteArray ba);
private slots:
void toolBtnClicked();
};
#endif // MAINWINDOW_H
.cpp 文件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QPainter>
#include <QtSvg/QSvgRenderer>
#include <QPixmap>
#include <QDomDocument>
#include <QDomNodeList>
#include <QTextStream>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
isDefaultIconLoaded(true)
{
ui->setupUi(this);;
connect(ui->toolButton, &QToolButton::clicked, this, &MainWindow::toolBtnClicked);
ui->toolButton->setStyleSheet("border:none;");
// open svg icon which has multiple states
QFile file(":/icon/theSvg.svg");
file.open(QIODevice::ReadOnly);
const QByteArray baData = file.readAll();
QDomDocument doc;
doc.setContent(baData, false);
// Read both the <g> elements from the .svg xml and store each 'icon content' in member var.
QDomNodeList gList = doc.elementsByTagName("g");
for(int i = 0; i < gList.size(); i++)
{
QString aContent;
QTextStream ts(&aContent);
gList.at(i).save(ts,0);
qDebug("%s", qPrintable(aContent));
if( isDefaultIconLoaded )
{
defaultIconSvgContent.insert(0, "<svg>");
defaultIconSvgContent += aContent;;
defaultIconSvgContent.append("</svg>");
isDefaultIconLoaded = false;
qDebug() <<defaultIconSvgContent;
}
else {
otherIconSvgContent.insert(0, "<svg>");
otherIconSvgContent += aContent;
otherIconSvgContent.append("</svg>");
qDebug() <<otherIconSvgContent;
}
}
// Load the default svg icon first
QByteArray ba = defaultIconSvgContent.toUtf8();
isDefaultIconLoaded = true;
loadCurrentSvgIcon(ba);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::loadCurrentSvgIcon(QByteArray ba)
{
m_svgRenderer.load(ba);
QPixmap pix(m_svgRenderer.defaultSize());
QPainter pixPainter(&pix);
m_svgRenderer.render(&pixPainter);
QIcon myicon(pix);
ui->toolButton->setIcon(myicon);
}
void MainWindow::toolBtnClicked()
{
if ( isDefaultIconLoaded == true )
{
// Toggle the icon to "other"
QByteArray ba = otherIconSvgContent.toUtf8();
loadCurrentSvgIcon(ba);
isDefaultIconLoaded = false;
}
else {
QByteArray ba = defaultIconSvgContent.toUtf8();
loadCurrentSvgIcon(ba);
isDefaultIconLoaded = true;
}
}
svg 文件的内容
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" height="16" width="16">
<g
class="nc-icon-wrapper" stroke-width="1" fill="#111111" stroke="#111111">
<title>default</title>
<path
fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" data-color="color-2" d="M1.5 1.5h2">
</path>
<circle
fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" cx="9" cy="9" r="3.5" data-color="color-2">
</circle>
<path
fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" data-color="color-2" d="M2.5 5.5h1">
</path>
<path
fill="none" stroke="#111111" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" d="M14.5 3.5h-2l-1-2h-5l-1 2h-4a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1v-9a1 1 0 0 0-1-1z">
</path>
</g>
<g
class="nc-icon-wrapper" fill="#111111">
<title>other</title>
<path
fill="#111111" d="M15,3h-2.5l-1.7-2.6C10.6,0.2,10.3,0,10,0H6C5.7,0,5.4,0.2,5.2,0.4L3.5,3H1C0.4,3,0,3.4,0,4v11 c0,0.6,0.4,1,1,1h14c0.6,0,1-0.4,1-1V4C16,3.4,15.6,3,15,3z M14,14H2V5h2c0.3,0,0.6-0.2,0.8-0.4L6.5,2h2.9l1.7,2.6 C11.4,4.8,11.7,5,12,5h2V14z">
</path>
<circle
data-color="color-2" cx="8" cy="9" r="3">
</circle>
</g>
</svg>
基本上,每个“g”元素代表一个图标。我正在读取 C'tor 中的每个 g 元素内容并将它们存储到成员变量中(以避免一次又一次地读取)。
然后我使用“QSvgRenderer”根据点击事件“加载”图标。
这可以按预期工作,但这是最佳实践还是有更好的方法可以实现这一目标?
解决方案
推荐阅读
- javascript - 如何使用 javascript 或 jquery 选择供应商前缀?
- python - 使用句子创建向量
- c++ - 第 25 行的“表达式必须具有整数或无范围枚举类型”
- python - 在 PySpark 中导入用户定义的模块失败
- azure-devops - 从 CLI 获取 Azure Devops NPM 提要身份验证令牌
- openldap - ActiveMQ Artemis 无法针对 OpenLDAP 进行身份验证
- c# - 将 SupportedRuntime 设置为 4.6 后缺少装配错误 (System.Runtime.InteropServices.RuntimeInformation)
- php - 将 ACF 文件插入 CSS 伪元素
- javascript - 不要从 URL 中获取 GET 参数
- pandas - 哪个更好,多个文件的多个请求或单个文件的单个请求 S3?