2

这是一个简化的、最小的完整示例,展示了我的问题:

我有一个托管一个应用程序QDeclarativeView;文件events.cpp

#include <QApplication>
#include <QDeclarativeView>
#include "TestItem.h"

int main(int argc,char* argv[]) {
  QApplication app(argc,argv);

  qmlRegisterType<TestItem>("Testing",1,0,"Tester");

  QDeclarativeView page;
  page.setSource(QUrl("page.qml"));
  Q_ASSERT(page.status()==QDeclarativeView::Ready);
  page.show();
  return app.exec();
}

TestItemQDeclarativeItem文件中定义的子类TestItem.h

#ifndef _TestItem_h_
#define _TestItem_h_

#include <iostream>
#include <QDeclarativeItem>
#include <QPainter>

class TestItem : public QDeclarativeItem {
  Q_OBJECT
public:
  TestItem() {
    setFlag(QGraphicsItem::ItemHasNoContents,false);
    std::cerr << "[TestItem created]";
  }
  void paint(QPainter* painter,const QStyleOptionGraphicsItem*,QWidget*) {
    painter->drawLine(0,0,width(),height());
    painter->drawLine(0,height(),width(),0);
  }
protected:
  void mousePressEvent(QGraphicsSceneMouseEvent*) {
    std::cerr << "[TestItem::mousePressEvent]";
  }
  void keyPressEvent(QKeyEvent*) {
    std::cerr << "[TestItem::keyPressEvent]";
  }
};

#endif

page.qml加载到的文件很QDeclarativeView简单:

import QtQuick 1.0
import Testing 1.0

Tester {
  width: 200
  height: 200
}

全部使用 qmake 文件构建(在 Debian-Wheezy amd64 上使用 Qt 4.8)

CONFIG += debug

QT += core gui declarative

TARGET = events
TEMPLATE = app

SOURCES += events.cpp 
HEADERS += TestItem.h

并且,一旦构建,当我运行时,./events我会得到一个显示测试器绘制的“X”的窗口,正如预期的那样:

在此处输入图像描述

[TestItem created]登录到控制台。但是,在窗口内单击或完全按下键都无法调用鼠标或键事件处理程序。

我完全迷惑了。是否需要一些额外的魔法(在 C++ 或 QML 域中)才能将鼠标/键盘事件路由到这些“插件”QDeclarativeItem类?我当然没有任何问题MouseArea在 QML 文件中定义 a 并让它对 QML 状态进行处理,并且减少的代码在 C++ 项和 QML 代码之间的信号和插槽互操作方面没有问题......但是当它涉及鼠标/键盘事件,在 C++ 端没有它们的迹象。

4

1 回答 1

2

要获取(左)鼠标事件,只需要添加

setAcceptedMouseButtons(Qt::LeftButton);

TestItem构造函数中。这有点令人惊讶,因为继承的文档QGraphicsItem::setAcceptedMouseButtons说“默认情况下,所有鼠标按钮都被接受”,但设置中的其他内容可能会与状态混淆。

要获取键盘事件,setFocus(true)只需要调用即可。该文档似乎暗示setFlag(QGraphicsItem::ItemIsFocusable,true)也应该被调用,但在我的测试中它实际上似乎没有必要。

于 2013-06-15T23:24:04.727 回答