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();
}

結果オレンジ色のボックスは、2 番目の実装を使用した 2 つの例を示しています

結果

質問元の実装ではグラデーションがボックスに沿って「垂直に」正しく表示されますが、新しい実装ではグラデーションが斜めに描画されます。2 つの実装の動作が一致しない理由を見逃したことはありますか? ありがとう

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

なぜそれが内部で機能したのQWidgetですか?私にはわかりません、そうすべきではありません!

于 2013-05-18T09:36:37.133 に答える