【问题标题】:Qt: How to implement Panning/Zooming in QGraphicsScene with two finger gestures on laptop trackpad (win/mac)?Qt:如何在笔记本电脑触控板(win/mac)上使用两个手指手势在 QGraphicsScene 中实现平移/缩放?
【发布时间】:2021-12-30 09:08:21
【问题描述】:

我有一个使用 QGraphicsScene 的 Qt 6.2 应用程序 (Windows/Mac),并希望在我的笔记本电脑的触摸板上使用两根手指进行平移 - 就像许多其他应用程序一样。

放大/缩小效果很好,但使用 2 根手指平移总是会导致缩小。

我发现了一些问题和一些零碎的样本。但没有半途而废的例子:

这样做的正确方法是什么?

到目前为止我尝试了什么(在 Windows 上):

1)

MyGraphicsView::MyGraphicsView(...) : QGraphicsView()
{
    viewport()->setAttribute(Qt::WA_AcceptTouchEvents);

...
bool MyGraphicsView::viewportEvent ( QEvent * event )
{
     switch (event->type())
    {
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd:
        {
        // never called
        }
MyDocWin::MyDocWin(...) : CMDIAppDocWin(),
{
    setAttribute(Qt::WA_AcceptTouchEvents);
...
bool MyDocWin::event(QEvent *event)
{
    switch (event->type())
    {
    case QEvent::TouchBegin:
    case QEvent::TouchUpdate:
    case QEvent::TouchEnd:
        {
            // never called
        }
...
std::vector<Qt::GestureType> sgGestureTypes = {Qt::TapGesture, Qt::TapAndHoldGesture,Qt::PanGesture       ,Qt::PinchGesture     ,Qt::SwipeGesture         };
    
    
    MyGraphicsView::MyGraphicsView(...) : QGraphicsView()
    {
       for(Qt::GestureType gesture : sgGestureTypes)
            grabGesture(gesture);
    ...
    bool MyGraphicsView::event(QEvent *event)
    {
      switch (event->type())
        {
        case QEvent::Gesture:
        case QEvent::NativeGesture:
                    // never called
    MyDocWin::MyDocWin(...) : CMDIAppDocWin(),
    {
    for (Qt::GestureType gesture : sgGestureTypes)
        grabGesture(gesture);
...
    bool MyDocWin::event(QEvent *event)
    {
        switch (event->type())
        {
        case QEvent::Gesture:
        case QEvent::NativeGesture:
                // never called

【问题讨论】:

    标签: c++ windows qt qgraphicsscene


    【解决方案1】:

    我终于设法完成了这项工作。我发现了什么:

    平移手势(在 Qt 中)被转换为鼠标滚轮消息,它可以有一个 y 和一个 x 偏移量。这对我来说似乎很奇怪,因为没有水平滚轮的鼠标。 更令人困惑的是,根据 MS 的定义,Pan 事件被转换为 WM_VSCROLL/WM_HSCROLL 事件 (https://docs.microsoft.com/en-us/windows/win32/wintouch/windows-touch-gestures-overview)

    Qt 可以很好地处理大部分(即平移),但不是全部:

    • 似乎无法区分触控板上的手势事件和鼠标上的真实滚轮事件。我最初想始终使用鼠标滚轮进行缩放并使用触摸板平移手势。这种组合似乎是不可能的。我现在使用 Ctrl/Shift 进行鼠标滚轮缩放。这解决了问题

    我必须在 Mac 和 Windows 上以不同方式处理两根手指的缩放手势:

    • 在 Windows 上,使用“(event->modifiers() & Qt::ControlModifier) == true”发送滚轮事件。 mac上没有。所以我写道:
      无效 myGraphicsView::wheelEvent(QWheelEvent* 事件)
      {
      if(event->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier))
      我的ZoomFunction(事件,0);
      别的
      QGraphicsView::wheelEvent(事件);
      }
      
    • 在 MacO 上,我们必须监听 QEvent::NativeGesture - 但在 Windows 上不调用:
      bool myGraphicsView::viewportEvent (QEvent * event)
      {
      开关(事件->类型())
      {
      案例 QEvent::NativeGesture:
      auto nge = dynamic_cast(event);
      如果(格)
      {
      if(nge->gestureType() == Qt::ZoomNativeGesture)
    • 在 MacOs 上,向上/向下滚动在 angleDelta().x() 中发送,而不是在 angleDelta().y() 中发送。无论出于何种原因,这两个值都会被交换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多