Reputation: 10939
I'm having troubles forcing a repaint/update of my Qt Widget (it extends the QGraphicsView
class). What I want is a rectangular selection box to be drawn which will highlight the target selection area as the user presses and moves the mouse.
The basic workflow:
making_selection_box
flag, and stores the start point (working).making_selection_box
is reset. Screen should be updated to remove the selection box artifact (not working).The overrided mouseMoveEvent:
void QSchematic::mouseMoveEvent(QMouseEvent *event)
{
if(making_selection_box)
{
// get selection box
qDebug() << "updating selection box";
curr_selection_end = event->pos();
repaint(box(drag_select_start, curr_selection_end));
}
// propogate event
QGraphicsView::mouseMoveEvent(event);
}
My overrided paintEvent:
void QSchematic::paintEvent(QPaintEvent *event)
{
qDebug() << "paintEvent";
if(making_selection_box)
{
qDebug() << "drawing selection box";
QPainter painter(viewport());
painter.setPen(Qt::black);
painter.drawRect(box(drag_select_start, curr_selection_end));
painter.end();
}
// propogate event
QGraphicsView::paintEvent(event);
}
Box is just a small helper function I wrote to create the correct QRect for different selection box start/end points.
static QRect box(const QPoint& p1, const QPoint &p2)
{
int min_x = p1.x();
int min_y = p1.y();
int max_x = p2.x();
int max_y = p2.y();
if(max_x < min_x)
{
max_x = min_x;
min_x = p2.x();
}
if(max_y < min_x)
{
max_y = min_y;
min_y = p2.y();
}
return QRect(min_x, min_y, max_x - min_x, max_y - min_y);
}
I've verified that mouseMoveEvent is being triggered correctly when the user presses a button and moves the mouse around.
I've also verified that paintEvent is being called by the system when I perform various standard operations such as resize the window, minimize/maximize it, etc.
I've verified that the method I'm using to paint to my widget will work correctly with other paintEvent triggers, I just can't manage to trigger a repaint in my code.
I've also tried forcing the update by using the update()
method instead of repaint()
, but no luck.
As a side note, am I going about creating this selection box functionality the wrong/hard way? Is there a better way to get a selection box without having to manually implement the mouse listeners and painting code?
I'm testing with Qt 4.8.4 on Windows 7 x64, using the Visual Studio 2010 MSVC compiler.
Upvotes: 2
Views: 900
Reputation: 10939
After looking through the QGraphicsScene API I found an easy workaround for having to manually manage the selection box: The drag mode needs to be set to RubberBandDrag
.
edit:
To further expand my answer which allows painting on the QGraphicsView for other purposes, it's the viewport which needs to receive the update/redraw, not my QGraphicsView object.
void QSchematic::mouseMoveEvent(QMouseEvent *event)
{
if(making_selection_box)
{
// get selection box
qDebug() << "updating selection box";
curr_selection_end = event->pos();
viewport()->repaint(box(drag_select_start, curr_selection_end));
}
// propogate event
QGraphicsView::mouseMoveEvent(event);
}
Upvotes: 1