- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个包含多个自定义 QGraphicsItem 的 QGraphicsScene。每个项目都包含一个 QGraphicsProxyWidget,它本身包含业务逻辑所需的任何小部件。代理有一个应用到它的 Qt::Window 标志,因此它有一个标题栏来移动它。这一切都运行良好,除了在缩放 View 时移动代理小部件时。
用户可以像谷歌地图那样在场景中四处移动,即通过缩小然后再放大到更远的地方。这是通过调用 QGraphicsView::scale 完成的。无论缩放值如何,项目都应始终可见,因此它们设置了 QGraphicsItem::ItemIgnoresTransformations 标志。
在缩放 View 时移动 proxyWidget 时发生的情况是,在第一次移动事件中,小部件将跳转到某个位置,然后才能正确拖动。
我在 Qt5.7.1 上遇到了这个问题,可以用 PyQt5 重现它,因为它更容易重现和修改,请看下面的代码片段。
重现步骤:
片段:
import sys
import PyQt5
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
from PyQt5.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsProxyWidget, QGraphicsWidget, QGraphicsObject
global view
global scaleLabel
def scaleScene(event):
delta = 1.0015**event.angleDelta().y()
view.scale(delta, delta)
scaleLabel.setPlainText("scale: %.2f"%view.transform().m11())
view.update()
if __name__ == '__main__':
app = QApplication(sys.argv)
# create main widget
w = QWidget()
w.resize(800, 600)
layout = QVBoxLayout()
w.setLayout(layout)
w.setWindowTitle('Example')
w.show()
# rescale view on mouse wheel, notice how when view.transform().m11() is not 1,
# dragging the subwindow is not smooth on the first mouse move event
w.wheelEvent = scaleScene
# create scene and view
scene = QGraphicsScene()
scaleLabel = scene.addText("scale: 1")
view = QGraphicsView(scene)
layout.addWidget(view)
view.show();
# create item in which the proxy lives
item = QGraphicsWidget()
scene.addItem(item)
item.setFlag(PyQt5.QtWidgets.QGraphicsItem.ItemIgnoresTransformations)
item.setAcceptHoverEvents(True)
# create proxy with window and dummy content
proxy = QGraphicsProxyWidget(item, Qt.Window)
button = QPushButton('dummy')
proxy.setWidget(button)
# start app
sys.exit(app.exec_())
跳跃距离为:
我正在寻找任何一个
谢谢
最佳答案
将近 2 年后,我再次回到这个问题上,终于找到了解决方案。或者更确切地说是一种解决方法,但至少是一种简单的方法。事实证明,我可以很容易地避免首先陷入本地/场景/忽略转换的问题。
我没有将 QGraphicsProxyWidget 作为 QGraphicsWidget 的父级,并明确地将 QWidget 设置为代理目标,而是直接从 QGraphicsScene 获取代理,让它在包装器上设置窗口标志,并在代理上设置 ItemIgnoresTransformations 标志。然后(这里是解决方法)我在代理上安装一个事件过滤器,拦截 GraphicsSceneMouseMove 事件,在该事件中我将代理位置强制为 currentPos+mouseDelta(均在场景坐标中)。
这是上面的代码示例,使用该解决方案进行了修补:
import sys
import PyQt5
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
global view
global scaleLabel
def scaleScene(event):
delta = 1.0015**event.angleDelta().y()
view.scale(delta, delta)
scaleLabel.setPlainText("scale: %.2f"%view.transform().m11())
view.update()
class ItemFilter(PyQt5.QtWidgets.QGraphicsItem):
def __init__(self, target):
super(ItemFilter, self).__init__()
self.target = target
def boundingRect(self):
return self.target.boundingRect()
def paint(self, *args, **kwargs):
pass
def sceneEventFilter(self, watched, event):
if watched != self.target:
return False
if event.type() == PyQt5.QtCore.QEvent.GraphicsSceneMouseMove:
self.target.setPos(self.target.pos()+event.scenePos()-event.lastScenePos())
event.setAccepted(True)
return True
return super(ItemFilter, self).sceneEventFilter(watched, event)
if __name__ == '__main__':
app = QApplication(sys.argv)
# create main widget
w = QWidget()
w.resize(800, 600)
layout = QVBoxLayout()
w.setLayout(layout)
w.setWindowTitle('Example')
w.show()
# rescale view on mouse wheel, notice how when view.transform().m11() is not 1,
# dragging the subwindow is not smooth on the first mouse move event
w.wheelEvent = scaleScene
# create scene and view
scene = QGraphicsScene()
scaleLabel = scene.addText("scale: 1")
view = QGraphicsView(scene)
layout.addWidget(view)
view.show();
button = QPushButton('dummy')
proxy = scene.addWidget(button, Qt.Window)
proxy.setFlag(PyQt5.QtWidgets.QGraphicsItem.ItemIgnoresTransformations)
itemFilter = ItemFilter(proxy)
scene.addItem(itemFilter)
proxy.installSceneEventFilter(itemFilter)
# start app
sys.exit(app.exec_())
希望这可以帮助那些和我一样陷入死胡同的人:)
关于qt5 - 更改 QGraphicsView 比例后使用 ItemIgnoresTransformations 移动 QGraphicsProxyWidget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42182399/
我总是在使用 QGraphicsScene 坐标系时遇到问题。我的场景创建起来非常简单,如下所示: scene = new QGraphicsScene(this); this->setScene(s
我将描述我的问题。 我有一个选项卡类,大致如下所示: class Tab : public QWidget { public: Tab(); ... private: ... QG
我正在尝试使用 QGraphics 变换矩阵进行平移和缩放。缩放有效,但平移参数 m31 和 m32 无效。看起来还有一个以场景为中心的功能。在下面的代码中,我操纵 rectScene 进行平移,但为
我想做一个 QGraphicsScene并显示在 QGraphicsView .我想通过鼠标中键滚动场景并通过左键选择橡皮筋。但我不知道如何使橡皮筋选择仅通过鼠标左键出现。 这是我的代码: # -*-
我将 QGraphicsView 子类化并在我的布局中显示小部件。在 View 中,我自然有 QGraphicsScene。 我可以很好地检索 QGraphicsScene 大小(即我设置的 2100
我想在我的 (Py)Qt 应用程序中的 QGraphicsView 上实现滚动/平移功能。它应该是这样工作的:用户按下鼠标中键, View 随着用户移动鼠标而滚动(这是一个非常常见的功能)。 我尝试使
我的QGraphicsView项目比其背景图像大很多,但我希望该背景图像仅绘制一次。现在,整个事物都被背景图像填充了多少次,只要有足够的空间即可。 那么,如何强制将背景图像仅绘制到 View 中心一次
我想要一个永远不会自动滚动的 QGraphicsView。 类似:基本上,我的问题与 http://developer.qt.nokia.com/forums/viewthread/2220 相同,但
在我的应用程序中,我添加了添加了像素图的 QGraphicsScene,并且所有内容都在关闭滚动条的情况下在 QGraphicsView 中查看。程序窗口比像素图小,当我按箭头键或移动鼠标滚轮时,像素
我想将声子视频小部件放置到 qgraphicsscene 上,以便我可以覆盖图形等。当我运行以下命令时,我听到声音,但 qgraphicsview 上没有播放视频。我将不胜感激,因为我认为我正在做示例
我有一个带有“ScrollBarAlwaysOff”垂直滚动条策略的 QGraphicsView。问题是,当我调整 View 的大小(通过 QSplitter 或仅通过调整窗口的大小)时, View
我正在 PyQt 中使用 QGraphicsView 构建一个 GUI,它将显示互连项目的大型网络,并且我希望能够叠加一个较小的门户来显示网络的远处部分 - 有点像“画中画” “之类的事情。这本身并不
您好,我有一个 GridLayout,上面有 64 个 GraphicsView(我知道它很多,但这是我目前唯一能想到的方法)。现在,我目前只是在计时器刻度上在这些图形 View 中的每一个上绘制一条
如何将新的矩形附加到 QgraphicView 在此代码中,当单击按钮时创建矩形。但是当我第二次单击按钮时,先前创建的矩形被删除。我需要创建 2 个矩形当我点击按钮 2 次时。当我点击按钮 3 次时创
我有一个 QDialog,它包含几个停靠小部件和一个 QGraphicsView。小部件布局设置为网格,QGraphicsView 大小策略设置为固定在 2 个轴上,并且 QGraphicsView
我有两个关于 QGraphicsView Framework 的问题。 第一个问题是关于一条特殊的线:我想问一下是否可以画一条蛇形线或波浪线(如链接图片中所示)?如果有任何解决方案,我将不胜感激,因为
我的 QGraphicsView 有一些问题。我将 QGraphicsView 子类化以重新定义 paintEvent。我想使用 QGraphicsItem 绘制某种树的节点和 QGraphicsLi
我在根据需要扩展 QWidgets 时遇到了极大的麻烦。这不是我第一次遇到这个问题,上次我通过 hacking 一个大的 sizeHint() 解决了它。这是错误的方法,我真的很想学习正确的方法。 如
我在我的应用程序中使用 QGraphicsScene/QGraphicsView 对。为了我的目的,我将它们分类。生成该对的代码片段如下: itsScene = new QGraphicsScene;
如何让QGraphicsView处理拖放?比如,从某个文件夹中拖出一个图像文件,然后放到 QGraphicsView 中? Windows、QT5.2、C++。 最佳答案 你需要创建一个 QGraph
我是一名优秀的程序员,十分优秀!