2

我最初通过在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();
}

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

结果

问题原来的实现正确地沿着盒子“垂直”地显示了一个渐变,但是新的实现对角地绘制了渐变。有什么我错过了为什么两个实现行为不同意的原因吗?谢谢

4

1 回答 1

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 ) ) { ... }

至于为什么它在 a 中起作用QWidget?我不知道,它不应该!

于 2013-05-18T09:36:37.133 回答