views:

705

answers:

2

I'm subclassing QProgressBar in a custom widget, and I overwrote the paintEvent method with the following code :


void myProg::paintEvent(QPaintEvent *pe)
{
    QProgressBar::paintEvent(pe);
    QRect region = pe->rect();
    QPainter *painter = new QPainter(this);
    QPen *pen = new QPen;
    painter->begin(this);
    painter->setBrush(Qt::red);
    int x = this->x();
    int y = this->y();
    pen->setWidth(10);
    painter->setPen(*pen);
    painter->drawLine(x,y,x+100,y);
    painter->end();

}

I'm trying to display a red line, as a starting point, to see that I can add my own modifications to the widget. However, this isn't working. I only see the widget as a regular QProgressBar. Any ideas on what could be wrong ?

+1  A: 

Just a few comments about what you've wrote:

  1. The way you constructed the painter QPainter(this) means you don't need to explicitly call begin() and end(), QT takes care of that for you.
  2. With that in mind, the destructor never gets called, this will leak a bunch of memory due to all the new QPainters.
  3. I'm pretty sure this->x() and this->y() return the top left corner of the window, but you should still see a red line, 5 pixels wide, at the top of the window.

When you set the QPainters brush, try using the QBrush constructor explicitly, as in painter->setBrush( QBrush(Qt::red) );

spbots
+4  A: 

The coordinate system you need to use is relative to the top-left of the widget, but you're apparently using one relative to the widget's parent. (Widget's x and y coords are relative to their parent). So your line will be getting clipped.

Also, it's unnecessary to call QPainter::begin and QPainter::end when you construct it using a QWidget * parameter. And the painter in your code doesn't get deleted, either. It's not necessary to create a painter on the heap with new: I'd just create it on the stack.

Try:


void myProg::paintEvent(QPaintEvent *pe)
{
    QProgressBar::paintEvent(pe);
    QRect region = pe->rect();
    QPainter painter(this);
    QPen pen(Qt::red); //Note: set line colour like this

    //(Brush line removed; not necessary when drawing a line)
    int x = 0; //Note changed
    int y = height() / 2; //Note changed
    pen.setWidth(10);
    painter.setPen(pen);
    painter.drawLine(x,y,x+100,y);

}

This should draw a red horizontal line 100 pixels long starting from the middle-left of the widget.

Doug
Is it possible to set a debug flag of some sorts that will say if something gets shown on the screen or not ?
Geo
Geo: I don't think there's a debug flag. There are a couple of things you can do if you're worried that this might be a problem in future. You can try to e.g. draw a big red box over your widget from -10000, -10000 to 10000, 10000 hoping that you see something, and then change your code until you can't see output any more. You can also try getting the clipping region or clipping path from the QPainter and printing out their bounding rectangles, checking to see if the coordinates are close to what you think.
Doug