Qt中的PaintEvent为类的每个实例绘制所有小部件相同[关闭]

我有一个名为MotionVectorDisplay的类,它继承自QWidget并且我重写了paintevent,我对这个类做的是绘制一个大小为16x16的pariticular宏块的运动矢量,并且在一个帧中有多个这些宏块所以我创建了一个新的每个宏块的此类的实例,传入多个参数用于构建运动矢量,并将该窗口小部件传递给另一个窗口小部件以进行显示 . 这一切都按预期工作,但我得到这样的输出
frame

在我看来,当调用paintevent时,它会记住最后一次调用paint事件并保留绘制的线条并创建图片中的丑陋混乱,这应该显示几行宏块而不是全部他们 . 这是代码

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);

这构造了MainWindow类中的宏块,这是MotionVectorDisplay类的构造函数和PaintEvent

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()));
        }
    }
}

回答(1)

2 years ago

我怀疑您需要将窗口小部件上的OpaquePaintEvent标志设置为false:

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

或者(更常见的是),您将在每个绘制事件中重新绘制窗口小部件的每个像素,以便它基本上覆盖之前绘制的任何内容,类似于绘制事件开始时的内容:

painter.setBrush( Qt::black ); // Or whatever your background color is
painter.drawRect( rect() );