一个 QWebEnginePage 用于两个或多个 QWebEngineView

Posted

技术标签:

【中文标题】一个 QWebEnginePage 用于两个或多个 QWebEngineView【英文标题】:One QWebEnginePage for two or more QWebEngineView 【发布时间】:2016-09-27 10:56:24 【问题描述】:

我有一个 QWebEnginePage 实例,它加载了一些 url(例如https://www.google.com)

我希望这个页面显示在两个 QWebEngineViews 中,但看起来 Qt 不允许这样做。

一旦我在一个视图上调用 setPage,另一个视图就会停止渲染页面。 看起来这是所有权问题或类似的问题,但我在 Qt 文档中没有看到任何相关信息。

还有其他人遇到过这样的问题吗?

auto p = new QWebEnginePage();
p->load(QUrl("https://www.google.com"));

auto w1 = new QWebEngineView();
auto w2 = new QWebEngineView();

w1->setPage(p);
w2->setPage(p);

w1->show();
w2->show();

我希望两个视图都显示相同的页面,但只有 w2 显示它。如果您稍后调用w1->setPage(p) - 该页面将显示在 w1 上,并从 w2 上消失。

UPD。 只想发表结论。 - QWebEnginePage 的 view() 方法证明了一对一的关系。 - setPage 源代码清楚地显示“第二次它只是与第一次视图断开连接”。 - “如果当前页面是 web 视图的子页面,它将被删除。” - 根本不回答我的问题。我的页面不是网络视图的子页面,也没有被删除,只是没有像我预期的那样同时呈现。

【问题讨论】:

你说得对,我已经用相关的代码更新了我的答案 【参考方案1】:

QWebEnginePage 无法连接到两个QWebEngineViews。

当您查看Qt sources 时,您将很容易理解当您调用setPage 两次时会发生什么,请参阅那里的setPage 函数。第二次它只是与第一个视图断开连接。

void QWebEngineView::setPage(QWebEnginePage* page)

    QWebEngineViewPrivate::bind(this, page);


void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)

    if (view && page == view->d_func()->page)
        return;

    if (page) 
        // Un-bind page from its current view.
        if (QWebEngineView *oldView = page->d_func()->view) 
            page->disconnect(oldView);
            oldView->d_func()->page = 0;
        
        page->d_func()->view = view;
        page->d_func()->adapter->reattachRWHV();
    

    if (view) 
        // Un-bind view from its current page.
        if (QWebEnginePage *oldPage = view->d_func()->page) 
            oldPage->disconnect(view);
            oldPage->d_func()->view = 0;
            oldPage->d_func()->adapter->reattachRWHV();
            if (oldPage->parent() == view)
                delete oldPage;
        
        view->d_func()->page = page;
    

    // skipped

【讨论】:

@Joe 第二次调用 setPage 时,页面与第一个视图解除绑定。无论如何,有必要创建两个页面实例来完成这项工作 是的,但那句话与那个事实无关。 @Joe,同意 - 我删除了错误的引用并添加了一段代码来解释 setPage() 期间发生的事情【参考方案2】:

QWebEnginePage 有一个方法QWebEnginePage::view,它返回指向当前显示页面的QWidget 的指针。因此,根据定义,它只能有一个视图,尽管视图不获取页面的所有权(所有权始终是一对一的关系)

我建议创建两个 QWebEnginePage 实例并将信号连接到另一个页面的它们各自的插槽(或调用相应的非插槽设置器的 lambda)。像scrollPositionChanged 这样的一些可能没有相应的设置器,因此您可能无法完美同步。

【讨论】:

从来没有使用过 QWebEnginePage::view 方法,但是是的——这个方法证明了一对一的关系。但是,setPage 方法文档doc.qt.io/qt-5/qwebengineview.html#setPage 说 View 不获取页面的所有权 - 因此我认为它可能会在视图之间共享。

以上是关于一个 QWebEnginePage 用于两个或多个 QWebEngineView的主要内容,如果未能解决你的问题,请参考以下文章

QWebEnginePage:toHtml 返回一个空字符串

Dagger multibinding java - 用于两个或多个实现

是否可以在屏幕外渲染 QWebEnginePage/QWebEngineView?

QWebEnginePage.print 与 QPrintPreviewDialog 导致空预览

qt5.7 中的信号和槽 - QWebEnginePage

QWebEnginePage 中的 setFeaturePermission 成员函数如何工作?