QT实现等待对话框转圈显示

应用背景


对话框中执行一段比较耗时的程序时,界面会出现假死现象,如果用户没有耐心就会乱点软件,导致软件崩溃。

解决思路


执行耗时任务前打开一个子窗口(显示动图),将耗时任务扔到一个线程里执行,这里新开线程必须是异步的,如果是同步的话没有作用!任务执行结束后将子窗口关闭

实现步骤


 1. 新建Qt的GUI类,在界面中添加label:
 QT实现等待对话框转圈显示_第1张图片
 2. 找一个gif资源,放到软件相对路径下,可通过以下网站自行下载:
  https://www.lanrentuku.com/gif/a/loading.html
 3. 主对话框中点击运行后,在相应槽函数中调用上面的dlg,然后创建异步线程,在线程中执行耗时任务:
 首先对转圈对话框进行一些设置,主要把窗口边框去掉,然后背景设置为透明而label中资源不透明:

LoginDlg::LoginDlg(QWidget *parent)
    : QDialog(parent)
{
    ui.setupUi(this);
    setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);//去掉边框的对话框风格
    //设置背景透明而内容不透明:
    this->setWindowOpacity(1);
    this->setAttribute(Qt::WA_TranslucentBackground);
    //设置为非模态
    setWindowModality(Qt::NonModal);
    //label中添加资源
    m_Move = new QMovie("../res/转圈圈.gif");
    ui.label_gif->setMovie(m_Move);
    ui.label_gif->setScaledContents(false);
    ui.label_gif->setAlignment(Qt::AlignCenter);
    ui.label_gif->setStyleSheet("QLabel {background-color:transparent;}");//设置lable背景透明
    m_Move->start();
}
LoginDlg::~LoginDlg()
{
    m_Move->stop();
}

点击运行的槽函数中:

    //转圈
    m_logindlg = new LoginDlg(this);
    //调用等待窗口转圈
    m_logindlg->show();
    //使用线程执行耗时操作
    QString path = ui.lineEdit->text();
    QFuture ff = QtConcurrent::run(this,&MyDlg::doThread,path);

 - 这里转圈对话框设置成了当前主对话框的成员变量,方便在其他槽函数中关闭它;
 - 另外,这里转圈对话框要设置为非模态的,就是不阻塞,否则无法执行下面的异步线程;
 - 最后需要注意的是这里的线程必须是异步的,如果是同步的(比如通过继承QTread类,重写run方法就是同步的,这样的话会等线程执行完成后才会弹出转圈对话框,结果就不是我们想要的),所以这里使用QFuture实现异步线程(QFuture使用可参考https://blog.csdn.net/hu12306/article/details/79760605,其他异步执行方法可参考https://blog.csdn.net/qq_37529913/article/details/110521759

这里假装给一个耗时函数:

void MyDlg::doThread(QString funcpath)
{
    //执行耗时任务
    while(1)
    {
        sleep(5);
    }
    emit loginTerminate(QString());//自定义的消息
}


这里接收消息,并关闭转圈窗口:

void ConvolutionCenterDlg::slotTerminate(QString infos)
{
    //关闭转圈窗口
    m_logindlg->close();
    //执行后续操作
}

最后效果显示:这里只截图了,没有录制动图,可以看到整个图层在主窗口上方且没有背景色,达到预期效果:


QT实现等待对话框转圈显示_第2张图片

 

你可能感兴趣的:(C++,QT,qt,开发语言)