首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QtWebView -如何在页面中启用页面滚动和元素滚动(例如Google )

QtWebView -如何在页面中启用页面滚动和元素滚动(例如Google )
EN

Stack Overflow用户
提问于 2015-01-15 20:11:21
回答 1查看 929关注 0票数 5

我遇到了一个与白名单浏览器有关的问题,我的公司一直在为我们的产品线开发/维护。浏览器运行在Qt 4.8.6之上,使用qtwebkit (迁移到5.X将是理想的,但我们使用的嵌入式Linux操作系统太旧,无法支持基于测试的更新版本,而升级到较新的操作系统对我们/我们的客户来说太昂贵了)。浏览器的主要界面是6x8触摸屏,安装在飞机驾驶舱内。

对于具有诸如可滚动/嵌入式映射(例如。Google Maps(Google Maps),浏览器的用户希望在选择地图之外的内容时能够拖动整个页面,在选择地图时只拖动地图(没有整个页面滚动) (Ala大多数流行的移动浏览器)。

到目前为止,我能够做到一项或另一项,但不能两者兼而有之:

  • 当我将鼠标处理程序钩到QWebView或QGraphicsWebView中时,我可以将光标转换为一只手,并且非常容易地支持整个网页的拖动。但是,这会抑制页面处理鼠标事件的能力,因为当用户正在拖放地图时(即当用户拖到地图上时,它会在不移动地图的情况下拖走整个页面)。
  • 当我不添加钩子来处理鼠标事件时,像地图这样的东西可以通过抓取/拖动来滚动,但是用户当然失去了拖动整个页面的能力。

现在,浏览器使用后者,禁用滚动条和一个方向箭头覆盖,允许用户滚动整个页面(因为显示大小有限,而且当滚动条的大小足够大时,滚动条占用了太多的空间,用户可以与它们交互)--这并不理想。

我的问题是:有什么简单的方法可以使页面和页面中的元素无缝滚动吗?

谢谢!抢夺

EN

回答 1

Stack Overflow用户

发布于 2015-01-19 12:44:56

在我看来,你似乎需要检查你是否在这样的地图上,忽略(传递)在这种情况下的事件。我想你应该能做这样的事:

代码语言:javascript
复制
bool GraphicsWebView::isOverMap(QPoint pos) {
    QWebPage* webPage = this->page();
    if (webPage) {
        QWebFrame* webFrame = webPage->frameAt(pos);
        if (webFrame) {
            QString selectorQuery = "#map-canvas"; // Based on https://developers.google.com/maps/tutorials/fundamentals/adding-a-google-map
            QList<QWebElement> list = webFrame->findAllElements(selectorQuery).toList(); // Find all the maps!

            foreach(QWebElement element, list) {
                if (element.geometry().contains(pos)) {
                    return true; // Cursor is over a map
                }
            }
        }
    }
    return false; // No match
}

显然,这是一个非常特定的函数,但是可能有一种方法可以找到一个更好的选择器查询,它将适用于所有这些类型的QWebElement

假设您通过子类QGraphicsWebView和重新实现void mouseMoveEvent(QGraphicsSceneMouseEvent * event)来挂钩鼠标事件,我建议您执行以下操作:

代码语言:javascript
复制
void GraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) {
    if (isOverMap(mapFromScene(event->scenePos()).toPoint())) { // We got a map!
        event.ignore(); // Clear the accept flag
        return; // Return, we're done here
    }

    handleMoveView(); // Not over any maps, let's scroll the page
}

文档的部分解释了如何处理与最顶层项有关的事件。我特别建议你读第三段。

希望这能帮上忙!

编辑:做了更多的研究,看起来类似的东西可能更通用:graphicsView.focusItem()->flags().testFlag(QGraphicsItem::ItemIsMovable);

作为isOverMap()的替代品,它至少值得研究

编辑:明白了,下面是一些你可以尝试的东西。从子类QGraphicsSceneMouseEvent开始,添加一个名为void destroyedWithoutAccept()的信号,如果该事件未被接受,该信号将在析构函数中发出。

然后修改mouseMoveEvent如下所示:

代码语言:javascript
复制
void GraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) {
    MyEvent myEvent = new MyEvent(event); // Copy event
    event.accept(); // accept original event
    connect(myEvent, SIGNAL(destroyedWithoutAccept),
            this, SLOT(handleMoveView)); // Callback if unused

    QGraphicsWebView::mouseMoveEvent(myEvent); // Pass it to Base class
}

如果这样做有效的话,如果使用deleteLater来破坏它,它可能会带来一些延迟。但在这种情况下,也要重新实现它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27972158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档