You are not logged in.

Dear visitor, welcome to QtForum.org. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

1

Monday, December 12th 2011, 4:20pm

[SOLVED] QGraphicsView->repaint() not working as expected???

Hello every one, for several days I have been trying to resolve my problem but without success. I have my class instance which does "tough" computations in a separate thread continually and a QT GUI App which displays the progress.

I made a Timer in GUI App which regularly sends signal to my class instance to stop computations for a while and to update the QGraphicsScene with freshly computed data (access to raw data structures is protected with QMutex). When it is done, my instance sends signal to GUI (QMainWindow). Now it is time to display new data with "ui->graphicsView->repaint()". But it happens only once - only the first time repaint() on QGraphicsView is called, the other calls do nothing - like they are never called...but they are!

I draw/create my visual data (many QGraphicsRectItem-s) on the QGraphicsScene only once - in the mainWindow constructor. After that when the signal from mainWindow comes I iterate over QList of items in the QGraphicsScene a change their color according to new data. QGraphicsScene is bind to QGraphicsView of the mainWindow in the mainWindow constructor.

I am sure that the process of changing the colors of QGraphicsRectItem-s is ok, signals a slots are functioning. What can be my problem???

EDIT: I am using Xubuntu 11.10, Qt Creator 2.2.1 based on Qt 4.7.4

EDIT2: MyClass is member variable in mainWindow and the computational process goes in separate thread.

some code...

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void MyClass::InitScene()
{
...
mScene = new QGraphicsScene();
QGraphicsRectItem * rect;
...
rect = new QGraphicsRectItem(x,y,a,b);
rect->setBrush(QColor(red,green,blue));
mScene->addItem(rect);
...
}

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
...
ui->graphicsView->setScene(MyClass->getScene());
...
QObject::connect(timer, SIGNAL(timeout()), MyClass, SLOT(sceneUpdateRequired()));
QObject::connect(MyClass, SIGNAL(sceneUpdated()), this, SLOT(slotRepaint()));
...
}

void MainWindow::slotRepaint()
{
qDebug() << "Repaint()";
ui->graphicsView->repaint();
}

void MyClass::sceneUpdateRequired()
{
qDebug() << "MyClass UpdateCanvas";
UpdateCanvas();
}

void MyClass::UpdateCanvas()
{
QGraphicsRectItem * el;
...
el = (QGraphicsRectItem*)mScene->items()[iter];
...
el->setBrush(QColor(newR, newG, newB));
...
emit(sceneUpdated());
}

This post has been edited 3 times, last edit by "juchuchuu" (May 18th 2012, 7:50pm)


2

Monday, December 12th 2011, 6:44pm

get more friendly with your debugger.

you say the repaint gets hit lots of times - does the rgb data actually chnage? have you checked the values in the debugger?

Also, if you do as per my sig, you might get more help and/or discover your error anyway by removing some superfluous (to this issue) code
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

3

Monday, December 12th 2011, 8:53pm

If you ask me:

1) I would not tell the scene when to repaint itself, it does know quite well when it has to repaint what. They are pretty smart together, QGraphicsScene and QGraphicsView... Use the QGraphicsScene (or its derivates) as container of different items. You can regard the scene as the parent of all items it consists of and it manages them for you.
2) Make use of inheritance. If you want to have a "custom" graphics item (like the QGraphicsRectItem) that changes its color and does some magic stuff, derive from QGraphicsRectItem and overload its paint() method. The items you add to the scene should know how to draw themselves.
3) Read the documentation and have a look at the test samples. Qt Graphics View Framework

If you want to change just a property of your custom item, create a slot CustomItem::changeProperty(...) and call this one by your timer.

4

Friday, December 16th 2011, 2:41pm

thank you very much for your comments

I optimized and restructured my code, replaced every float** XY with QList<QList<float> *> * XY (to be able to see them in debugger), read several articles about threading, signals, slots and found solution. One of the main problems was that rgb values actually did not change...
1) I would not tell the scene when to repaint itself, it does know quite well when it has to repaint what. They are pretty smart together, QGraphicsScene and QGraphicsView... Use the QGraphicsScene (or its derivates) as container of different items. You can regard the scene as the parent of all items it consists of and it manages them for you.
I will try it, thank you

juchuchuu

5

Friday, December 16th 2011, 2:50pm

get more friendly with your debugger.

you say the repaint gets hit lots of times - does the rgb data actually chnage? have you checked the values in the debugger?


One of the main problems was that rgb values actually did not change...


aha.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.