处理自定义QT小部件中的输入事件
Handle input events in custom Qt widget
我正在使用Visual Studio 2017中的游戏引擎库(AppGameKit(和QT(5.12.3(。通常使用此引擎的默认项目模板,将构建一个可执行的可执行文件,以启动它的可执行文件自己的窗口并处理钥匙和鼠标输入。
现在,我正在尝试调整以在QT中使用(嵌入在QWidget
中(。目前,我通过将QWidget
的HWND
(QWidget::winId()
(传递给游戏引擎初始化功能。
我现在唯一的问题是QT正在处理所有输入(鼠标和键盘(,我需要游戏引擎才能访问它。
通过检查游戏引擎的核心代码,我看到以下WndProc
功能:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
//Lots of input handling
default:
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
return 0;
}
游戏引擎中通常创建Win32窗口的代码执行以下操作(在我的情况下,这是我嵌入窗口小部件的情况下的(:
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = hIcon ? (HICON)hIcon : LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"OPENGLWINDOW";
wcex.hIconSm = NULL;
RegisterClassExW(&wcex);
在某些时候创建窗口:
HWND hWnd = CreateWindowW(L"OPENGLWINDOW", L"AGK", dwStyle, x, y,
WindowRect.right-WindowRect.left, WindowRect.bottom-WindowRect.top, NULL, NULL, hInstance, NULL);
因此,我可以看到WndProc
函数会发生什么,但是我不确定该如何将其"连接"到QT小部件。
一些谷歌搜索我也向我指出了qapplication :: installNativeEvent((,但在我的情况下如何使用它。
编辑
我尝试了installNativeEvent
。因此,我将自己的QAbstractNativeEventFilter
实施为:
class MyEventFilter : public QAbstractNativeEventFilter
{
public:
MyEventFilter(){}
bool nativeEventFilter(const QByteArray &eventType, void *message, long* res) override
{
if (eventType == "windows_generic_MSG") {
res = (long*)WndProc(((MSG*)message)->hwnd, ((MSG*)message)->message, ((MSG*)message)->wParam, ((MSG*)message)->lParam);
}
return false;
}
};
WndProc
在游戏引擎中处理键和鼠标输入。
和main.cpp
:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
AGK_QT w;
w.show();
a.installNativeEventFilter(new MyEventFilter());
return a.exec();
}
但我仍然没有从游戏引擎中的键盘或鼠标中得到任何响应。
问题中的 edit 部分是实际的正确答案。它起初没有工作,但这是因为一个不同的问题。
因此需要QAbstractNativeEventFilter
:
class MyEventFilter : public QAbstractNativeEventFilter
{
public:
MyEventFilter(){}
bool nativeEventFilter(const QByteArray &eventType, void *message, long* res) override
{
if (eventType == "windows_generic_MSG") {
res = (long*)WndProc(((MSG*)message)->hwnd, ((MSG*)message)->message, ((MSG*)message)->wParam, ((MSG*)message)->lParam);
}
return false;
}
};
WndProc
在游戏引擎中处理键和鼠标输入。
在main.cpp
中,将事件过滤器设置为应用程序:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
AGK_QT w;
w.show();
a.installNativeEventFilter(new MyEventFilter());
return a.exec();
}
游戏引擎具有自己的循环,我需要致电:
qApp->processEvents()
我的错误是在更新游戏引擎更新功能之前,我致电qApp->processEvents()
。切换他们被称为我为我修复的顺序。
- 如何在Qt 4.8中阻止/忽略/丢弃早于特定超时的用户输入事件
- 输入验证将数字放入向量中
- 我觉得我放入结构中的输入代码可以压缩,关于如何在保持代码简短的同时保持数据个性化的任何建议?
- 如何获取C++中的输入并将其"split"到列表中?换句话说,取 N 个输入并放入 N 长度的数组中
- 丢失读入的每一行输入中的最后一个令牌
- 使用重定向命令从 stdin 读入的字符串"<"输入文件未正确附加
- 有没有办法在使用 GLFW 按下按键后只处理一个输入事件?
- C++多按键输入或按键按下/释放事件
- 将输入事件发送到窗口
- 跟踪鼠标输入事件
- 处理自定义QT小部件中的输入事件
- 如何处理 OpenSceneGraph 键盘输入事件中的区分大小写
- GetSave文件名 / IFileSaveDialog - 用户输入的事件/对文件名更改做出反应?
- 计算输入文件中数组中放入的"things"数
- 是否可以使用 select(2) 来监视 SDL 文本输入事件
- 事件处理程序是Embarcadero C++Builder中的重入程序吗
- ifstream 代码不会将输入放入变量中
- SIEM通过TCP流式传输,将多条消息输入一个事件中
- SFML 2实时文本输入?(无事件循环)
- 游戏键盘输入和事件