gpt4 book ai didi

c++ - 在 QT 中重新绘制小部件

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:43:44 24 4
gpt4 key购买 nike

我有一段代码可以初始化 QWidget 的实例,将其放入布局中并调用动画。所有这些都在循环中发生。我遇到过每次迭代同时绘制动画的问题,完全忽略了 QThread::usleep()。有没有一种方法可以以正确的方式清理布局,以便达到预期的效果?

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

动画是使用 QPropertyAnimation 和 setChunk() 方法中的 paintEvent() 完成的。如果您需要更多代码,请通知我。

添加均衡器类的 segmentation :

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

最佳答案

通常 Qt 使用其事件系统(由 QWidget::update 触发)定期更新屏幕以避免过多的 painting operations 。因为您想在 for 循环内更新屏幕而不返回主事件循环,所以默认方法不起作用。可能有不同的解决方案:

  1. 手动处理事件:您应该在整个等待时间内重复调用 QCoreApplication::processEvents 而不是 QThread::usleep 来处理所有新事件(来自QPropertyAnimation)。请注意,您可能希望在删除和破坏您的 Equalizer 对象之前处理这些事件。

  2. 强制立即重新绘制屏幕: 您可以通过调用 QWidget::repaint 强制 Qt 立即重新绘制屏幕,​​这将调用 paintEvent立即。
    此选项不能与 QPropertyAnimation 结合使用。

  3. 使用定时器事件定期更新:移除for循环(和usleep函数调用)并使用一个QTimer对象定期执行一些操作。

请注意,选项 3 是用于基于事件的系统(例如 Qt)的首选解决方案。

关于c++ - 在 QT 中重新绘制小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43716463/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com