PDA

View Full Version : Delays in processing events



Caius Aérobus
5th April 2006, 15:30
Hello,
I just draw some rectangles in a painter and I want to be able to move the rectangles. The coordinates data are stored using a QAbstractItemModel.
I have a paint code as below:

void
vadControlPolygon::paintEvent(QPaintEvent *event)
{
QPainter painter(this->viewport());
painter.setWindow(0, 0, 100, 100);
QStyleOptionViewItem option;
painter.eraseRect(painter.viewport());
// getchar() // with this line the drawings update!
// les sommets
for (int i=0 ; i<3 ; i++)
this->itemDelegate()->paint(&painter, option, this->model()->index(i, 0));
}

the painting itself being delegated, as you can see.
Now I code the mouse moving event processing as below:

void
vadControlPolygon::mouseMoveEvent(QMouseEvent *e)
{
// check if we are moving any rectangle
if (!this->index.isValid())
return;
// update the model data
this->model()->setData(this->index, this->model()->data(this->index).toInt() +
(e->pos().x() - this->lastx) * 100 / this->width());
QModelIndex idx(this->index.sibling(this->index.row(), 1));
this->model()->setData(idx, this->model()->data(idx).toInt() +
(e->pos().y() - this->lasty) * 100 / this->height());
// emit that signal, which has been connected to the paintEvent() slot
emit repaint(new QPaintEvent(QRect()));
// remember the current pointer position
this->lastx = e->pos().x();
this->lasty = e->pos().y();
}

the mouse press and release event handling is not here but you can imagine what it does.

So my problem is that the painting does not change BUT if I add some kind of delay in the paintEvent() code, such as a getchar() (see the code, the getchar() is commented), the painting is updated just after the getchar() has been executed. The new figure then corresponds to the current situation, that is after all the remaining mouse move events have been processed (it means that the figure is suddenly changed, the intermediate drawings do not appear).
So could it be a problem of several events of the same type arriving in a delay too short for them to be processed? any such experience among you Qt users?

vratojr
5th April 2006, 15:47
// emit that signal, which has been connected to the paintEvent() slot
emit repaint(new QPaintEvent(QRect()));


Hi,PaintEvent is not a slot, you cannot connect a signal to it. Try to call update() instead.

Caius Aérobus
5th April 2006, 15:51
but the signal-slot connection is not the problem: it works! I have replace the emit command but update() but same result, the problem is not here.

jpn
6th April 2006, 22:13
Well, I must say, the updating mechanism of yours is really wicked..

All you really need is:


// member variables:
// QPoint offset;
// QPersistentModelIndex index;

void RectView::mousePressEvent(QMouseEvent* e)
{
index = indexAt(e->pos());
offset = index.data().toRect().topLeft() - e->pos();
}

void RectView::mouseMoveEvent(QMouseEvent* e)
{
if (index.isValid())
{
QRect r = index.data().toRect();
r.moveTopLeft(e->pos());
r.translate(offset);
model()->setData(index, r);
}
}

void RectView::mouseReleaseEvent(QMouseEvent* e)
{
index = QPersistentModelIndex();
}

void RectView::paintEvent(QPaintEvent* e)
{
QAbstractItemView::paintEvent(e);
QPainter painter(viewport());
setDirtyRegion(viewport()->rect());

for (int row = 0; row < model()->rowCount(); ++row)
{
for (int col = 0; col < model()->columnCount(); ++col)
{
QModelIndex index = model()->index(row, col, QModelIndex());
itemDelegate()->paint(&painter, QStyleOptionViewItem(), index);
}
}
}

Caius Aérobus
7th April 2006, 10:32
Thanks very much for your help. ALL my problems (view update from model and delays) have been solved simply by adding the following line:
setDirtyRegion(viewport()->rect());
A last question: why keeping a persistent model index at the end of the move process??
index = QPersistentModelIndex();
Regards.

jpn
7th April 2006, 11:07
I'm not sure if it really matters in this case, but


From QModelIndex docs:
Model indexes can become invalid over time so they should be used immediately and then discarded. If you need to keep a model index over time use a QPersistentModelIndex.

wysota
7th April 2006, 12:42
It matters if items are added or removed as their coordinates change then. In this situation it would be required to use persistent indexes if an item could be added or removed while the mouse was being dragged.


but the signal-slot connection is not the problem: it works! I have replace the emit command but update() but same result, the problem is not here.

It works because emit xxx() is changed into xxx() (as "emit" just gets ignored by the compiler), so if you "emit" a function, it'll just get called. I guess moc could report such wicked behaviours (at least warn about them) but they are harmless. It just makes the code more "wicked" ;)