Почему мой QDeclarativeItem не получает никаких событий мыши / клавиатуры?

Это уменьшенный, минимально полный пример, демонстрирующий мою проблему:

У меня есть приложение, которое размещает 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();
}

Тот TestItem это подкласс QDeclarativeItem определено в файле 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
}

Это все построено (с Qt 4.8 на Debian-Wheezy amd64) с файлом qmake

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, когда он выполняет какие-либо действия до состояния QML, и код, из которого он сокращен, не имеет проблем с сигналами и слотами, взаимодействующими между элементом C++ и кодом QML... но когда дело доходит до событий мыши / клавиатуры, есть только никаких признаков их на стороне C++.

1 ответ

Решение

Чтобы получить (левые) события мыши, нужно всего лишь добавить

setAcceptedMouseButtons(Qt::LeftButton);

в TestItem конструктор. Это немного удивительно, так как документация для унаследованных QGraphicsItem::setAcceptedMouseButtons говорит: "По умолчанию все кнопки мыши принимаются", но, возможно, что-то еще в настройке портит состояние.

Чтобы получить события клавиатуры, setFocus(true) просто должен быть вызван. Документация, кажется, подразумевает setFlag(QGraphicsItem::ItemIsFocusable,true) также должен быть вызван, но это на самом деле не кажется необходимым в моем тесте.

Другие вопросы по тегам