代码之家  ›  专栏  ›  技术社区  ›  Ad N

如果qapplication执行延迟,qwebengineview在加载内容时会自动失败

  •  0
  • Ad N  · 技术社区  · 7 年前

    我们正在开发一个qt ui包含 QWebEngineView . 目前正在使用qt 5.9.6在macos(10.12..10.14)上进行测试

    由于操作系统的特殊性,应用程序有时在到达 QApplication::exec() . 我们意识到,如果等待太久, QWebEngineView::load(QUrl) 调用将自动失败,显示灰色视图,而不是预期的呈现HTML。

    我们创建了一个最小的示例,触发了测试环境中的问题:

    #include <QApplication>
    #include <QMainWindow>
    #include <QWebEngineView>
    #include <QWidget>
    
    #include <chrono>    
    #include <iostream>
    #include <thread>
    
    int main(int argc, char *argv[])
    {
        QApplication qtapp(argc, argv);
    
        QMainWindow *window = new QMainWindow;
        window->setFixedSize({800, 600});
        QWebEngineView *webview = new QWebEngineView();
        window->setCentralWidget(webview);
    
        window->show();
    
        std::this_thread::sleep_for(std::chrono::seconds(30));
        std::clog << "Done sleeping" << std::endl;
    
        webview->load({"https://www.google.com"});
    
        return qtapp.exec();
    }
    

    评论 sleep 谷歌主页的表现还不错。与 睡觉 ,取而代之的是灰色区域。

    • 在这个例子中使用qt有错误吗?
    • 或者这是框架中的一个bug?

    编辑: 进一步调查表明,只要 睡觉 在两者之前 webview->load() window->show() .

    1 回复  |  直到 7 年前
        1
  •  0
  •   eyllanesc    7 年前

    qt有一个事件循环,允许您监视各种事件,如键盘、鼠标等。因此,当您使用睡眠时,您会阻止它,从而导致gui冻结,如果您有耗时的任务,策略是将其划分为较少的任务,如果我们可以或在新线程中执行它,并通过信号将结果传输到gui线程,请对它们进行权衡。在下面的例子中,我展示了一个简单的实现。

    #include <QtWebEngineWidgets>
    #include <iostream>
    
    class Worker: public QObject
    {
        Q_OBJECT
    public:
        using QObject::QObject;
    public slots:
        void start_task(){
            std::this_thread::sleep_for(std::chrono::seconds(30));
            std::clog << "Done sleeping" << std::endl;
            emit finished();
        }
    signals:
        void finished();
    };
    
    class Thread final : public QThread {
        Q_OBJECT
    public:
        using QThread::QThread;
        ~Thread() override {
            finish(); wait();
        }
    public slots:
        void finish() {
            quit(); requestInterruption();
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication qtapp(argc, argv);
        QMainWindow window;
        window.setFixedSize({800, 600});
        QWebEngineView *webview = new QWebEngineView();
        window.setCentralWidget(webview);
        window.show();
        Thread thread;
        QObject::connect(QApplication::instance(), &QApplication::aboutToQuit, &thread, &Thread::finish);
        thread.start();
        Worker worker;
        worker.moveToThread(&thread);
        QObject::connect(&worker, &Worker::finished, webview, [webview](){
            qDebug()<< "finished";
            webview->load({"https://www.google.com"});
        });
        QMetaObject::invokeMethod(&worker, "start_task", Qt::QueuedConnection);
        return qtapp.exec();
    }
    #include "main.moc"
    
    推荐文章