PaintEvent in Qt painting all widgets the same for each instance of the class [closed]

StackOverflow https://stackoverflow.com/questions/15464614

  •  24-03-2022
  •  | 
  •  

Pergunta

I have a class called MotionVectorDisplay which inherits from QWidget and I override the paintevent, what I do with this class is draw motion vectors for a pariticular macroblock which is 16x16 in size and there are multiple of these macroblocks in a frame so I create a new instance of this class for each macroblock, pass in multiple parameters for building the motion vectors and parent that widget to another widget for displaying. This all works as expected but I get output like this frame

It seems to me that when the paintevent is called it remembers the last time the paint event is called and keeps the drawn lines and creates the ugly mess that is there in the picture, that should show a few lines for a few macroblocks not all of them. This is the code

mv = new MotionVectorDisplay(pics[frameCounter].motionVect, 
                             pics[frameCounter].subMotionVector,
                             macBlockParent);
mv->stackUnder(cooefsLink);
QGraphicsOpacityEffect* effect = 
        new QGraphicsOpacityEffect(mv);
effect->setOpacity(0.9);
mv->setGraphicsEffect(effect);
if(mvToggle->checkState() == Qt::Checked)
{
    mv->show();
}
else
{
    mv->hide();
}
motionVectorsContain.push_back(mv);

That constructs the macroblock in the MainWindow class, this is the constructor and PaintEvent from the MotionVectorDisplay class

MotionVectorDisplay::MotionVectorDisplay(const pair<string, string>& motionVect,
                                         const vector<pair<string, string> >& subMotionVect,
                                         QWidget* parent)
                                         : QWidget(parent)
{
    this->setFixedSize(16, 16);
    this->setStyleSheet("background-color: transparent;");
    motionVectors = &motionVect;
    subMotionVectors = &subMotionVect;
}

void MotionVectorDisplay::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setPen(QPen(Qt::black, 1.5));

    for(int subMotVects = 0; subMotVects < subMotionVectors->size(); subMotVects++)
    {
        string x = subMotionVectors->at(subMotVects).first;
        string y = subMotionVectors->at(subMotVects).second;
        if(subMotVects == 0)
        {
            painter.drawLine(0, 0, atoi(x.c_str()), atoi(y.c_str()));
        }
        else if(subMotVects == 1)
        {
            painter.drawLine(4, 4, atoi(x.c_str()), atoi(y.c_str()));
        }
        else if(subMotVects == 2)
        {
            painter.drawLine(8, 8, atoi(x.c_str()), atoi(y.c_str()));
        }
        else
        {
            painter.drawLine(12, 12, atoi(x.c_str()), atoi(y.c_str()));
        }
    }
}
Foi útil?

Solução

I suspect that you need to set the OpaquePaintEvent flag on your widget to false:

this->setAttribute(Qt::WA_OpaquePaintEvent, false);

Alternatively (and more commonly), you'd repaint every pixel of your widget in every paint event so that it essentially writes over anything that was painted there before, something like this at the beginning of your paint event:

painter.setBrush( Qt::black ); // Or whatever your background color is
painter.drawRect( rect() );
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top