Qt如何在循环中更新GUI

Posted

技术标签:

【中文标题】Qt如何在循环中更新GUI【英文标题】:Qt How to update GUI in the loop 【发布时间】:2017-04-06 08:40:59 【问题描述】:

我需要更新屏幕以显示按钮的移动方式。 这是我的代码:

void mouseReleaseEvent(QMouseEvent *event)
    double b=(button->x()*event->y())/(button->x()-1);
    double k=(button->y()-b)/button->x();
    int time=0;
    fnl=false;
    if(event->button()==Qt::LeftButton)
    
        while(!fnl)
        
            int mX=button->x()-1;
            int mY=k*(button->x()-1)+b;
            button->setText(QString::number(b));
            button->move(mX,mY);
            QThread::sleep(1);
            //here I need to update screen and show button
        

    

但它不会更新 GUI。它只是在循环内播放。

【问题讨论】:

你知道QTimer吗?我建议您创建一个由计时器定期调用的功能。在函数中,你可以检查按钮是否被按下,如果是,更新它的位置。 在 C# 计时器中是否有像 timer1.tick 这样的事件处理程序? 【参考方案1】:

切勿在 GUI 线程中使用QThread::sleep(),它会阻止 GUI 线程执行任何操作。相反,您可以使用QTimer 来安排稍后运行的某些内容。此外,您的插槽/函数应尽可能短且经过优化,以便将控制权返回给事件循环并能够处理 other events that may happen。

您可能想查看this question 以解决类似问题。 可以在此处应用相同的技术来解决问题,方法是将您的 while 循环替换为一个插槽和一个间隔设置为 0QTimer但是 Qt 可以使用 the animation framework 完成所有这些工作,下面是一个在单击时移动的按钮示例:

#include <QtWidgets>

int main(int argc, char* argv[])
    QApplication a(argc, argv);
    //create and show button
    QPushButton button("Animated Button");
    button.move(QPoint(100, 100));
    button.show();
    //create property animator object that works on the position of the button
    QPropertyAnimation animation(&button, "pos");
    //set duration for the animation process to 500ms
    animation.setDuration(500);

    //when the button is clicked. . .
    QObject::connect(&button, &QPushButton::clicked, [&]
        //set the starting point of the animation to the current position
        animation.setStartValue(button.pos());
        //set the ending point to (250, 250)
        animation.setEndValue(QPoint(250, 250));
        //start animation
        animation.start();
    );

    return a.exec();

Qt 还提供了many examples 用于使用动画框架。 . .

【讨论】:

谢谢。正是我一直在寻找的东西!【参考方案2】:

计时器是最好的选择。如果你想使用蛮力,你可以打电话

qApp->processEvents();

在你的循环中。丑陋但完成工作。

【讨论】:

使用processEvents()时,您的代码应为reentrant,这意味着您应该准备好让您再次进入此插槽的相同事件。在这种情况下,插槽会在其内部再次被调用(在某些情况下这可能会无限发生)。这很可能不是您想要的行为。看看this page from the wiki @Mike -- 同意。我应该说“丑陋但经常完成工作”...... 关键是要把工作做好。当您养成编写异步代码的习惯时,它会打开许多​​其他可能性并使生活变得更加轻松。下一步是养成using state machines的习惯。

以上是关于Qt如何在循环中更新GUI的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Qt GUI 应用程序中工作循环并显示 qimage

如何在 qt creator 的 main.cpp 中有一个计时器,以便在单击按钮时更新 GUI?

Qt 在处理时更新(重绘)文本框

如何通过 Qt gui 应用程序显示视频的帧?

如何在标准GUI应用程序中使用Qt3D进行渲染?

Qt Main-Gui 和其他线程+事件循环