Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 2

Qt-interest Archive, August 2007
Re: Repainting without erasure


Message 1 in thread

Hello,
Thanks a lot Thomas for your app (I learnt a lot from it) and sorry for 
taking a bit too long to get back to you (I got busy with other stuff).
Being a newbie switching from Tcl/Tk, I have this problem: I currently 
have a client program that reads some data from a server and it keeps
looping while it waits for data from the server. Something like this (in 
the main thread):

for(;;)
     {
     data.read();
     double xpos = data.GetXPos();
     double ypos = data.GetYpos();
     }


Assuming all the data that we get from the server is the 
x & y position of a point (at some rate, say 5 Hz) and I want to draw 
those points on a window, MyWidget, what is a simple way to plot those 
points on a window? I mean, since if I call app.exec() the rest of the 
program will not executed until I call app.exit(), do I have to execute 
the rest of the code in a separate thread?


Thanks,
Ernest

On Mon, 30 Jul 2007, Thomas Lübking wrote:

> upps, you ended up in spam suspect...
>
> attached is a small app that paints accumulative using
> Qt::WA_PaintOutsidePaintEvent
>
> Thomas
>
> Am Sonntag, 29. Juli 2007 15:06 schrieb Ernest G Ngaruiya:
>> For some reason (I'm on X11), nothing is painted on the widget when I set
>> Qt::WA_PaintOutsidePaintEvent. I will try your last idea (QPixmap) and see
>> if works.
>>
>> Regards,
>> Ernest
>>
>> On Sat, 28 Jul 2007, Thomas Lübking wrote:
>>> tried QWidget::setAttribute(Qt::WA_OpaquePaintEvent) ?
>>> but you'll really have to paint the whole widget then (care about
>>> background etc.)
>>>
>>> MIGHT be QGraphicsView has improved support for this functionality ..
>>> (but i really don't know)
>>>
>>> If you only on X11, you can also abuse Qt::WA_PaintOutsidePaintEvent
>>> (you can then write your own myRepaint() that operates without using
>>> paintevents, open a painter on the widget and paint it witout any erasure
>>> - but that's hackish ;)
>>>
>>> if nothing else helps, you could try keeping an offscreen buffer
>>> (QPixmap) and map that onto the widget on paintevents (that's similar to
>>> the above solution, but works everywhere)
>>>
>>> Thomas
>>>
>>> Am Samstag, 28. Juli 2007 01:09 schrieb Ernest G Ngaruiya:
>>>> Hello,
>>>> I am very new to Qt. What I'm trying to do is simple: make a window with
>>>> methods for drawing and erasing lines and rectangles. Since speed is
>>>> key, and to do away with flickering, I need to be able to draw and
>>>> redraw specific rectangles or lines without repainting the entire
>>>> widget. The window class' member functions should be callable by client
>>>> programs.
>>>>
>>>> What I'm doing currently is, I have functions that change global
>>>> line/rectangle dimension varialbles and then call repaint(const QRect
>>>> &r), repaint ( int x, int y, int w, int h ) or repaint ( const QRegion &
>>>> rgn ).
>>>>
>>>> The paintEvent function then does stuff according to whether certain
>>>> global variables evaluate to true or false. The problem is that, even if
>>>> I call repaint ( const QRegion & rgn ), it erases the entire window. For
>>>> example, if I write these simple functions and call them for another
>>>> program:
>>>>
>>>> /*_________________________________________
>>>>       begin example snippet */
>>>>
>>>> //a line is a actually a rectangle (for my own purposes)
>>>>
>>>> void window::drawline(int x1,int y1,int x2,int y2,int r,int g,int b)
>>>> {
>>>> toDo = 1; //paintEvent checks this variable and draws a line if toDo ==
>>>> 2 xx1 = x1;
>>>> xx2 = x2;
>>>> yy1 = y1;
>>>> yy2 = y2;
>>>> color = QColor(r,g,b);
>>>> repaint(QRegion(xx1,yy1,xx2,yy2));
>>>> }
>>>>
>>>>
>>>> void window::drawrect(int x1,int y1,int x2,int y2,int r,int g,int b)
>>>> {
>>>>    toDo = 2;  //similarly, paintEvent draws a rect if toDo is == 3
>>>>    xx1 = x1;
>>>>    xx2 = x2;
>>>>    yy1 = y1;
>>>>    yy2 = y2;
>>>>    color = QColor(r,g,b);
>>>>    repaint(QRegion(xx1,yy1,xx2,yy2));
>>>> }
>>>>
>>>> void DrawingWindow::paintEvent(QPaintEvent *)
>>>> {
>>>>    QPainter painter(this);
>>>>    switch (toDo)
>>>>      {case 3: //draw rect
>>>>        painter.setPen(Qt::NoPen);
>>>>        painter.setBrush(color);
>>>>        painter.drawRect(QRect(xx1,yy1,xx2,yy2));
>>>>        break;
>>>>       case 4: //eraseRect
>>>>        painter.eraseRect(QRectF(xx1,yy1,xx2,yy2));
>>>>        break;
>>>>
>>>>     //......................
>>>>
>>>> /* end example snippet
>>>> _____________________________________________ */
>>>>
>>>>
>>>> If I call drawline() first then drawrect(), the line is erased and I can
>>>> only see the rectangle. I don't want to erase anything unless the client
>>>> program calls window.eraserect(). Is there a way to do this?
>>>>
>>>> Thanks,
>>>> Ernest
>>>>
>>>> --
>>>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
>>>> "unsubscribe" in the subject or the body. List archive and information:
>>>> http://lists.trolltech.com/qt-interest/
>>>
>>> --
>>> Fear... Fear attracts the fearfull.
>>> The strong. The weak. The innocent. The corrupt.
>>> Fear... Fear is my ally!
>>>
>>> --
>>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
>>> "unsubscribe" in the subject or the body. List archive and information:
>>> http://lists.trolltech.com/qt-interest/
>
> -- 
> Fear... Fear attracts the fearfull.
> The strong. The weak. The innocent. The corrupt.
> Fear... Fear is my ally!
>

Message 2 in thread

this time i forgot the group... tststs - getting older.
---------
You could implement the data poll in the widgets timerEvent() and 
widget->startTimer(ms) (if it's about humans, 40-50ms is a good value for 
"animations", 200 will provide ypu 5Hz, 20 should be the certainly available 
minimum) instead of running a global loop (Qt has one anyway) if there's no 
other reason to keep it in the main function.

(Of course the server and the client should be two processes or treads - 
otherwise they would not be client/server ;)

Thomas

--
 [ signature omitted ] 

Message 3 in thread

On Tue, 7 Aug 2007, Thomas Lübking wrote
> You could implement the data poll in the widgets timerEvent() and
> widget->startTimer(ms) (if it's about humans, 40-50ms is a good value for
> "animations", 200 will provide ypu 5Hz, 20 should be the certainly available
> minimum) instead of running a global loop (Qt has one anyway) if there's no
> other reason to keep it in the main function.
>
> (Of course the server and the client should be two processes or treads -
> otherwise they would not be client/server ;)

I was thinking of using signals and slots but your idea worked perfectly.

I think the only questions I have remaining in my mind are:

1)Is there a way to rotate the window system such that the origin is not 
at the top left corner but the bottom left corner?

2)It appears like the whole window gets erased everytime I minimise the 
window after painting using something like:

setAttribute(Qt::WA_PaintOutsidePaintEvent);
QPainter p();
p.setBrush(QColor(r,g,b));
p.drawPoint(x,y)
p.end();
setAttribute(Qt::WA_PaintOutsidePaintEvent, false);

Is there a particular reason why the whole window gets erased when I 
minimise it?

3)The member functions in the QPainter class e.g drawLine,drawPoint etc 
accept ints as parameters. Is there a way to make them accept doubles as 
well?


Thanks,
Ernest

> Am Dienstag, 7. August 2007 03:27 schrieben Sie:
>> Hello,
>> Thanks a lot Thomas for your app (I learnt a lot from it) and sorry for
>> taking a bit too long to get back to you (I got busy with other stuff).
>> Being a newbie switching from Tcl/Tk, I have this problem: I currently
>> have a client program that reads some data from a server and it keeps
>> looping while it waits for data from the server. Something like this (in
>> the main thread):
>>
>> for(;;)
>>      {
>>      data.read();
>>      double xpos = data.GetXPos();
>>      double ypos = data.GetYpos();
>>      }
>>
>>
>> Assuming all the data that we get from the server is the
>> x & y position of a point (at some rate, say 5 Hz) and I want to draw
>> those points on a window, MyWidget, what is a simple way to plot those
>> points on a window? I mean, since if I call app.exec() the rest of the
>> program will not executed until I call app.exit(), do I have to execute
>> the rest of the code in a separate thread?
>>
>>
>> Thanks,
>> Ernest
>>
>> On Mon, 30 Jul 2007, Thomas Lübking wrote:
>>> upps, you ended up in spam suspect...
>>>
>>> attached is a small app that paints accumulative using
>>> Qt::WA_PaintOutsidePaintEvent
>>>
>>> Thomas
>>>
>>> Am Sonntag, 29. Juli 2007 15:06 schrieb Ernest G Ngaruiya:
>>>> For some reason (I'm on X11), nothing is painted on the widget when I
>>>> set Qt::WA_PaintOutsidePaintEvent. I will try your last idea (QPixmap)
>>>> and see if works.
>>>>
>>>> Regards,
>>>> Ernest
>>>>
>>>> On Sat, 28 Jul 2007, Thomas Lübking wrote:
>>>>> tried QWidget::setAttribute(Qt::WA_OpaquePaintEvent) ?
>>>>> but you'll really have to paint the whole widget then (care about
>>>>> background etc.)
>>>>>
>>>>> MIGHT be QGraphicsView has improved support for this functionality ..
>>>>> (but i really don't know)
>>>>>
>>>>> If you only on X11, you can also abuse Qt::WA_PaintOutsidePaintEvent
>>>>> (you can then write your own myRepaint() that operates without using
>>>>> paintevents, open a painter on the widget and paint it witout any
>>>>> erasure - but that's hackish ;)
>>>>>
>>>>> if nothing else helps, you could try keeping an offscreen buffer
>>>>> (QPixmap) and map that onto the widget on paintevents (that's similar
>>>>> to the above solution, but works everywhere)
>>>>>
>>>>> Thomas
>>>>>
>>>>> Am Samstag, 28. Juli 2007 01:09 schrieb Ernest G Ngaruiya:
>>>>>> Hello,
>>>>>> I am very new to Qt. What I'm trying to do is simple: make a window
>>>>>> with methods for drawing and erasing lines and rectangles. Since speed
>>>>>> is key, and to do away with flickering, I need to be able to draw and
>>>>>> redraw specific rectangles or lines without repainting the entire
>>>>>> widget. The window class' member functions should be callable by
>>>>>> client programs.
>>>>>>
>>>>>> What I'm doing currently is, I have functions that change global
>>>>>> line/rectangle dimension varialbles and then call repaint(const QRect
>>>>>> &r), repaint ( int x, int y, int w, int h ) or repaint ( const QRegion
>>>>>> & rgn ).
>>>>>>
>>>>>> The paintEvent function then does stuff according to whether certain
>>>>>> global variables evaluate to true or false. The problem is that, even
>>>>>> if I call repaint ( const QRegion & rgn ), it erases the entire
>>>>>> window. For example, if I write these simple functions and call them
>>>>>> for another program:
>>>>>>
>>>>>> /*_________________________________________
>>>>>>       begin example snippet */
>>>>>>
>>>>>> //a line is a actually a rectangle (for my own purposes)
>>>>>>
>>>>>> void window::drawline(int x1,int y1,int x2,int y2,int r,int g,int b)
>>>>>> {
>>>>>> toDo = 1; //paintEvent checks this variable and draws a line if toDo
>>>>>> == 2 xx1 = x1;
>>>>>> xx2 = x2;
>>>>>> yy1 = y1;
>>>>>> yy2 = y2;
>>>>>> color = QColor(r,g,b);
>>>>>> repaint(QRegion(xx1,yy1,xx2,yy2));
>>>>>> }
>>>>>>
>>>>>>
>>>>>> void window::drawrect(int x1,int y1,int x2,int y2,int r,int g,int b)
>>>>>> {
>>>>>>    toDo = 2;  //similarly, paintEvent draws a rect if toDo is == 3
>>>>>>    xx1 = x1;
>>>>>>    xx2 = x2;
>>>>>>    yy1 = y1;
>>>>>>    yy2 = y2;
>>>>>>    color = QColor(r,g,b);
>>>>>>    repaint(QRegion(xx1,yy1,xx2,yy2));
>>>>>> }
>>>>>>
>>>>>> void DrawingWindow::paintEvent(QPaintEvent *)
>>>>>> {
>>>>>>    QPainter painter(this);
>>>>>>    switch (toDo)
>>>>>>      {case 3: //draw rect
>>>>>>        painter.setPen(Qt::NoPen);
>>>>>>        painter.setBrush(color);
>>>>>>        painter.drawRect(QRect(xx1,yy1,xx2,yy2));
>>>>>>        break;
>>>>>>       case 4: //eraseRect
>>>>>>        painter.eraseRect(QRectF(xx1,yy1,xx2,yy2));
>>>>>>        break;
>>>>>>
>>>>>>     //......................
>>>>>>
>>>>>> /* end example snippet
>>>>>> _____________________________________________ */
>>>>>>
>>>>>>
>>>>>> If I call drawline() first then drawrect(), the line is erased and I
>>>>>> can only see the rectangle. I don't want to erase anything unless the
>>>>>> client program calls window.eraserect(). Is there a way to do this?
>>>>>>
>>>>>> Thanks,
>>>>>> Ernest
>>>>>>
>>>>>> --
>>>>>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
>>>>>> "unsubscribe" in the subject or the body. List archive and
>>>>>> information: http://lists.trolltech.com/qt-interest/
>>>>>
>>>>> --
>>>>> Fear... Fear attracts the fearfull.
>>>>> The strong. The weak. The innocent. The corrupt.
>>>>> Fear... Fear is my ally!
>>>>>
>>>>> --
>>>>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
>>>>> "unsubscribe" in the subject or the body. List archive and information:
>>>>> http://lists.trolltech.com/qt-interest/
>>>
>>> --
>>> Fear... Fear attracts the fearfull.
>>> The strong. The weak. The innocent. The corrupt.
>>> Fear... Fear is my ally!
>
> -- 
> Fear... Fear attracts the fearfull.
> The strong. The weak. The innocent. The corrupt.
> Fear... Fear is my ally!
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
>