2015-01-15 27 views
5

我已经遇到了一个有关白名单Web浏览器的问题我的公司一直在为我们的一个开发/维护产品线。浏览器运行在Qt 4.8.6之上,使用qtwebkit(迁移到5.X将是理想的,但我们使用的嵌入式Linux操作系统太旧了,无法支持基于我们测试的较新版本,并升级到更新的版本操作系统对我们/我们的客户而言成本过高)。浏览器的主界面是一个6x8触摸屏,安装在飞机驾驶舱内。QtWebView - 如何启用页面滚动和滚动页面中的元素(例如谷歌地图)

对于像可滚动/嵌入式地图(例如Google地图)之类的网站,浏览器的用户希望能够在选择地图外的东西时拖动整个页面,并拖动地图(没有整个页面滚动)当地图被选中时(大部分流行的移动浏览器都是Ala)。

到目前为止,我能够做一个或另一个,但不能同时:

  • 当我勾鼠标处理程序为QWebView或QGraphicsWebView,我可以把光标变为一只手很容易支持拖动整个网页。但是,这会阻止页面处理鼠标事件的能力,因为用户在拉动地图时(即,当用户拖动地图时,会拖动整个页面而不移动地图)。

  • 当我不添加钩子来处理鼠标事件时,地图可以通过抓取/拖动它们来滚动,但当然用户失去拖动整个页面的能力。

眼下,浏览器使用后,随着滚动条禁用和方向箭头覆盖,以允许用户滚动整个页面(如显示大小是有限的,和滚动条占用太多空间当它们的大小足以让用户与它们交互时)......但这并不理想。

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

谢谢! Rob

回答

2

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

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)挂钩的鼠标事件,我建议你做一些事情,如:DOC的

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看起来像这样:

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是用来摧毁它可能会带来一点延迟。但是在这种情况下,它也会重新实现。

+0

感谢您的回复!不幸的是,谷歌地图只是一个例子......航空公司实际上正在寻找使用各种天气,航班跟踪和其他相关网站。其中一些具有交互式地图,而另一些则不具备(每个网站的实施也是独一无二的)。我只提到谷歌地图,因为它是我目前用来测试的那个。我以前也尝试过上面的命中测试行为,但没有任何访问权限(当您查询它是否可移动时,它总是报告'错误')。 – Bob

+0

没问题。只是做了一个新的编辑,应该使更好更灵活的设计。 – Atlante45