在QGraphicsScene中绘制QLinearGradient

时间:2013-05-18 08:32:51

标签: qt gradient qgraphicsitem

我最初通过绘制QWidget::paintEvent()中的所有内容来实现我的图表。我有一个函数drawHeatMapLegend()来绘制一个带有QLinearGradient的框来表示我的图形的热图作为图例。

原始实施

widMapGraph::widMapGraph(QWidget parent = 0) : QWidget(parent) {
    gradient_.setCoordinateMode(QGradient::ObjectBoundingMode);
    gradient_.setColorAt(0.0, Qt::green);
    gradient_.setColorAt(0.3, Qt::yellow);
    gradient_.setColorAt(0.6, Qt::red);
}

void widMapGraph::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    drawHeatMapLegend(&painter);
}

void widMapGraph::drawHeatMapLegend(QPainter* painter) {
    QRect legendBox(30, 70, 25, 100);
    int left = legendBox.left() + legendBox.width() + 10;
    painter->save();
    painter->setPen(QPen());
    painter->setBrush(gradient_);
    painter->drawRect(legendBox);
    painter->drawText(left, legendBox.top(), "0.00%");
    painter->drawText(left, legendBox.top() + legendBox.height() / 2, "50.00%");
    painter->drawText(left, legendBox.top() + legendBox.height(), "100.00%");
    painter->restore();
} // end: (widMapGraph::drawHeatMapLegend)

现在,我尝试将QGraphicScene / QGraphicsView框架用于我的图形,并为我的地图图例实现了QGraphicsRectItem的子类。

课程定义

class MapLegend : public QObject, public QGraphicsRectItem {
    Q_OBJECT
public:
    MapLegend(QGraphicsItem *parent = 0);
    void paint (QPainter *painter,
                const QStyleOptionGraphicsItem *option,
                QWidget *widget);
    QLinearGradient gradient_;
    /* other members */
}

班级实施

MapLegend::MapLegend(QGraphicsItem *parent) : QGraphicsRectItem(parent) {
    setRect(30, 70, 25, 100);
    gradient_.setCoordinateMode(QGradient::ObjectBoundingMode);
    gradient_.setColorAt(0.0, Qt::green);
    gradient_.setColorAt(0.3, Qt::yellow);
    gradient_.setColorAt(0.6, Qt::red);
} // end_ctor(MapLegend)

void MapLegend::paint(QPainter *painter,
                      const QStyleOptionGraphicsItem *option,
                      QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);
    int left = rect().left() + rect().width() + 10;
    painter->setPen(QPen());
    painter->setBrush(gradient_);
    painter->drawRect(rect());
    painter->drawText(left, rect().top(), "0.00%");
    painter->drawText(left, rect().top() + rect().height() / 2, "50.00%");
    painter->drawText(left, rect().top() + rect().height(), "100.00%");
} // end: MapLegend::paint()

void My2ndGraph::task() {
    myView->scene()->clear();
    myView->scene()->addItem(myLegend); // myLegend is a class variable as MapLegend
    update();
}

结果橙色框显示了使用第二次实现的两个示例

Result

问题原始实现在框中正确显示“垂直”渐变,但新实现沿对角线绘制渐变。有什么我错过了为什么两个实现行为不同意?感谢

1 个答案:

答案 0 :(得分:2)

您尚未设置渐变的起点和终点,因此默认使用左上角和右下角:

  

QLinearGradient :: QLinearGradient()构造一个默认的线性   插值区域在(0,0)和(1,1)之间的渐变。

  

QGradient :: ObjectBoundingMode:在此模式下,渐变坐标   相对于正在绘制的对象的边界矩形   (0,0)位于左上角,(1,1)位于右下角   对象的边界矩形。

所以你需要手动告诉它梯度方向,如下所示:

gradient_.setStart( 0.0, 0.0 );
gradient_.setFinalStop( 0.0, 1.0 );

或初始化时:

MapLegend::MapLegend(QGraphicsItem *parent) : QGraphicsRectItem(parent),
    gradient_( QLinearGradient( 0.0, 0.0, 0.0, 1.0 ) ) { ... }

至于为什么它在QWidget内工作?我不知道,它应该没有!