我有一个用户界面,
N.2 QGraphicsView
N.3 QCheckBoxes如下所示:
我正在使用QWheelEvent
和键CTRL
来放大QGraphicsView的内部(左)。这部分效果很好。
我正在使用QWheelEvent
和ALT
键在QGraphicsView内部放大(右)。这部分有问题,因为它根本没有缩放。
当同时按下CTRL
和ALT
时,两个QGraphicsviews都应在我拥有鼠标的同一点处进行放大和缩小,但是缩放会将两个图像沿奇怪的方向移动。
以下列方式设置复选框: 一旦运行界面,左侧的QGraphicsView就已经处于“拖动模式”。当我单击复选框时,QGraphicsView变为可选状态,并且可以执行许多不同的操作。 正确的QGraphicsView也是如此。选中“缩放”复选框后,如果我在视图的正确方向上在感兴趣的区域中绘制一个矩形,它将进行缩放。但是,如果我在视图的左侧绘制一个矩形,它不会重置:
因此,除了QCheckbox
之外,我还希望能够使用QWheelEvent以及CTRL和ALT键进行放大,并且不确定该复选框是否以任何方式影响我的QWheelEvent。也许不是,问题仅仅是我实现QWheelEvent
的方式。
我不确定自己在做什么错,我读了this source,发现它很有用,但是并不能解决问题。 Also this对于理解QGraphicsView::scale()
功能很有用。
请阐明这件事。在描述问题的最重要的源代码下面:
mainwindow.h
private:
bool ctrl_down = false; // to check if CTRL is pressed
bool alt_down = false; // to check if ALT is pressed
protected:
void keyPressEvent(QKeyEvent *event);
void wheelEvent(QWheelEvent *event);
void keyReleaseEvent(QKeyEvent *event);
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->leftView->installEventFilter(this);
ui->rightView->installEventFilter(this);
}
void MainWindow::onRubberBandUpdate(const QRect &viewportRect, const QPointF &fromScenePoint, const QPointF &toScenePoint)
{
if(viewportRect.isNull() && fromScenePoint.isNull() && toScenePoint.isNull())
{
if(ui->zoomSelect->isChecked())
{
ui->leftView->fitInView(QRectF(start, end), Qt::KeepAspectRatio);
ui->rightView->fitInView(QRectF(start, end), Qt::KeepAspectRatio);
}
else
{
// Additional operations
}
}
else
{
start = fromScenePoint;
end = toScenePoint;
}
}
void MainWindow::on_leftSidePan_toggled(bool checked)
{
if(ui->leftSidePan->isEnabled())
{
if(checked)
{
ui->leftView->setDragMode(QGraphicsView::RubberBandDrag);
ui->leftSidePan->setText("Left: Select");
}
else
{
ui->leftView->setDragMode(QGraphicsView::ScrollHandDrag);
ui->leftSidePan->setText("Left: Drag");
}
}
}
void MainWindow::on_rightSidePan_toggled(bool checked)
{
if(ui->rightSidePan->isEnabled())
{
if(checked)
{
ui->rightView->setDragMode(QGraphicsView::RubberBandDrag);
ui->rightSidePan->setText("Right: Select");
}
else
{
ui->rightView->setDragMode(QGraphicsView::ScrollHandDrag);
ui->rightSidePan->setText("Right: Drag");
}
}
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Control) { ctrl_down = true; }
else if(event->key() == Qt::Key_Alt) { alt_down = true; }
}
void MainWindow::wheelEvent(QWheelEvent *event)
{
if(ctrl_down) // Only left zoom
{
ui->leftView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
ui->leftView->verticalScrollBar()->blockSignals(true);
ui->leftView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
QPointF pos = ui->leftView->mapToScene(event->pos());
double DELTA = 1.0 + event->angleDelta().y() / 1200.0;
QTransform xform = ui->leftView->transform();
xform.translate(pos.x(), pos.y()); // origin to spot
xform.scale(DELTA, DELTA); // scale
xform.translate(-pos.x(), -pos.y()); // spot to origin
ui->leftView->setTransform(xform);
ui->leftView->update();
event->accept();
}
else if(alt_down) // Only right zoom
{
ui->rightView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
ui->rightView->verticalScrollBar()->blockSignals(true);
ui->rightView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
QPointF posr = ui->rightView->mapToScene(event->pos());
double DELTAR = 1.0 + event->angleDelta().y() / 1200.0;
QTransform yform = ui->rightView->transform();
yform.translate(posr.x(), posr.y()); // origin to spot
yform.scale(DELTAR, DELTAR); // scale
yform.translate(-posr.x(), -posr.y()); // spot to origin
ui->rightView->setTransform(yform);
ui->rightView->update();
event->accept();
}
if(alt_down && ctrl_down) // Both zoom
{
ui->leftView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
ui->rightView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
ui->leftView->verticalScrollBar()->blockSignals(true);
ui->leftView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->rightView->verticalScrollBar()->blockSignals(true);
ui->rightView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// For the Left View
static const double scaleFactorTot = 1.1;
static double currentScaleTot = 1.0; // stores the current scale value.
static const double scaleMinTot = .1; // defines the min scale limit.
// For the Right View
static const double scaleFactorTotR = 1.1;
static double currentScaleTotR = 1.0; // stores the current scale value.
static const double scaleMinTotR = .1; // defines the min scale limit.
if(event->delta() > 0)
{
ui->rightView->scale(scaleFactorTotR, scaleFactorTotR);
currentScaleTotR *= scaleFactorTotR;
ui->leftView->scale(scaleFactorTot, scaleFactorTot);
currentScaleTot *= scaleFactorTot;
}
else if (currentScaleTot > scaleMinTot && currentScaleTotR > scaleMinTotR)
{
ui->rightView->scale(1 / scaleFactorTotR, 1 / scaleFactorTotR);
currentScaleTotR /= scaleFactorTotR;
ui->leftView->scale(1 / scaleFactorTot, 1 / scaleFactorTot);
currentScaleTot /= scaleFactorTot;
}
}
}
void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
if(event->key() == Qt::Key_Control) { ctrl_down = false; }
if(event->key() == Qt::Key_Alt) { alt_down = false; }
}