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}}工作错了。 不幸的是,我无法调试它......
请给我一些提示......我被困了......
答案 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并解决这个问题。