QtWebView - 如何启用页面滚动和页面中元素的滚动(例如谷歌地图)
QtWebView - How to enable scrolling of page and scrolling of elements in a page (e.g. Google Maps)
>我遇到了一些与白名单 Web 浏览器相关的问题,我的公司一直在为我们的一条产品线开发/维护。浏览器运行在Qt 4.8.6之上,使用qtwebkit(迁移到5.X是理想的,但是我们使用的嵌入式Linux操作系统太旧,无法根据我们的测试支持较新的版本,并且升级到较新的操作系统对我们/我们的客户来说成本太高)。浏览器的主要界面是一个6x8触摸屏,安装在飞机驾驶舱内。
对于具有可滚动/嵌入式地图(例如Google地图)之类的内容的网站,浏览器的用户希望在选择地图之外的内容时能够拖动整个页面,并在选择地图时仅拖动地图(不滚动整个页面)(唉,大多数流行的移动浏览器)。
到目前为止,我能够做一个或另一个,但不能同时做两个:
-
当我将鼠标处理程序挂接到QWebView或QGraphicsWebView中时,我可以将光标变成手,并且非常容易地支持拖动整个网页。但是,这会抑制页面在用户拉过地图时处理鼠标事件的能力(即,当用户拖动地图时,它会拖动整个页面而不移动地图)。
-
当我不添加钩子来处理鼠标事件时,地图之类的东西可以通过抓取/拖动来滚动,但当然用户失去了拖动整个页面的能力。
现在,浏览器使用后者,禁用滚动条和方向箭头覆盖以允许用户滚动整个页面(因为显示尺寸有限,当滚动条的大小足够大以便用户与它们交互时,滚动条会占用太多空间)......但这并不理想。
我的问题:有没有简单的方法可以使页面和页面中的元素可以无缝滚动?
谢谢!抢
,您需要检查您是否在这样的地图上,并在这种情况下忽略(传递)事件。我认为你应该能够做这样的事情:
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)
来钩住鼠标事件,我建议你做这样的事情:
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 来销毁它,它可能会引入一些延迟。但在这种情况下,也要重新实现它。
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- 使用一个考虑到std::map中键值的滚动或换行的键
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将元素添加到数组的线程安全函数?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 我想访问std::unique_ptr中的一个特定元素
- QtWebView - 如何启用页面滚动和页面中元素的滚动(例如谷歌地图)
- Qt:元素可见且不遮挡(无需滚动)
- 在滚动区使用自定义Qt类,并强制不调整元素的大小,但滚动条出现