QPen setCosmetic does not work in high QGraphicsView scale

524 views Asked by At

I have a QGraphicsView and a QGraphicsItem that added to graphicsView's scene. I override QGraphicsView wheelEvent to do scale view, but i want my graphics item width does not change.

For this purpose i set cosmetic true for pen in graphics item paint function. it is work fine but after some scale in, cosmetic feature does not work and graphics item width begins to grow up.

MyGraphicsItem.h

#include <QGraphicsItem>

class MyGraphicsItem : public QGraphicsItem
{
public:
    MyGraphicsItem();
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
    QRectF boundingRect() const;
};

MyGraphicsItem.cpp

#include "MyGraphicsItem.h"
#include <QPen>
#include <QPainter>

MyGraphicsItem::MyGraphicsItem()
{
}

void MyGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    QPen pen;
    pen.setColor(Qt::black);
    pen.setCosmetic(true);

    painter->setPen(pen);
    painter->drawLine(QPointF(0, 250), QPointF(500, 250));
}

QRectF MyGraphicsItem::boundingRect() const
{
    return QRectF(0, 0, 500, 500);
}

MyGraphicsView.h

#include <QGraphicsView>

class MyGraphicsView : public QGraphicsView
{
public:
    MyGraphicsView();
    void wheelEvent(QWheelEvent* event);
};

MyGraphicsView.cpp

#include "MyGraphicsView.h"
#include <QtMath>
#include <QDebug>
#include <QGLFormat>
#include <QWheelEvent>
#include <QStyleOptionGraphicsItem>

MyGraphicsView::MyGraphicsView()
{
    setScene(new QGraphicsScene(0, 0, 500, 500));

    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);

    setViewport(new QGLWidget);
}

void MyGraphicsView::wheelEvent(QWheelEvent* event)
{
    qreal s = qPow(2, event->delta() / 120 / 4.0);
    scale(s, s);
}

MainWindow.h

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

MainWindow.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"

#include "MyGraphicsItem.h"
#include "MyGraphicsView.h"

MainWindow::MainWindow(QWidget* parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    auto view = new MyGraphicsView;
    view->scene()->addItem(new MyGraphicsItem);

    setCentralWidget(view);
}

MainWindow::~MainWindow()
{
    delete ui;
}

main.cpp

#include "MainWindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

Any suggest?

Another problem that i see, is that after some more scale in (zoom) on painted line, QGraphicsView's scroll bars jump to top left corner of view.

1

There are 1 answers

0
Dimitry Ernot On

By default, a QGraphicsItem is adapted according to the views transformation.

You can ignore it by adding setFlag(QGraphicsItem::ItemIgnoresTransformations); in your MyGraphicsItem constructor. Your item will be not scaled when you zoom in/out.