Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 将QGraphicsColorizeEffect应用于QGraphicsSvgItem的一部分(仅适用于svg本身)_Qt_Svg_Qgraphicsitem - Fatal编程技术网

Qt 将QGraphicsColorizeEffect应用于QGraphicsSvgItem的一部分(仅适用于svg本身)

Qt 将QGraphicsColorizeEffect应用于QGraphicsSvgItem的一部分(仅适用于svg本身),qt,svg,qgraphicsitem,Qt,Svg,Qgraphicsitem,我有一个QGraphicsSvgItem子类,我想在其中修改svg颜色。我想用这个QGraphicsColorizeEffect,效果非常好 我的项目也有一个自定义的选择矩形,高亮显示-类似于其他项目类型 当我应用着色效果时,高光也会变成相同的颜色 我已尝试setEnabled(false)在油漆中,但似乎没有效果 示例代码: 文件mysvg.h 我曾经考虑过让一个QGraphicsSvgItem成为MySvg项目的私有成员-但是MySvg项目必须做很多其他事情,我不知道如何处理渲染器(谁将拥有

我有一个
QGraphicsSvgItem
子类,我想在其中修改svg颜色。我想用这个
QGraphicsColorizeEffect
,效果非常好

我的项目也有一个自定义的选择矩形,高亮显示-类似于其他项目类型

当我应用着色效果时,高光也会变成相同的颜色

我已尝试
setEnabled(false)在油漆中,但似乎没有效果

示例代码:

文件mysvg.h

我曾经考虑过让一个
QGraphicsSvgItem
成为
MySvg
项目的私有成员-但是
MySvg
项目必须做很多其他事情,我不知道如何处理渲染器(谁将拥有它…)-如果我能找出如何使
QGraphicsSvgItem
子类成为
MySvg
类的成员,我就可以对该成员应用colorize并对
MySvg
项执行所有其他操作

请帮助我找到一种将颜色应用于svg的方法,但不要应用于项目的其他绘图部分

编辑-我尝试将成员项添加到类中,并对成员应用着色效果-但它根本不应用着色效果。。。svg加载所有原始颜色

以下是包含成员项的代码:

新mysvg.h

新mysvg.cpp


如何将着色效果应用于svg,而不是选择矩形

效果是基类的一个特性
QGraphicsItem
。它将应用于整个图形项及其所有子项。因此,项目内部绘制的所有内容都会受到其效果的影响

选择矩形应绘制在SVG项对象的外部。 它可以通过组合类
QGraphicsSvgItem
封闭
qgraphicssitemgroup
来实现

QGraphicsItem
添加到
QGraphicsItemGroup
时,它将变为重新租用。因此,当组对象被销毁时,项目被销毁。因此,不需要手动删除它
QGraphicsItem
拥有effect的所有权,因此不需要删除effect对象

下面的类
MyGraphicsItemGroup
可以按照您的预期工作

实现“MyGraphicsSiteMgroup.cpp”

#包括“mygraphicsitemgroup.h”
#包括
#包括
#包括
#包括
#包括
MyGraphicsSiteMgroup::MyGraphicsSiteMgroup()
{
setFlags(QGraphicsItem::ItemIsMovable|
QGraphicsItem::ItemIsFocusable|
QGraphicsItem::ItemIsSelectable);
QString filename=QFileDialog::getOpenFileName(0,
QObject::tr(“打开Svg文件”),QString(),
QObject::tr(“Svg文件(*.Svg*.svgz)”);
QGraphicsColorizeEffect*效果=新的QGraphicsColorizeEffect();
效果->设置颜色(Qt::红色);
QGraphicsSvgItem*svg=新的QGraphicsSvgItem(文件名);
svg->setGraphicsEffect(效果);
addToGroup(svg);
}
void MyGraphicsSiteMgroup::paint(QPainter*painter,
常量QStyleOptionGraphicsItem*选项,QWidget*小部件)
{
QSTYLEOPTIONGRAPHISTIEM opt(*选项);
opt.state=QStyle::state\u None;
QGraphicsItemGroup::paint(painter,&opt,小部件);
QRectF rectangle=boundingRect();
如果(选项->状态&QStyle::状态_选中)
drawSelectionRectangle(画师、选项、矩形);
}
void MyGraphicsSiteMgroup::drawSelectionRectangle(QPaint*painter,
常量QSTYLEOPTIONGRAPHIC SITEM*选项,常量QRectF和矩形)
{
painter->setPen(QPen(选项->调色板.windowText(),0,Qt::DotLine));
画家->挫折(QColor(255188,0,50));
画师->绘图矩形(矩形);
}
标题“MyGraphicsSiteMgroup.h”

\ifndef MYGRAPHICSITEMGROUP\u H
#定义MyGraphicsSiteMgroup\u H
#包括
类MyGraphicsSiteMgroup:公共QGraphicsSiteMgroup
{
公众:
MyGraphicsSiteMgroup();
虚拟虚空油漆(QPainter*油漆工,
常量QStyleOptionGraphicsItem*选项,QWidget*小部件);
无效drawSelectionRectangle(QPainter*painter,
常量QSTYLEOPTIONGRAPHIC SITEM*选项、常量QRectF和矩形);
};
#endif//MYGRAPHICSITEMGROUP\u H

根据您的解释,我的第二个实现应该也能正常工作-因为我在一个
QGraphicsItem
上设置了效果,它被绘制在另一个(不是孩子)的内部。然而,这种效果根本没有得到应用。使用一个组似乎非常笨拙,并且使对象的实现变得非常困难,因为我必须在构建后的不同时间设置svg,我必须能够对对象应用更改,如颜色、变换等。。。为什么一个组对象会允许成员产生效果,而一个普通对象不会?Thalia第二个实现有一个很大的区别。如果项目在组中,它也将添加到场景中。内部
QGraphicsItem
具有指向其场景的私有指针。许多人依赖于此。在您的解决方案中,该项必须连接到父项,并且不会附加到任何场景。该解决方案并不比第二个实现更难。您可以直接使用内部项并设置所有需要的效果
QGraphicsItemGroup
只是另一个包装主对象的
QGraphicsItem
。我现在将尝试实现它,感谢您提供的解决方案。我仍然不理解将项目添加到场景的部分,我的成员对象应该作为大项目的一部分绘制。。。我在使用
QGraphicsItemsGroup
时有过一些不好的经历,但在这种特殊情况下,组属性可能不会成为问题。@Thalia items的
paint()
函数是由它所拥有的项目(添加为
s.addItem(svg)
触发的。场景为项目调用
paint()
,还调用私有效果函数。在第二个解决方案中,场景不知道
#ifndef MYSVG_H
#define MYSVG_H

#include <QGraphicsSvgItem>
#include <QGraphicsColorizeEffect>

class MySvg : public QGraphicsSvgItem
{
public:
    MySvg();
    ~MySvg();
    virtual void paint(QPainter* painter,
                       const QStyleOptionGraphicsItem* option,
                       QWidget* widget = NULL);
private:
    QGraphicsColorizeEffect* m_effect;
    void drawSelectionRectangle(QPainter* painter, const QStyleOptionGraphicsItem* option, const QRectF& rectangle);
};
#endif // MYSVG_H
#include <QStyleOptionGraphicsItem>
#include <QStyle>
#include <QPainterPath>
#include <QPainter>
#include <QFileDialog>
#include <QSvgRenderer>

MySvg::MySvg()
{
    m_effect = new QGraphicsColorizeEffect();
    m_effect->setColor(Qt::red);
    setGraphicsEffect(m_effect);
    setFlags(QGraphicsItem::ItemIsMovable    |
             QGraphicsItem::ItemIsFocusable  |
             QGraphicsItem::ItemIsSelectable);

    QString filename = QFileDialog::getOpenFileName(0, tr("Open Svg File"),
                     QString(), tr("Svg files (*.svg *.svgz)"));
    setSharedRenderer(new QSvgRenderer(filename));
}

MySvg::~MySvg()
{
    delete renderer();
    delete m_effect;
}

void MySvg::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QStyleOptionGraphicsItem opt(*option);
    opt.state = QStyle::State_None;

    QGraphicsSvgItem::paint(painter, &opt, widget);

    //m_effect->setEnabled(false);  // no effect though seemed logical
    QRectF rectangle = boundingRect();
    if (option->state & (QStyle::State_Selected))
        drawSelectionRectangle(painter, option, rectangle);
    //m_effect->setEnabled(true);
}

void MySvg::drawSelectionRectangle(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRectF &rectangle)
{
    painter->setPen(QPen(option->palette.windowText(), 0, Qt::DotLine));
    painter->setBrush(QColor(255, 188, 0, 50));
    painter->drawRect(rectangle);
}
#include <QApplication>
#include <QGraphicsView>
#include "mysvg.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QGraphicsScene s;
    QGraphicsView view;
    view.setScene(&s);
    s.setSceneRect(-50, -50, 500, 650);
    view.show();
    MySvg* svg = new MySvg();
    s.addItem(svg);
    return app.exec();
}
QT       += core gui svg
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = mysvg
TEMPLATE = app
SOURCES += main.cpp \
           mysvg.cpp
HEADERS +=  mysvg.h
class SvgMember : public QGraphicsSvgItem
{
public:
    SvgMember (const QByteArray &content, const QColor& c);
    ~SvgMember ();
private:
    QGraphicsColorizeEffect* m_effect;
};

class MySvg : public QGraphicsItem
{
public:
    MySvg();
    ~MySvg();
    virtual void paint(QPainter* painter,
                       const QStyleOptionGraphicsItem* option,
                       QWidget* widget = NULL);
    virtual QRectF boundingRect() const;
    virtual QPainterPath shape() const;

private:
    void drawSelectionRectangle(QPainter* painter, const QStyleOptionGraphicsItem* option, const QRectF& rectangle);
    SvgMember * m_member;
};
MySvg::MySvg()
{
    setFlags(QGraphicsItem::ItemIsMovable    |
             QGraphicsItem::ItemIsFocusable  |
             QGraphicsItem::ItemIsSelectable);

    QString filename = QFileDialog::getOpenFileName(0, QObject::tr("Open Svg File"),
                     QString(), QObject::tr("Svg files (*.svg *.svgz)"));
    QFile f(filename);
    f.open(QFile::ReadOnly | QFile::Text);
    QByteArray svgContents = f.readAll();
    f.close();
    m_member = new SvgMember (svgContents, Qt::red);
}

MySvg::~MySvg()
{ 
    delete m_member;
}

void MySvg::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QStyleOptionGraphicsItem opt(*option);
    opt.state = QStyle::State_None;

    m_member->paint(painter, &opt, widget);

    QRectF rectangle = boundingRect();
    if (option->state & (QStyle::State_Selected))
        drawSelectionRectangle(painter, option, rectangle);
}

/*! \brief reimplemented to use member rectangle */
QRectF MySvg::boundingRect() const
{
    return m_member->boundingRect();
}

/*! \brief reimplemented to use member shape */
QPainterPath MySvg::shape() const
{
    return m_member->shape();
}

void MySvg::drawSelectionRectangle(QPainter *painter, const QStyleOptionGraphicsItem *option, const QRectF &rectangle)
{
    painter->setPen(QPen(option->palette.windowText(), 0, Qt::DotLine));
    painter->setBrush(QColor(255, 188, 0, 50));
    painter->drawRect(rectangle);
}

SvgMember ::SvgMember (const QByteArray &content, const QColor &c)
{
    m_effect = new QGraphicsColorizeEffect();
    setGraphicsEffect(m_effect);
    m_effect->setColor(c);
    setSharedRenderer(new QSvgRenderer(content));
}

SvgMember ::~SvgMember ()
{
    delete renderer();
    delete m_effect;
}
#include "mygraphicsitemgroup.h"

#include <QGraphicsColorizeEffect>
#include <QGraphicsSvgItem>
#include <QStyleOptionGraphicsItem>
#include <QPainter>
#include <QFileDialog>

MyGraphicsItemGroup::MyGraphicsItemGroup()
{
    setFlags(QGraphicsItem::ItemIsMovable    |
             QGraphicsItem::ItemIsFocusable  |
             QGraphicsItem::ItemIsSelectable);

    QString filename = QFileDialog::getOpenFileName(0,
        QObject::tr("Open Svg File"), QString(),
        QObject::tr("Svg files (*.svg *.svgz)"));

    QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect();
    effect->setColor(Qt::red);

    QGraphicsSvgItem *svg = new QGraphicsSvgItem(filename);
    svg->setGraphicsEffect(effect);
    addToGroup(svg);
}

void MyGraphicsItemGroup::paint(QPainter* painter,
    const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    QStyleOptionGraphicsItem opt(*option);
    opt.state = QStyle::State_None;
    QGraphicsItemGroup::paint(painter, &opt, widget);

    QRectF rectangle = boundingRect();
    if (option->state & QStyle::State_Selected)
        drawSelectionRectangle(painter, option, rectangle);
}

void MyGraphicsItemGroup::drawSelectionRectangle(QPainter *painter,
    const QStyleOptionGraphicsItem *option, const QRectF &rectangle)
{
    painter->setPen(QPen(option->palette.windowText(), 0, Qt::DotLine));
    painter->setBrush(QColor(255, 188, 0, 50));
    painter->drawRect(rectangle);
}
#ifndef MYGRAPHICSITEMGROUP_H
#define MYGRAPHICSITEMGROUP_H

#include <QGraphicsItemGroup>

class MyGraphicsItemGroup : public QGraphicsItemGroup
{
public:
    MyGraphicsItemGroup();

    virtual void paint(QPainter* painter,
        const QStyleOptionGraphicsItem* option, QWidget* widget);

    void drawSelectionRectangle(QPainter *painter,
        const QStyleOptionGraphicsItem *option, const QRectF &rectangle);
};

#endif // MYGRAPHICSITEMGROUP_H