Qt中的PaintEvent为类的每个实例绘制所有小部件

时间:2013-03-17 18:36:45

标签: c++ qt qpainter 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 个答案:

答案 0 :(得分:1)

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

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

或者(更常见的),你会在每个绘制事件中重新绘制窗口小部件的每个像素,以便它基本上覆盖之前绘制的任何内容,在绘制事件开始时就像这样:

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