问题描述
上下文
假设我想实现一个自定义 QWidget 类,它应该实现一个按钮(类似于 QPushButton)。
要求:
- 它应遵循操作系统的颜色(也是图标)
- 它应显示来自
QWidget::action
的图标。在本练习中,图标可以是一个使用 QPainter 手动绘制的简单矩形。在最终版本中,我使用 SvgRenderer 用操作系统颜色为图标着色。 - 它应允许不同的尺寸和分辨率。
注意:QPalette
有助于出于多种目的获取操作系统颜色。重要的是不要保存调色板,而是在需要时调用 QWidget::palette()
:如果用户在操作系统上更改颜色设置,这允许操作系统正确更新 UI。
为了说明我的尝试,我将使用以下示例:
#include <QDebug>
#include <QAction>
#include <QApplication>
#include <QIconEngine>
#include <QPainter>
#include <QPaintEvent>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
class TestIconEngine: public QIconEngine
{
public:
void paint(QPainter* p,const QRect &rect,QIcon::Mode mode,QIcon::State state) override
{
p->fillRect(rect,QColor(128,0)); // I SHOULD USE QPALETTE HERE!!! <------
qDebug() << "icon engine paint: " << rect << mode << state;
}
QIconEngine* clone() const override
{
throw std::runtime_error("Not yet implemented");
}
};
class TestWidget: public QPushButton
{
Q_OBJECT
public:
explicit TestWidget( QWidget* parent=nullptr):QPushButton(parent){}
void paintEvent(QPaintEvent *event) override
{
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing,true);
p.setClipRect(event->rect());
const auto pal = palette();
p.setBrush(pal.color(QPalette::Button));
p.setPen(QPen(pal.color(QPalette::Highlight),2.0));
const auto r = rect();
p.drawRoundedRect(r.x()+1,r.y()+1,r.width()-2,r.height()-2,10.0,10.0);
const auto& actList = actions();
if (actList.size()>0)
{
const QAction* act = actList[0];
const QRect iconRect(r.x()+5,r.y()+5,r.height()-10,r.height()-10);
act->icon().paint(&p,iconRect);
}
}
};
#include "main.moc"
int main(int argn,char* argv[])
{
QApplication app(argn,argv);
QWidget window;
window.resize(300,200);
window.show();
QVBoxLayout layout(&window);
layout.setContentsMargins(10,10,10);
window.setLayout(&layout);
TestWidget test(&window);
layout.addWidget(&test);
QAction act;
act.setIcon(QIcon(new TestIconEngine())); //This shit takes ownership of engine (!RAII)
test.addAction(&act);
return app.exec();
}
我的假设是 QAction::icon
的存在是为了在小部件上放置一个图标。但我很难理解它背后的设计尝试是什么,因为:
-
QPalette
没有传递给QIconEngine
,因此,我不知道如何使用适当的操作系统颜色呈现图标。我可能会想象一些黑客将QPalette
保存在static
变量中,但这似乎不是正确的方法。 -
QIconEngine
似乎是自定义QIcon
的方式,当我通过扩展QIcon
可以获得相同的结果时,为什么需要这样做? (为此,QIcon
需要为virtual
,令人沮丧的是事实并非如此)。 - 我是否应该为每个
QIconEngine
创建一个QIcon
实例?还是在所有QIconEngine
之间共享一个Icons
? - 我应该在
QIconEngine
或QIcon
中缓存图标的渲染吗?
问题:
如何使 QPalette 可访问,以便 QIconEngine 可以以适当的 (OS) 颜色绘制图标?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)