对于 3D 建模项目,我使用 SDL 并将其包含在 GTK Widget 中(感谢 [GTKSDL]、http://gtksdl.sourceforge.net“直接链接到 GTKSDL”)。
该小部件只是使用 GTK 加载 .obj 文件并使用 OpenGL 对其进行建模,然后将其显示在 SDL 小部件中。 到目前为止,一切正常。
当我尝试使用 SDL 事件移动小部件中的对象时,问题就出现了。在 GTK 中集成 SDL 窗口之前,事件运行没有任何问题。 另外,一旦显示 3D 模型,我就不可能与 GTK 交互,因为显然 SDL 的事件循环正在等待某些东西,而无论我做什么,它都没有得到它。
我想过 fork 两个事件循环,但似乎 GTK 和 SDL 试图同时访问 X 服务器,这会产生多个冲突。 我尝试删除 SDL 中的无限循环,但它也不起作用。
我在 Devian,我在互联网上搜索了“GTKSdl”的实现,但它似乎已经过时了,有什么想法如何修补它吗?
更新:
我已经在使用 SDLPollEvent 和 g_idle add。 因此,在我选择一个文件(使用 GTK)后,我填充结构“t_stage”并使用 g_idle_add :
g_idle_add((GSourceFunc) &mainloop, stage);
gboolean mainloop(t_stage *stage)
{
SDL_Event evt;
while (SDL_PollEvent(&evt) != 0)
{
if (evt.type == SDL_MOUSEBUTTONDOWN)
on_mouse_down(stage, &(evt.button));
else if (evt.type == SDL_MOUSEBUTTONUP)
on_mouse_up(stage, &(evt.button));
else if (evt.type == SDL_MOUSEMOTION)
on_mouse_move(stage, &(evt.motion));
else if (evt.type == SDL_KEYDOWN)
handle_key(stage, evt.key.keysym.sym, 1);
else if (evt.type == SDL_KEYUP)
handle_key(stage, evt.key.keysym.sym, 0);
}
apply_keys(stage);
draw(stage, 0);
return (1);
}
但是事件仍然没有收到。有什么想法吗?
最佳答案
GTKSDL 似乎是 2001 年创建的 alpha 质量小部件,但从未维护过(我认为也没有广泛使用)。从那时起,GTK 发生了很大变化,所以我不确定这是否是最适合您的解决方案。
但是,您面临的问题之一是您不能在 GTK 的事件处理程序内使用无限循环(对于我所知道的使用消息泵的每个事件驱动工具包也是如此)。如果这样做,您只会阻止 GTK 有机会处理待处理的事件。有关如何解决此问题的更多信息,请查看Embedding SDL into GTK+
更新:
g_idle_add
允许指定回调和传递给该回调的参数(gpointer data
参数)。 gpointer 只是一个指向 void 的指针。如果您需要回调了解多个参数,您可以向其传递要读/写的结构的地址。
在使用 g_idle_add
注册的回调中,您可以读取 SDL 事件。不要使用SDL_WaitEvent
为此,因为它将阻塞直到发生 SDL 事件,所以使用 SDL_PollEvent
(检索待处理事件(如果有))或 SDL_PeepEvents
(检索所有待处理事件(如果有))。这些函数是非阻塞的,如果没有事件待处理,它们就会返回,而 SDL_WaitEvent 将阻塞,直到收到事件。
然后您可以处理事件,确保退出空闲处理程序之前不会花费太长时间,否则 GTK UI 将卡住。您可能还希望将这些事件转换为 GTK 事件,然后将它们分派(dispatch)给 GTK 以供其处理。
您还有一个旧的 example of SDL integration with GTK 1.2 。我认为其中大部分都可以与 GTK 2 一起使用,基本思想就在那里,只需要更新代码以替换从那时起在 GTK 中已弃用的符号即可。
关于c - GTKSDL - 处理事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10191703/