Я пытался принимать события касания в Qt6 следующим образом: в main.cpp:
QApplication::setAttribute(Qt::ApplicationAttribute::WA_AcceptTouchEvents);
error: no member named 'WA_AcceptTouchEvents' in 'Qt::ApplicationAttribute'
IntelliSense показывает, что Qt::ApplicationAttribute имеет WA_AcceptTouchEvents. Но я думаю, что это ошибка Qt Creator, потому что в WA_AcceptTouchEvents нет Qt::ApplicationAttribute:
и я попытался запустить этот код:
QApplication::setAttribute(Qt::WA_AcceptTouchEvents);
error: cannot initialize a parameter of type 'Qt::ApplicationAttribute' with an rvalue of type 'Qt::WidgetAttribute'
Я пытался принять это в конструкторе окна, но у QOpenGLWindow нет метода setAttribute:
error: use of undeclared identifier 'setAttribute'; did you mean 'QInputMethodEvent::Attribute'?
OpenGLWindow::OpenGLWindow()
{
setTitle("OpenGL ES 2.0, Qt6, C++");
resize(350, 350);
setAttribute(Qt::WA_AcceptTouchEvents);
}
Мой профайл:
QT += core gui opengl widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# disables all the APIs deprecated before Qt 6.0.0
# DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000
SOURCES += \
main.cpp \
opengl_window.cpp
HEADERS += \
opengl_window.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
Добавлен
musicamante разместил следующую ссылку и цитату в комментариях ниже:
документация (Обработка событий), «В отличие от виджетов, QWindows всегда получают события касания, нет необходимости соглашаться. При работе напрямую с QWindow достаточно переопределить QWindow::touchEvent()»
Но когда я запускаю следующий код на реальном устройстве, прикасаюсь к экрану (он печатает counter = 0), удерживая палец на экране, пытаюсь коснуться другим пальцем и не печатаю следующую строку, как counter = 1. Такое впечатление, что мультитач отключен.
void OpenGLWindow::touchEvent(QTouchEvent *event)
{
switch (event->type())
{
case QEvent::TouchBegin:
qDebug() << "counter = " << m_counter;
m_counter++;
break;
}
}
Перекрестная ссылка: https://forum.qt.io/topic/155009/how-to-accept-touch-events-in-qt6
Компилятор прав - в Qt::ApplicationAttribute нет WA_AcceptTouchEvents, только ion Qt::WidgetAttribute
QWidget::setAttribute(), так что же такое OpenGLWindow?
Кажется, вы пробуете что-то случайно. Как должно быть ясно из документации, перечисления WA_* являются частью атрибутов виджета, которые по очевидным причинам не могут быть произвольно использованы для чего-либо, кроме виджетов, таких как объекты QApplication или QWindow. Кроме того, опять же из документации (Обработка событий): «В отличие от виджетов, QWindows всегда получают события касания, нет необходимости соглашаться. При работе напрямую с QWindow достаточно переопределить QWindow::touchEvent() ".
@chehrlic IntelliSense показывает, что Qt::ApplicationAttribute имеет WA_AcceptTouchEvents. Я опубликовал скриншот. Я думаю, что это ошибка Qt Creator.
@pptaszni Я удалил изображения. Я думал, так будет понятнее.
@musicamante Но когда я запускаю код с помощью touchEvent (см. код в моем посте) на реальном устройстве, прикасаюсь к экрану (он печатает counter = 0), удерживая палец на экране, пытаюсь коснуться другим пальцем, но не получается напечатайте следующую строку, например counter = 1. Такое впечатление, что мультитач отключен.
@8Observer8: поскольку в QtCreator нет IntelliSense, я не знаю, что вы пытаетесь мне сказать. Здесь нет необходимости в полной квалификации значения перечисления, поскольку это простое перечисление, а не класс перечисления.
@8Observer8 QTouchEvent группирует несколько точек касания, добавление пальца создает не новое событие TouchBegin, а событие TouchUpdate, вам необходимо принять событие начала, чтобы получать события обновления, аналогично тому, что происходит с событиями MouseButtonPress и MouseMove. Все это объяснено в том же разделе, на который я дал ссылку выше, вы действительно все это прочитали?
@chehrlic Да, извини. Qt Creator не имеет IntelliSense, поскольку «IntelliSense — это технология автозаполнения Microsoft, наиболее известная в Microsoft Visual Studio. Добавляет имя функции при вводе начальных букв». Я не знаю, как называется технология автодополнения в Qt Creator. Я просто хотел отметить, что система завершения в Qt Creator предполагает, что WA_AcceptTouchEvents находится в Qt::ApplicationAttribute.
@musicamante Спасибо большое! Добавил решение в конец темы.
Просто на заметку на будущее. Если я использую QOpenGLWidget вместо QOpenGLWindow, мне придется вызвать конструктор: setAttribute(Qt::WidgetAttribute::WA_AcceptTouchEvents); Неправильно вызывать следующую команду внутри main.cpp: QApplication::setAttribute(Qt::WidgetAttribute::WA_AcceptTouchEvents);
Я написал решение своей проблемы здесь: forum.qt.io/topic/155009/…
@8Observer8 Пожалуйста, не оставляйте ответы в теле вопроса, сайт так не работает. Я проголосовал за возобновление вашего вопроса, как только вы сможете опубликовать свое решение в качестве фактического ответа, используя соответствующую кнопку. Кроме того, избегайте добавления ссылок для перекрестных публикаций (вы уже делали это в прошлом): если другая ссылка не предоставляет дополнительную информацию, которая фактически расширяет/объясняет то, что вы здесь уже пишете, у кого-либо нет причин проходить полную поток, который, возможно, будет содержать ту же информацию, которую вы уже предоставили.
@8Observer8 Этот «неправильный вызов», очевидно, неверен по причинам, объясненным выше: вы можете устанавливать атрибуты виджетов в виджетах, а не в приложении. Нет необходимости это делать, так как это должно быть совершенно ясно из соответствующей документации QWidget.setAttribute() или QCoreApplication.setAttribute(). Как уже было сказано, вам нужно уделять больше внимания документации и быть более терпеливым в обучении/решении.
@musicamante, почему, если я позвоню print(dir(Qt.ApplicationAttribute)) в PyQt6, я не увижу WA_AcceptTouchEvents? Qt Creator не должен показывать WA_AcceptTouchEvents, если я печатаю Qt::ApplicationAttribute::
@musicamante Я создаю тему: «Qt Creator предполагает, что WA_AcceptTouchEvents находится в Qt::ApplicationAttribute» forum.qt.io/topic/155020/…
@8Observer8 Автодополнение — это просто интерпретируемое (и не всегда надежное) расширение семантики, а не правильный логический синтаксис: значение имеет фактическая реализация, выполняемая во время компиляции/выполнения. print(dir(Qt.ApplicationAttribute)), очевидно, будет отображать перечисления AA_* (ApplicationAttribute), а не WA_*: завершение основано на автоматическом анализе и следует независимой логике, которая может быть несовместима с интерпретатором/компилятором. Это может быть ошибка Creator, но это совершенно не имеет значения: Python (и C++) обращается к реальным объектам и ApplicationAttribute содержит только AA_* перечисления.
Как написал в комментариях musicamante, ответ есть в документации:
из документации (Обработка событий), «В отличие от виджетов, QWindows всегда получают события касания, нет необходимости соглашаться. При работе напрямую с QWindow достаточно переопределить QWindow::touchEvent()».
Очень полезная заметка о мультитачах от musicamante:
QTouchEventгруппирует несколько точек касания, добавление пальца создает не новоеTouchBegin, а событиеTouchUpdate, вам необходимо принять событие начала, чтобы получать события обновления, аналогично тому, что происходит с событиямиMouseButtonPressиMouseMove.
Мне следует уделять больше внимания документации.
Этот пример кода работает для меня:
opengl_window.h
#ifndef OPENGL_WINDOW_H
#define OPENGL_WINDOW_H
#include <QtGui/QTouchEvent>
#include <QtOpenGL/QOpenGLWindow>
class OpenGLWindow : public QOpenGLWindow
{
Q_OBJECT
public:
OpenGLWindow();
private:
void touchEvent(QTouchEvent *event) override;
int m_counter = 0;
};
#endif // OPENGL_WINDOW_H
opengl_window.cpp
#include "opengl_window.h"
OpenGLWindow::OpenGLWindow()
{
setTitle("OpenGL ES 2.0, Qt6, C++");
resize(350, 350);
}
void OpenGLWindow::touchEvent(QTouchEvent *event)
{
switch (event->type())
{
case QEvent::TouchBegin:
qDebug() << "touch begin";
event->accept();
break;
case QEvent::TouchEnd:
qDebug() << "touch end";
break;
case QEvent::TouchUpdate:
qDebug() << "counter = " << m_counter;
m_counter++;
for (int i = 0; i < event->points().length(); i++) {
int x = event->points()[i].position().x();
int y = event->points()[i].position().y();
qDebug() << x << " " << y;
}
break;
}
}
main.cpp
#include <QtWidgets/QApplication>
#include "opengl_window.h"
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::ApplicationAttribute::AA_UseDesktopOpenGL);
QApplication a(argc, argv);
OpenGLWindow w;
w.show();
return a.exec();
}
про
QT += core gui opengl widgets
CONFIG += c++17
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# disables all the APIs deprecated before Qt 6.0.0
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000
SOURCES += \
main.cpp \
opengl_window.cpp
HEADERS += \
opengl_window.h
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
Пожалуйста, указывайте код как код, а не изображения.