PDA

View Full Version : Problem with QScrollview and QPainter



saida
28th February 2006, 12:23
Hi,
Iam having a problem with the usage of QScrollView and QPainter.
Iam using Qt 3.3.4 on a solaris machine. My application requires
to parse a log file and generate graph from it. The problem is that
the drawContents method is drawing the graph more than once because
of which the graph is overwriting from the top once it has reached
the area that has been set using resizeContents.

I have also set the size based on the size of the file.
But nothing has changed. Iam sending you the part of the code:


void drawContents(QPainter *p,int cx,int cy,int cw,int ch)
{
//opens the file for reading
//TextStream is created for reading

while(!stream.atEnd())
{
//Each line is read
//parsing is done
//Graph is drawn
}

//file is closed
resizeContents(7000,gy);
//lines are drawn vertically to avoid erasing
}

Note:: In the above program, gy is declared as "int" holds the y-coordinate
till where the line is to be drawn.It is incremented by 20 each time in the
loop.

I have tried other options like resizing the contents before the drawContents , even in this case also the behaviour the same.

So, Kindly help me out from this problem because of which my application
got struck.

Thanks in advance.

with regards,
Saida

zlatko
28th February 2006, 12:46
I have tried other options like resizing the contents before the drawContents , even in this case also the behaviour the same.


Are you sure? That must be helpfull :rolleyes:
Where did you call resizeContents()?

saida
28th February 2006, 13:34
hi,
Thanks for replying soon. Earlier I have called the resizeContents in the constructor with some area. Then I placed it based it on the size of the file that iam parsing, at the end of drawContents.
It goes like this:


class ScrollDemo::public QScrollView
{
public:
void ScrollDemo(....)
{ }

protected:
void drawContents(.....)
{
//here all the coding which I mentioned previously

//end of while loop
//closing of the file
long unsigned int kount1= kount*20+150;
resizeContents(7000,kount1);
}
};

Note:: Here kount is the variable used to count the no.of lines that iam drawing on the Scroll area
and each line is drawn by incrementing the y-coordinate by 20.
Hence kount1 holds the total area that is to be resized.

Another important thing that I would like to mention is that for small to medium sized files, this code is working perfectly. For large files, I couldn't find any solution.

Eagerly waiting for ur reply,
Saida.

wysota
28th February 2006, 13:36
You should read the contents of the file in some other method, because now each time the window redraws, the file is reread, which is a big overhead. After reading the file, you can set the proper size of the scrollview's viewport and the call update() which will in turn call drawContents and there you should draw the data which is already stored somewhere in your application.

saida
28th February 2006, 13:48
Hi Wysota,

Thanks for the information that u have given. The problem in this is that I need to draw the
graph as and when I get the blocks in each line. And If I do these things outside the drawContents method, I need to store the blocknames, signal name, positions of the blocks from where I need to draw the lines in the graph, which will be a tough task.
Because, the best way of storing all this is again a file which i need to open again in drawContents method.
sorry if I couldn't understand your suggestion. If it is so, please be more clear ( like show me the outline of the code that u want me to follow ).

Thanks once again,
saida.

wysota
28th February 2006, 14:44
The best way of storing things is in data structures, such as a list of classes or whatever. Files are too slow for that. If you want to read the file each time the widget is redrawn, you'll end up reading that file all the time.

When the contents change, just reread the file once to update your data structures and then tell the widget to update itself and in drawContents just use that stored data to draw your widget.

saida
1st March 2006, 07:18
hi wysota,
I followed what you have suggested. Now it is responding little fast. My problem is that the application is drawing the graph multiple times. Because of this, it is drawing the contents from the top once it has reached the end of scroll area that has been set using resizeContents(). This time I have changed the code as:


class ScrollViewDemo : public QScrollView
{
public :
ScrollViewDemo(...)
{
//parsing of the file
//resizeContents( width, height );
updateContents(0 , 0 , width, height );
}

protected:
void drawContents(.....)
{
// drawing of the graph using the values stored in the variables
}
};

Not:e: If I comment the updateContents() line, I couldnot find any change in the graph.

Kindly help me out of this problem.

Thanks a lot,
saida

wysota
1st March 2006, 07:51
My problem is that the application is drawing the graph multiple times. Because of this, it is drawing the contents from the top once it has reached the end of scroll area that has been set using resizeContents().

Could you explain a bit more? How does it draw from the top once it reaches the end of scroll area? A screenshot would be nice...

saida
1st March 2006, 10:03
Wyosta,
Iam sending you the snapshots of the graph that is a part of my application.

I am sending you three snapshots:

1) The first one is the graph generated for a small file and is perfect
without any problem. (small.gif)
2) The second one is for a big file where the overlap is shown. (large1.gif)
3) The third one is also the graph generated for the above file and shows the
position where it is drawing for the second time. From here, the graph is
redrawn and continues from the top once it has reached the end of area that
has been set. (large2.gif)

Kindly read the format of the code (which I have sent previously) before seeing
these snaps for clear idea of my problem.

One more thing I would like to know is that Iam setting the area as:

long unsigned int kount1=(kount*20)+150;
resizeContents(7000,kount1);

where kount holds the no.of lines that are to be represented on the graph.And each line
is drawn by incrementing the y-coordinate by 20. And I saw the syntax of resizeContents
where the parameters are integers. So, can you tell me would there be any problem
with above usage. ( kount is declared as "int" only)


I'll be waiting for your reply.

Thanks,
saida.

wysota
6th March 2006, 11:24
Could you show the code used for plotting the graph? I mean the contents of the loop which originally was:


while(!stream.atEnd())
{
//Each line is read
//parsing is done
//Graph is drawn
}

Especiall that "graph is drawn" part :)

Sarma
6th March 2006, 11:33
Sir,
Thanks once again for your immediate response. well, the parsing is done on what we call the log files and each line of the file contains different blocks which are shown over the gray line in the snaps. And the code is somewhat big(over 600 lines). And you also need the files to understand the code and the graph that has been generated. Shall I send a sample file( whose graph is sent previously:: small.gif )?

Important thing to note is that Iam able to get the graph for small files but not for larger ones.

wysota
6th March 2006, 12:20
It would be best if you sent a compilable example with example data so that I could compile and run it on my machine.

Sarma
6th March 2006, 12:59
That would be better. Iam sending you again two files and the complete code. These are the files that iam sending:

small.txt (that contains the small file for which small.gif is sent).
large.txt ( that contains the large file for which large.gif is sent) and
source.cpp ( where the code has been written).

Note: The "/tmp/parsetext.txt " in the code at any time contains the file for which graph has to be generated. And sir, I have not changed the code as you said previously (reading the file in another method). I have tried that but I faced the same problem of over-writing for large files. Kindly take time to see this and help me in what ever way possible.

Thanks alot for your co-operation.
with regards,
sarma.

wysota
6th March 2006, 18:11
Ok, I think I might have found your problem. As far as I remember there exists a maximum size of a widget under X11. I don't remember the exact size, but it's probably around 64k (or less) and I see you are trying to obtain greater heights which probably causes an overflow of some variable resulting in y values being y = kount1 % maxheight.

So having found the bug is one thing, but working it around is another. In your case, you can either switch to Qt4 (which, afair has a workaround for this) or make a fake scrollview. Instead of having a very big viewport, have a regular widget which will change its contents according to scrollbar values. Meaning you'll have to implement paintEvent in such a way, that is renders only a part of your chart which should currently be visible. You could also check if QCanvasView has the same limitations.

A side effect will be that your widget should redraw much faster.

Sarma
7th March 2006, 06:14
Sir,
What you said might be correct. But Iam a novice in QtProgramming. So I don't know how to fix this problem . I shall be greatful to you if you help me in this regard.This is the only problem that Iam having since 3 weeks. Presently Iam trying it with QCanvasView.

Thanks alot,
Sarma.:(