Qt 4.8。 Mac OS 10.6.8上的平板电脑事件

时间:2013-03-05 08:46:08

标签: qt events tablet

TabletEvents是鼠标事件。

MAC OS Qt 4.8.0 - 4.8.5的实际值。 适用于任何操作系统的Qt 4.7.3和Windows和Linux上的Qt 4.8.0。

我有两个QGraphcisScene实例和两个QGraphicsView实例。 相同的类型,但是一个视图有一个父视图,另一个视图没有 - (它也是透明的,用于在桌面上绘制某些东西)。

我正在使用平板电脑(wacom pen和touch)进行绘画。我处理QTabletEvents,它只适用于没有父级的QGrahicsView实例(意味着父== 0)。

在包含父级的视图上(

  

QMainWindow-> centralWidget-> ControlContainerWidget-> QStackedLayout->的QGraphicsView

)平板电脑事件未到来。他们来QApplication::eventFilter很好,但没有看到。他们以QMainWindow身份mouseEvents来到qt_mac_handleTabletEvent。 如果我将父级设置为0,则平板电脑事件可以正常运行。

平板电脑活动的第一个接收者是QMainWindow。 我在QWidget *qwidget = [theView qt_qwidget]; QWidget *widgetToGetMouse = qwidget; 内看到了:

`qt_sendSpontaneousEvent(widgetToGetMouse, &qtabletEvent);`

然后:

qtabletEvent

sendSpontaneousEvent - 在调用QWidget *w = static_cast<QWidget *>(receiver); QTabletEvent *tablet = static_cast<QTabletEvent*>(e); QPoint relpos = tablet->pos(); bool eventAccepted = tablet->isAccepted(); while (w) { QTabletEvent te(tablet->type(), relpos, tablet->globalPos(), tablet->hiResGlobalPos(), tablet->device(), tablet->pointerType(), tablet->pressure(), tablet->xTilt(), tablet->yTilt(), tablet->tangentialPressure(), tablet->rotation(), tablet->z(), tablet->modifiers(), tablet->uniqueId()); te.spont = e->spontaneous(); res = d->notify_helper(w, w == receiver ? tablet : &te); eventAccepted = ((w == receiver) ? tablet : &te)->isAccepted(); e->spont = false; if ((res && eventAccepted) || w->isWindow() || w->testAttribute(Qt::WA_NoMousePropagation)) break; relpos += w->pos(); w = w->parentWidget(); } tablet->setAccepted(eventAccepted); 之前创建的事件未被接受。

然后在QApplication :: notify()中:

res = d->notify_helper(w, w == receiver ? tablet : &te);

我们可以看到:

QMainWindow::tabletEven

它通过过滤器,布局调用事件处理,然后调用 - event->ignore() t。默认实施是QWidget *qwidget = [theView qt_qwidget];

由于QMainWindow没有Parent,所以全部都是。 所以平板电脑事件不会出现在QMainWindow的孩子身上。

然后似乎{{1}}工作错了。 不幸的是,我无法调试它......

请给我一些提示......我被困了......

1 个答案:

答案 0 :(得分:0)

我花了更多的时间来比较Qt 4.8.0和4.7.3,现在我发现它是内部qt事件调度程序中的问题。它将事件发送到NSWindow(QMainWindow)而不是NSView(QGraphicsView)。 我没有找到问题所在,但我发现QMainWindow从:: event()方法返回false。 所以我重新实现了那个方法并在那里解析了平板电脑事件:

bool UBMainWindow::event(QEvent *event)
{
    bool bRes = QMainWindow::event(event);

    if (NULL != UBApplication::boardController)
    {
        UBBoardView *controlV = UBApplication::boardController->controlView();
        if (controlV && controlV->isVisible())
        {
            switch (event->type())
            {
            case QEvent::TabletEnterProximity:
            case QEvent::TabletLeaveProximity:
            case QEvent::TabletMove:
            case QEvent::TabletPress:
            case QEvent::TabletRelease:
                {
                    return controlV->directTabletEvent(event);
                }
            }
        }
    }
    return bRes;
}

问题是:我需要在应用程序中使用平板电脑进行任何控制,所以我需要确定QGraphicsView何时在鼠标光标下:

bool UBBoardView::directTabletEvent(QEvent *event)
{
    QTabletEvent *tEvent = static_cast<QTabletEvent *>(event);
    tEvent = new QTabletEvent(tEvent->type()
        , mapFromGlobal(tEvent->pos())
        , tEvent->globalPos()
        , tEvent->hiResGlobalPos()
        , tEvent->device()
        , tEvent->pointerType()
        , tEvent->pressure()
        , tEvent->xTilt()
        , tEvent->yTilt()
        , tEvent->tangentialPressure()
        , tEvent->rotation()
        , tEvent->z()
        , tEvent->modifiers()
        , tEvent->uniqueId());

    if (geometry().contains(tEvent->pos()))
    {
        if (NULL == widgetForTabletEvent(this->parentWidget(), tEvent->pos()))
        {
            tabletEvent(tEvent);
            return true;
        }
    }
    return false;
}

此外,我还需要停止处理QGraphicsView孩子的平板电脑事件。

QWidget *UBBoardView::widgetForTabletEvent(QWidget *w, const QPoint &pos)
{
    Q_ASSERT(w);


    UBBoardView *board = qobject_cast<UBBoardView *>(w);

    QWidget *childAtPos = NULL;

    QList<QObject *> childs = w->children();
    foreach(QObject *child, childs)
    {
        QWidget *childWidget = qobject_cast<QWidget *>(child);
        if (childWidget)
        {
            if (childWidget->isVisible() && childWidget->geometry().contains(pos))
            {
                QWidget *lastChild = widgetForTabletEvent(childWidget, pos);

                if (board && board->viewport() == lastChild)
                    continue;

                if (NULL != lastChild)
                    childAtPos = lastChild;
                else
                    childAtPos = childWidget;

                break;
            }
            else
                childAtPos = NULL;
        }
    }
    return childAtPos;
}

也许当我有更多时间 - 我会更深入地研究qt并解决这个问题。