У меня есть «стандартное» приложение QW5 Qt5 с MainWindow, которое включает QGraphicsView в mainwindow.ui, созданном в QtCreator.Этот QGraphicsView имеет свою сцену, установленную на простой подкласс QGraphicsScene, который имеет большой прямоугольник на заднем плане, который является подклассом QGraphicsRectItem, который переопределяет обработчики mousePressEvent () и mouseReleaseEvent () QGraphicsRectItem.Запуск на Ubuntu 18.04, который не должен иметь значения, но только в случае ...
Все работает, кроме ... 2-го и последующих раз, когда я нажимаю левую (или любую) кнопку мыши, сообщаются координатыв QGraphicsSceneMouseEvent mousePressEvent buttonDownScenePos «устарели» - так же, как и предыдущий щелчок мыши, а не в новом месте, где находится мышь, когда произошел новый щелчок.MouseReleaseEvent сообщает координаты, как и ожидалось.
Есть ли способ получить buttonDownScenePos mousePressEvent, чтобы он оставался текущим с фактическим положением мыши при нажатии вместо прежнего местоположения мыши?
Мне кажется, что в прошлом я сталкивался с подобной проблемой, которая имела отношение к обработке двойного щелчка, что событие сообщается до того, как он узнает, произошел двойной щелчок или нет.В этом случае события двойного щелчка не важны, но было бы неплохо иметь возможность отвечать на один щелчок, как только это произойдет, вместо того, чтобы ждать события выпуска.
Соответствующий код:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
class Board;
class BoardScene;
#include <QMainWindow>
#include <QPointer>
#include "board.h"
#include "boardscene.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{ Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void drawBoard();
private:
Ui::MainWindow *ui;
QPointer<Board> board;
QPointer<BoardScene> boardScene;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
board = new Board( this );
boardScene = new BoardScene( board, this );
ui->boardView->setScene( boardScene );
ui->boardView->setDragMode( QGraphicsView::ScrollHandDrag );
ui->boardView->scale( 40.0, 40.0 );
drawBoard();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::drawBoard()
{ }
boardscene.h
#ifndef BOARDSCENE_H
#define BOARDSCENE_H
class Board;
#include <QGraphicsScene>
#include "board.h"
#include "boardrect.h"
class BoardScene : public QGraphicsScene
{ Q_OBJECT
public:
BoardScene( Board *pbp, QObject *parent = nullptr );
void drawGrid();
Board *bp;
QBrush backBrush,blackBrush,whiteBrush;
QPen linePen;
};
#endif // BOARDSCENE_H
boardscene.cpp
#include "boardscene.h"
#include <QGraphicsLineItem>
#include <QGraphicsRectItem>
BoardScene::BoardScene( Board *pbp, QObject *parent ) : QGraphicsScene ( parent )
{ bp = pbp;
backBrush = QBrush( QColor( 224,152, 64 ) );
blackBrush = QBrush( QColor( 0, 0, 0 ) );
whiteBrush = QBrush( QColor( 255,255,255 ) );
linePen = QPen ( QColor( 0, 0, 0 ) );
linePen.setWidth( 0 );
drawGrid();
}
void BoardScene::drawGrid()
{ QGraphicsLineItem *lip;
BoardRect *rip;
setBackgroundBrush( blackBrush );
rip = new BoardRect( QRectF( -2.0, -2.0, (qreal)(bp->Xsize +3), (qreal)(bp->Ysize + 3) ), nullptr );
rip->setBrush( backBrush );
rip->setPen( linePen );
addItem( rip );
for ( int x = 0; x < bp->Xsize; x++ )
{ lip = addLine( QLineF( (qreal)x, 0.0, (qreal)x, (qreal)(bp->Ysize - 1) ), linePen );
lip->setAcceptedMouseButtons( Qt::NoButton );
}
for ( int y = 0; y < bp->Ysize; y++ )
{ lip = addLine( QLineF( 0.0, (qreal)y, (qreal)(bp->Xsize - 1), (qreal)y ), linePen );
lip->setAcceptedMouseButtons( Qt::NoButton );
}
}
boardrect.h
#ifndef BOARDRECT_H
#define BOARDRECT_H
#include <QGraphicsRectItem>
#include <QGraphicsSceneMouseEvent>
class BoardRect : public QGraphicsRectItem
{
public:
BoardRect( const QRectF &rect, QGraphicsItem *parent = nullptr );
~BoardRect() {}
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event);
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
};
#endif // BOARDRECT_H
boardrect.cpp
#include "boardrect.h"
BoardRect::BoardRect( const QRectF &rect, QGraphicsItem *parent ) : QGraphicsRectItem( rect, parent )
{}
void BoardRect::mousePressEvent(QGraphicsSceneMouseEvent *event)
{ QString msg = QString("press %1 %2").arg(event->buttonDownScenePos(event->button()).rx())
.arg(event->buttonDownScenePos(event->button()).ry());
qDebug( qPrintable( msg ) );
QGraphicsRectItem::mousePressEvent(event);
event->accept();
}
void BoardRect::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{ QString msg = QString("release %1 %2").arg(event->buttonDownScenePos(event->button()).rx())
.arg(event->buttonDownScenePos(event->button()).ry());
qDebug( qPrintable( msg ) );
QGraphicsRectItem::mousePressEvent(event);
event->accept();
}
При первом щелчке после запуска сообщенные координаты хорошо согласуются с местоположением в сетке, где была нажата мышькак для нажатия, так и для отпускания - они оба показывают, где кнопка была нажата.
Однако при втором и последующих щелчках mousePressEvent сообщает те же координаты, что и предыдущие события mousePress и Release, а mouseReleaseEvent сообщаеткоординаты, где кнопка мыши «пошла вниз» в текущем событии.
Последний бит странности: при нажатии влево, затем вправо, затем снова влево координата, сообщаемая mousePressEvent для 2-го левого щелчка - это предыдущая координата левого щелчка, пропуская координату правого щелчка, чтобы вернуться туда, где кнопка мыши нажала последний левый щелчок.
Есть идеи?Спасибо.