У меня есть класс с именем MotionVectorDisplay, который наследуется от QWidget, и я перезаписываю painttevent. Я делаю с этим классом рисование векторов движения для конкретного макроблока размером 16×16, и в кадре несколько таких макроблоков, поэтому я создаю новый экземпляр этого класса для каждого макроблока, передать несколько параметров для построения векторов движения и родительский элемент этого виджета для другого виджета для отображения. Это все работает, как и ожидалось, но я получаю вывод, как это
Мне кажется, что когда вызывается painttevent, он запоминает последний раз, когда вызывается событие рисования, сохраняет нарисованные линии и создает ужасный беспорядок, присутствующий на рисунке, который должен показать несколько строк для нескольких макроблоков, но не все их. Это код
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, это конструктор и PaintEvent из класса MotionVectorDisplay
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()));
}
}
}
Я подозреваю, что вам нужно установить флаг OpaquePaintEvent на вашем виджете в false:
this->setAttribute(Qt::WA_OpaquePaintEvent, false);
В качестве альтернативы (и более часто), вы должны перерисовывать каждый пиксель вашего виджета в каждом событии рисования, чтобы он по существу записывал поверх всего, что было нарисовано ранее, что-то вроде этого в начале вашего рисования:
painter.setBrush( Qt::black ); // Or whatever your background color is
painter.drawRect( rect() );
Других решений пока нет …