| Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date | |
| All threads index page 6 | |
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
--
[ signature omitted ]
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/
--
[ signature omitted ]
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/
>
>
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/
--
[ signature omitted ]
Attachment:
painttest.tar.bz2
Description: application/tbz
Hi Ernest, > 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 ). > You should not call repaint() if speed is important. Use update() with the same arguments instead. > 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: Could you run the program with QT_FLUSH_PAINT=1 set in your environment and confirm that the entire window is repainted? Areas that are repainted will then be flushed with yellow. -- [ signature omitted ]