Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/apache-kafka/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在QT中重新绘制小部件_C++_Qt - Fatal编程技术网

C++ 在QT中重新绘制小部件

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

我有一段代码,初始化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);
}

通常情况下,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);