QGraphicsView 和自定义游标

发布于 2024-10-04 12:36:53 字数 1615 浏览 0 评论 0原文

我正在尝试为我的 QGraphicsView 使用自定义光标和预设光标的组合。 在我的实现中,我们为视图创建了“模式”的概念。这意味着根据用户所处的“模式”,左键单击或左键拖动会发生不同的情况。无论如何,这些都不是问题,只是上下文。

当我尝试更改每种模式的光标时,问题就出现了。例如,对于模式 1,我们希望显示常规箭头光标,但对于模式 2,我们希望使用自定义像素图。看似简单,我们调用graphicsview->viewport()->setCursor(Qt::QArrowCursor)当我们切换到模式 1 时,以及 graphicsview->viewport()->setCursor(我们的自定义光标) 切换到模式 2 时。但它根本不起作用。

首先,光标不会更改为自定义光标。这是第一个问题。但是,如果通过其他操作将图形视图的拖动模式设置为 ScrollHandDrag,则一旦拖动操作完成,光标将切换为自定义光标。诡异的。但情节变得更加复杂......一旦我们切换到自定义光标,无论我们调用多少次setCursor(Qt::QArrowCursor),它都永远无法更改回ArrorCursor。我是否在视口或图形视图本身上调用 setCursor 似乎也并不重要。

因此,只是为了好玩,我在要更改光标之前添加了对 Graphicsview->unsetCursor() 的调用,这至少纠正了第二个问题。只要我们在中间进行一点手动拖动,光标就会发生很好的变化。更好,但肯定不是最佳的。但应该注意的是,在视口上执行 unsetCursor 不起作用。它绝对必须在图形视图上完成 - 无论我们将光标设置在视口上。

为了完全解决这个问题,我在设置光标后添加了这两行:

graphicsview->setDragMode(QGraphicsView::ScrollHandDrag);
graphicsview->setDragMode(QGraphicsView::NoDrag);

这有效,但是你们太棒了!因此,这两种方法内部发生了一些神奇的事情来解决问题,但浏览代码我看不出是什么。我想这与拖动模式正在改变光标这一事实有关。

为了完整起见,我还应该提到触发模式更改的是一个 QPushButton,它已使用 QGraphicsScene->addWidget() 添加到场景中。我不知道这是否与此有关,但你永远不知道。

我希望有人能澄清为什么我需要进行这些看似随机的调用。我不认为我在任何地方做错了什么。预先感谢您的任何帮助。

编辑: 这是带有如上所述的光标补丁的实际代码示例。您可以从下面的链接查看和/或下载它们。粘贴到这里有点长。我包含了光标更改的框架,因为我有一种有趣的感觉,这在某种程度上很重要。

https://gist.github.com/712654

问题所在的代码在 MyGraphicsView.cpp 开始第 104 行。这是图形视图中光标设置的位置。正是如上所述。

请记住,有了非常丑陋的补丁,光标确实可以工作 - 或多或少。如果没有这些行,您将非常清楚地看到上面帖子中列出的问题。

链接中还包含使用视图的主窗口的所有代码等...唯一缺少的是我正在使用的图像。但图像本身并不重要,任何 16x16 png 都可以。

I am trying to make use of a mix of custom cursors and preset cursors for my QGraphicsView.
In my implementation we have created a notion of "modes" for the view. Meaning that depending on what "mode" the user is in, different things will happen on the left-click, or left-click drag. Anyway, none of that is the problem, just the context.

The problem arises when I try to change the cursor for each mode. For instance, for mode 1 we want to show the regular Arrow cursor, but for mode 2, we want to use a custom pixmap. Seemingly simple we call graphicsview->viewport()->setCursor(Qt::QArrowCursor)  when we are switching to mode 1, and graphicsview->viewport()->setCursor(our custom cursor) for mode 2. Except it doesn't work at all.

Firstly, the cursor does not change to the custom cursor. That is the first problem. However, if through another operation the drag mode of the graphics view gets set to ScrollHandDrag, the cursor will switch to the custom cursor once the drag operation is complete. Weird. But the plot thickens... Once we switch to the custom cursor, it can never be changed back to the ArrorCursor no matter how many times we call setCursor(Qt::QArrowCursor). it also doesn't seem to matter whether I call setCursor on the viewport or the graphics view itself.

So, just for fun, I added a call to graphicsview->unsetCursor() just before we want to change the cursor, and that at least rectifies the second problem. The cursor changes just fine so long as we do a little HandDragging in between. Better, but certainly not optimal. However it should be noted, that doing the unsetCursor on the viewport doesn't work. it must absolutely be done on the graphicsview - regardless of the fact that we are setting the cursor on the viewport.

To completely patch over the problem I have added these two lines after I set the cursor:

graphicsview->setDragMode(QGraphicsView::ScrollHandDrag);
graphicsview->setDragMode(QGraphicsView::NoDrag);

Which works, but ye gads!! So something magical is happening inside these two methods that fixes the problem, but glancing at the code I don't see what. Something to do with the fact that the drag mode is changing the cursor I imagine.

Just for completeness, I should also mention that the thing that triggers the mode change, is a QPushButton that has been added to the scene using QGraphicsScene->addWidget(). I don't know if that has anything to do with it, but you never know.

I am hoping that either someone could clarify why I need to make these seemingly random calls. I don't think I am doing anything wrong anywhere. Thanks in advance for any help.

EDIT:
Here is an actual code example with the cursor patches as described above. You can look at and/or download them from the link below. It was a little long to paste here. I included the framework around which the cursors are changed, because I have a funny feeling that that is important somehow.

https://gist.github.com/712654

The code where the problem lies is in MyGraphicsView.cpp starting at line 104. This is where the cursor is set in the graphics view. It is exactly as described above.

Keep in mind, with the very ugly patches in place the cursors do work - more or less. Without those lines you will see very clearly the problems listed in the post above.

Also included in the link, is all the code for a mainWindow that uses the view, etc... the only thing missing are the images I am using. But the images themselves don't matter, any 16x16 pngs will do.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘香 2024-10-11 12:36:53

我添加了一个 museReleaseEvent 来解决类似的问题...

void mouseReleaseEvent(QMouseEvent *event) {
     QGraphicsView::mouseReleaseEvent(event);
     viewport()->setCursor(Qt::CrossCursor);
}

这将在拖动事件完成后重置光标,在拖动过程中手将可见,这是有意义的。

I added a museReleaseEvent to solve a similar problem...

void mouseReleaseEvent(QMouseEvent *event) {
     QGraphicsView::mouseReleaseEvent(event);
     viewport()->setCursor(Qt::CrossCursor);
}

This will reset the cursor after the drag event is complete, during the drag the hand will be visible which makes sense.

看海 2024-10-11 12:36:53

我的解决方案:

view->setDragMode( QGraphicsView::ScrollHandDrag );
QApplication::setOverrideCursor( Qt::ArrowCursor );

My solution:

view->setDragMode( QGraphicsView::ScrollHandDrag );
QApplication::setOverrideCursor( Qt::ArrowCursor );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文