C++ 在QT中重新绘制小部件
我有一段代码,初始化QWidget的一个实例,将其放入布局并调用动画。所有这些都是在循环中发生的。我遇到了每次迭代同时绘制动画的问题,完全忽略了QThread::usleep()。有没有办法以正确的方式清洁布局,以便达到预期的效果C++ 在QT中重新绘制小部件,c++,qt,C++,Qt,我有一段代码,初始化QWidget的一个实例,将其放入布局并调用动画。所有这些都是在循环中发生的。我遇到了每次迭代同时绘制动画的问题,完全忽略了QThread::usleep()。有没有办法以正确的方式清洁布局,以便达到预期的效果 double randomTestArray[numOfPoints]; double fMin = 0; double fMax = 20; srand(time(NULL)); for(int p = 0 ; p < 100 ; p++) { Equ
double randomTestArray[numOfPoints];
double fMin = 0;
double fMax = 20;
srand(time(NULL));
for(int p = 0 ; p < 100 ; p++)
{
Equalizer * eq = new Equalizer();
ui->verticalLayout->addWidget(eq);
for(int i = 0 ; i < numOfPoints ; i++)
{
randomTestArray[i] = fMin + (double)rand() * (fMax - fMin) / RAND_MAX;
}
eq->setChunk(&randomTestArray[0] , &startArray[0]);
ui->verticalLayout->removeWidget(eq);
delete eq;
QThread::usleep(1000);
}
通常情况下,Qt使用其事件系统(由触发)定期更新屏幕以避免过多。因为您想在不返回主事件循环的情况下更新
for
-循环的内的屏幕,所以默认方法不起作用。可能有不同的解决方案:
手动处理事件:您应该在整个等待时间内重复调用,而不是QThread::usleep
来处理所有新事件(来自QPropertyAnimation
)。请注意,您可能希望在删除和销毁均衡器
对象之前处理事件
强制立即重新绘制屏幕:您可以通过调用强制Qt立即重新绘制屏幕,这将立即调用paintEvent
。
此选项与QPropertyAnimation
组合使用时效果不佳
使用计时器事件定期更新:删除for
-循环(和usleep
函数调用),并使用对象定期执行某些操作
请注意,选项3是与基于事件的系统一起使用的首选解决方案,例如Qt.“for(int p=0;p<1;p++)”--真的吗?此外,您似乎创建了一个均衡器
实例,将其添加到布局中,在其上调用setChunk
,将其从布局中删除并将其全部删除,而从未返回到Qt
事件循环。我认为您需要提供一个。什么是“返回Qt事件循环”?Qt
是基于事件的。当您针对QObject
派生类的实例调用函数时,通常会导致将一个或多个事件发布到这些对象。为了处理这些事件,需要允许事件循环运行。您能提供基于此代码的解决方案吗?我不能提供答案,因为不清楚代码应该做什么。正如在前面的评论中所要求的,请提供一个。我已经尝试了所有这些方法,但它仍然只是在循环之后才开始绘制。我在问题的末尾添加了它选项3不再包含
for循环。因此,动画不可能在事件循环之后开始。我忽略了您使用的是QPropertyAnimation
,因此,我更新了第一种方法。请注意,选项3是我的首选解决方案。
void Equalizer::setChunk(double *chunk, int * startYArr)
{
if(*startYArr == -1)
{
for(int i = 0 ; i < 24 ; i++)
{
*(startYArr + i) = 150;
}
}
int xCoordinateArray[24];
int yCoordinateArray[24];
for(int i = 0 ; i < 24 ; i++)
{
yCoordinateArray[i] = *(chunk + i) * 5;
xCoordinateArray[i] = 100 + i*25;
}
cout << "Chunk initialized" << endl;
cout << "Start Coordinates : " << endl;
for(int i = 0 ; i < 24 ; i++)
{
cout << startYArr[i] << endl;
}
cout << "End Coordinates : " << endl;
for(int i = 0 ; i < 24 ; i++)
{
cout << yCoordinateArray[i] << endl;
}
QPropertyAnimation *animation = new QPropertyAnimation(this , "nrect");
animation->setDuration(2000);
animation->setStartValue(QRect(xCoordinateArray[0] , *(startYArr + 0) , 10 , 10));
animation->setEndValue(QRect(xCoordinateArray[0] , 150 - yCoordinateArray[0] , 10 , 10));
animation->start();
connect(animation, &QPropertyAnimation::valueChanged , [=](){update();});
QPropertyAnimation *animation2 = new QPropertyAnimation(this , "nrect2");
animation2->setDuration(2000);
animation2->setStartValue(QRect(xCoordinateArray[1] , *(startYArr + 1), 10 , 10));
animation2->setEndValue(QRect(xCoordinateArray[1] , 150 - yCoordinateArray[1] , 10 , 10));
animation2->start();
connect(animation2, &QPropertyAnimation::valueChanged , [=](){update();});
QPropertyAnimation *animation3 = new QPropertyAnimation(this , "nrect3");
animation3->setDuration(2000);
animation3->setStartValue(QRect(xCoordinateArray[2] , *(startYArr +2) , 10 , 10));
animation3->setEndValue(QRect(xCoordinateArray[2] , 150 - yCoordinateArray[2] , 10 , 10));
animation3->start();
connect(animation3, &QPropertyAnimation::valueChanged , [=](){update();});
................................
for(int i = 0; i < 24 ; i++)
{
*(startYArr + i) = yCoordinateArray[i];
}
void Equalizer::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QRect ellipse(mRect);
QPainter painter(this);
painter.setBrush(Qt::red);
painter.drawEllipse(ellipse);
QRect ellipse2(mRect2);
painter.setBrush(Qt::red);
painter.drawEllipse(ellipse2);
QRect ellipse3(mRect3);
painter.setBrush(Qt::red);
painter.drawEllipse(ellipse3);
.............................
eq->setChunk(&randomTestArray[0] , &startArray[0]);
QCoreApplication::processEvents();
ui->verticalLayout->removeWidget(eq);
QThread::usleep(1000);