将鼠标左键按下事件发送到QGraphicsView时重置滚动条的问题

Problem with resetting scrollbars when left mouse press event is sent to QGraphicsView

提问人:todovvox 提问时间:11/2/2023 更新时间:11/2/2023 访问量:39

问:

因此,我目前正在尝试每次用户在QGraphicsView上按中间按钮时使用ScrollHandDrag在鼠标上实现拖动模式。问题是 - 要实际使用滚动手拖动模式拖动,您必须左键单击。

我的解决方案是简单地在QGraphicsScene之后继承的类中覆盖MousePressEvent方法,并在此处捕获鼠标中键事件,访问使用此QGraphicsScene的QGraphicsView,在QGraphicsView上设置ScrollHandDrag拖动模式,然后从QGraphicsScene向QGraphicsView发送另一个事件,只需单击鼠标左键即可。这样,人们只需使用鼠标中键即可启用 ScrollHandDrag,而实际上只需使用该按钮即可拖动。

这基本上是这样完成的:

case Qt::MiddleButton: {
    views()[0]->setDragMode(QGraphicsView::ScrollHandDrag);

    QMouseEvent eventGraphicsView(QEvent::MouseButtonPress, event->pos(), event->scenePos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
    QApplication::sendEvent(views()[0]->viewport(), &eventGraphicsView);
    break;
}

MousePressEvent必须在QGraphicsScene之后继承的类中被覆盖,因为考虑到现在代码的结构,QGraphicsView不可用。

这里的问题是,即使它工作正常并且我可以拖动 QGraphicsView - 每次我尝试拖动时,滚动条都会将其位置重置为以前的位置。视图似乎跳到最后一个位置,滚动条。

所以问题是——为什么会这样?事件应该有所不同吗?当我使用例如ctrl +左键单击用法实现它时,一切正常,尽管在此实现中我没有向QGraphicsView发送任何类型的事件,所以我想问题出在这里的某个地方。

C++ Qt5 QtWidgets

评论

1赞 musicamante 11/2/2023
事件的重建无效,因为您使用的是场景位置。尽管如此,您应覆盖视图中的(并释放),而不是场景。mouseButtonPress
1赞 musicamante 11/2/2023
您可以将场景位置重新映射到视图,但这似乎毫无意义:为什么不按照上面的建议在视图中执行此操作呢?就您的目的而言,场景甚至不应该首先接收事件。
1赞 musicamante 11/2/2023
你可以只使用小部件升级,这样你只需要实现QGraphicsView类,不需要完全重构。或者,在视口上安装事件过滤器。
1赞 musicamante 11/2/2023
我不确定我是否遵循了您的解释,所以我会给你我的解释:当您在 Designer 中升级小部件时,它将用作具有相同小部件类型的 UI 的“占位符”,并且您为其指定一个升级的类名,这将是您将在代码中使用的实际类(取自升级对话框中设置的头文件)。UI基本上是相同的,允许为特定类型设置属性。在代码中,您将实现自定义类(必须从相同的基类型继承,即使是间接继承),然后重写和/或您需要的任何其他内容。mousePressEvent()
1赞 musicamante 11/2/2023
当您构建程序时,将使用给定的自定义类而不是标准类创建 uic 代码,因为它是在 includes 中声明的,并且当程序运行时,将正确创建自定义类的实例,并完成所有覆盖。这非常有用,因为您可以轻松地创建自定义小部件子类,并通过 Designer 在 UI 中使用它们。不同之处在于,您不会看到自定义类,而只会看到占位符:这意味着,例如,如果您的自定义类以不同的方式绘制其内容,您将不会看到 »setupUi()

答: 暂无答案