Einschränkender Element aus der QGraphicsView -Szene nach eingeschränktem RechtekC++

Programme in C++. Entwicklerforum
Anonymous
 Einschränkender Element aus der QGraphicsView -Szene nach eingeschränktem Rechtek

Post by Anonymous »

Ich verwende qGraphicsView , um ein Bild zu skalieren/zu bewegen. Ich arbeite in diesem Code, der auf dieser Frage basiert. Es beschränkt das Bild daran .
Mit dieser neuen Klasse versuche ich, das Bild überall auf dem Ansichtsfenster zu verschieben, so lange ein bestimmter Bereich davon (_pixmaprect) ausgeht vollständig Aus den Ansichtsfenstergrenzen. : //i.imgur.com/z0lowpg.mp4
In der Skala 1.22
Ich bin in der Lage, es nur ein wenig um seinen ursprünglichen Bereich auf größeren Maßstäben zu bewegen. in der Lage, es überall zu bewegen, einschließlich des Verschiebens von Ansichtsfenster, das ich vermeiden möchte. >
Dies ist nicht, das Bild ist vollständig draußen. :

Ich habe versucht, ein sehr minimales Beispiel zu erstellen. Der Code ist nicht gut geschrieben, aber es ist verständlich: < /p>

Code: Select all

#include 

class GraphicsView : public QGraphicsView
{
public:
QLabel*              _posLabel   = nullptr;
QGraphicsScene*      _scene      = nullptr;
QGraphicsPixmapItem* _pixmapItem = nullptr;
bool    _isPanning    = false;
qreal   _currentScale = 1.0;
QPoint  _lastMousePos;
QRect   _pixmapRect;

GraphicsView(QWidget* parent, const QPixmap& pixmap) : QGraphicsView(parent)
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setRenderHint(QPainter::SmoothPixmapTransform);
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setFrameShape(QFrame::NoFrame);
setTransformationAnchor(QGraphicsView::NoAnchor);
setResizeAnchor(QGraphicsView::NoAnchor);
setBackgroundBrush(Qt::NoBrush);
setAlignment(Qt::AlignCenter);
setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing);
setMouseTracking(true);
setFixedSize(parent->size());
setStyleSheet("*{ background-color: transparent; }");

_posLabel = new QLabel(this);
_posLabel->setFixedSize(300, 50);
_posLabel->setStyleSheet("QLabel { font-size: 18px; color : white; }");
_posLabel->move(0, 0);
_posLabel->setText("0,0 0x0\nscale: 0");

QList sbList{ new QSpinBox(this), new QSpinBox(this) };
for (int i = 0; i < 2; i++) // just to help debug
{
QSpinBox* sb = sbList[i];
sb->setRange(1, i ? height() : width());
sb->move(       i ? 900 : 860, 0);
sb->setValue(   i ? 50  : 50);
sb->setSingleStep(40);
sb->setFixedWidth(60);
connect(sb, &QSpinBox::valueChanged, [=](int value)
{
QPixmap pixmap2(pixmap.size());
pixmap2.fill(Qt::transparent);
QRect r(420, 250, sbList[0]->value(), sbList[1]->value());
QPainter painter(&pixmap2);
painter.drawPixmap(r.x(), r.y(), pixmap.copy(r));
_pixmapRect = r;
_pixmapItem->setPixmap(pixmap2);
});
}

QGraphicsPixmapItem* bgPixmapItem = new QGraphicsPixmapItem();
QPixmap bg(size());
bg.fill(QColor(0, 0, 0, 180));
bgPixmapItem->setPixmap(bg);

_pixmapItem = new QGraphicsPixmapItem();
_scene = new QGraphicsScene(this);
_scene->addItem(bgPixmapItem);
_scene->addItem(_pixmapItem);
setScene(_scene);
};

void centerScene()
{
// First check if the top left corner is in the middle of the view.
QPointF topLeft = mapFromScene(0, 0);
if (topLeft.x() > 0 || topLeft.y() > 0)
{
QTransform t;
t.translate(
topLeft.x() > 0 ? -topLeft.x() / _currentScale : 0,
topLeft.y() > 0 ? -topLeft.y() / _currentScale : 0
);
setTransform(t, true);
}
else
{
// If not, then check if perhaps the bottom right corner is.
QPointF bottomRight = mapFromScene(width(), height());
if (bottomRight.x() < width() || bottomRight.y() < height())
{
QTransform t;
t.translate(
bottomRight.x() < width() ? - (bottomRight.x() - width())  / _currentScale : 0,
bottomRight.y() < height() ? -(bottomRight.y() - height()) / _currentScale : 0
);
setTransform(t, true);
}
}

QRect pixmapRect = viewportTransform().mapRect(_pixmapRect);
_posLabel->setText(QString("%1,%2 %3x%4\nscale: %5")
.arg(pixmapRect.x()).arg(pixmapRect.y()).arg(pixmapRect.width()).arg(pixmapRect.height())
.arg(QString::number(_currentScale, 'f', 2)));
}

void mouseMoveEvent(QMouseEvent* event) override
{
if (!_isPanning)
return;
QPointF delta = mapToScene(event->pos()) - mapToScene(_lastMousePos);
QTransform t;
t.translate(delta.x(), delta.y());
setTransform(t, true);
centerScene();
_lastMousePos = event->pos();
event->accept();
}

void mousePressEvent(QMouseEvent* event) override
{
if (event->button() == Qt::LeftButton)
{
_isPanning = true;
_lastMousePos = event->pos();
setCursor(Qt::ClosedHandCursor);
event->accept();
}
}

void mouseReleaseEvent(QMouseEvent* event) override
{
if (event->button() == Qt::LeftButton)
{
_isPanning = false;
setCursor(Qt::ArrowCursor);
event->accept();
}
}

void wheelEvent(QWheelEvent* event) override
{
// Store cursor position relative to scene
QPointF mousePos        = event->position(),
mousePosCurrent = mapToScene(mousePos.x(), mousePos.y());

// Calculate zoom factor
double factor = pow(1.5, event->angleDelta().y() / 240.0);
double newScale = _currentScale * factor;
if (newScale < 1.) { // Do not allow zooming out (in absolute)
factor /= newScale;
newScale = 1.;
}
else if (newScale > 50.) { // Do not allow zoom > 50x
factor = factor * 50. / newScale;
newScale = 50.;
}

// Zoom centered on the mouse cursor
QTransform t;
t.translate(mousePosCurrent.x(), mousePosCurrent.y());
t.scale(factor, factor);
t.translate(-mousePosCurrent.x(), -mousePosCurrent.y());
setTransform(t, true);

_currentScale = newScale;
centerScene();

event->accept();
}
};

class Widget : public QWidget
{
public:
QPixmap _pixmap;
Widget() : QWidget(nullptr)
{
QPixmap pixmap("image.png"); // image.png: https://i.imgur.com/BGZ1jdy.png
QSize size = pixmap.size();
setFixedSize(size);
QLabel* label = new QLabel(this);
label->setFixedSize(size);
label->setPixmap(pixmap);
GraphicsView* view = new GraphicsView(this, pixmap);
emit view->findChild()->valueChanged(0);
}
};

int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post