2011-05-16 2 views
1

Я пытаюсь создать gui для приложения дополненной реальности с помощью kinect. Идея состоит в том, чтобы использовать руки, обнаруженные отслеживанием скелета kinect, для управления приложением посредством жестов.Когда я отправляю или отправляю QMouseEvent, в позиции QPushbutton, его сигнал clicked() не испускается

Этот вопрос не касается жестов, так как эта часть моей пристройки отлично работает.

В моем приложении я хочу, чтобы имитировать щелчок мыши, когда выполняется жест щелчка. Чтобы сделать это, я отправляю два события: один, мышь и один mousebuttonreleased, так как обычный щелчок также представляет собой серию пресс-релизов.

Все это отлично работает на QWebView. В окне браузера я могу «щелкнуть» по ссылкам.

Но по какой-то причине я не могу «щелкнуть» на QPushButton. Сигнал clicked() не испускается. У меня есть небольшой пример, чтобы проиллюстрировать мою проблему:

Первая основная функция:

int main(int argc, char **argv){ 
    QApplication app(argc, argv); 
    QWebViewButtons mainapp(0, Qt::Window); 
    app.setActiveWindow(&mainapp); 
    mainapp.show(); 
    mainapp.setApplication(&app); //this is a setter to also get access to the main application in the widget 
    return app.exec(); 
} 

Это мой собственный виджет:

QWebViewButtons::QWebViewButtons(QWidget* parent, Qt::WindowFlags flags): QWidget(parent, flags){ 
    this->m_ui.setupUi(this); 
    QObject::connect(this->m_ui.pushButton, SIGNAL(clicked(bool)), this, SLOT(buttonClicked(bool))); 
} 

void QWebViewButtons::mousePressEvent(QMouseEvent* event){ 
    printf("mouse click, %d, %d\n", event->pos().x(), event->pos().y()); 
} 

void QWebViewButtons::buttonClicked(bool clicked){ 
    printf("slot button clicked\n");  
} 

void QWebViewButtons::keyPressEvent(QKeyEvent* event){ 
    printf("Key pressed\n"); 
    QPoint pos(this->width()/2, this->height()/2); 
    QPoint global = this->mapToGlobal(pos); 
    QWidget *w = this->m_app->widgetAt(global); 
    //printf("widget under point of click: %s", w); 
    QApplication::sendEvent(w, new QMouseEvent(QEvent::MouseButtonPress, pos, Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier)); 
    QApplication::sendEvent(w, new QMouseEvent(QEvent::MouseButtonRelease, pos, Qt::MouseButton::LeftButton, Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier)); 
} 

Я последовал предложение здесь: Qt Artificial mouse clicks doesnt work properly и отправить отправлять события мыши непосредственно в QPushButton. Но это не помогло. Я также попытался отправить события мыши в «это» или в основное приложение.

Теперь у меня заканчиваются идеи. Что я хочу, так это то, что слот buttonClicked() вызывается, если я нажимаю любую клавишу. Но я только вызывается, если я нажму кнопку с помощью мыши. Как я могу это сделать? Или моя основная идея полностью ложна?

Спасибо за ваши идеи.

+0

поэтому QWidget * w = this-> m_app-> widgetAt (глобальный); вы знаете, какая кнопка была активирована? но не можете сказать, что приложение было нажато? – Exa

+0

Я знаю, какой виджет находится в этой позиции, а затем я могу проверить, является ли это кнопкой, и вызывать функцию click(). Но это не то, что я хочу, потому что тогда мне не нужно было бы отправлять события мыши. То, что я хочу, заключается в том, чтобы добиться такого же поведения, как если бы щелкнула левая кнопка мыши, и оставил Qt остальным, независимо от того, была ли кнопка или что-то еще. – Valerie

ответ

0

Хорошо, фокус в том, чтобы действительно отправить клик на точный виджет в нужное положение щелчка. В моем приложении у меня были проблемы из-за полупрозрачных виджетов, лежащих друг над другом.

Таким образом, команда widgetAt (global) не поможет мне. Но вместо этого вы можете использовать childAt (global). Конечно, вам нужно знать, с какого виджета вы хотите найти ребенка.

Это сделало трюк для меня. :-)

1

Итак, я правильно понял? Когда вы делаете свой «щелчок», вы попадаете в keyPressEvent? Если это так, вы можете проверить, был ли «клик» сделан над кнопкой и явно вызвал сигнал щелчка кнопки(). Но это не то, что вы хотите?

А что такое QWebViewButtons? Область, в которой пользователь выполняет свои жесты?

Вы отлаживали функцию keyPressEvent, чтобы увидеть, имеет ли ваш sendEvent правильный виджет (w)? Я не понимаю, почему виджет не должен получать событие ...

И помните, что при обновлении QMouseEvent и отправке его через sendEvent никогда не удаляется. При использовании sendEvent вы должны создать свое событие в стеке.

Возможно, вам стоит взглянуть на эту тему, где рекомендуется QTestEventList: Mimicking/faking a Mouse Click and Mouse Wheel using Qt. Но я могу себе представить, что вы не хотите, чтобы тестовые функции делали трюк;)

+0

Я думаю, проблема в том, что я не знаю, к какому виджету/объекту я должен отправить свои события кликов. В моем реальном приложении я не знаю, где кнопки, поскольку они расположены через макеты, и еще хуже. Есть несколько виджетов друг над другом, а некоторые из них прозрачны. В этом приложении, когда я вызываю функцию widgetAt, я не получаю кнопку, даже если я ее нажму. Он возвращает один из других виджетов. Если я отправлю мой mouseevent этому виджету, некоторые из них дойдут до моей кнопки. Но не все. К сожалению, я не могу использовать этот почтовый код, потому что это слишком много. – Valerie

+0

В приложении, упомянутом в приведенном выше комментарии, я могу «щелкнуть» одну кнопку с помощью жестов. Но когда я пытаюсь нажать на другой, всегда первый получает mouseclickevent. Не важно, какую кнопку я нажимаю с первого щелчка, все последующие клики направляются к этому. Как я могу вызвать такое поведение? – Valerie