我正在寻找一个我可以从纯 C 中使用的 GUI 工具包,它至少可以在 Linux 上运行,并且不会强迫我使用它自己的事件循环——我想将 libev 用于主循环并让它在何时通知工具包库X 事件进来左右。
我还没有找到类似的东西——我真的必须修补一个工具包库才能得到我想要的吗?
我正在寻找一个我可以从纯 C 中使用的 GUI 工具包,它至少可以在 Linux 上运行,并且不会强迫我使用它自己的事件循环——我想将 libev 用于主循环并让它在何时通知工具包库X 事件进来左右。
我还没有找到类似的东西——我真的必须修补一个工具包库才能得到我想要的吗?
不幸的是,这种需求可能严重限制了您可以选择的 GUI 工具包,因为它们在这方面都非常糟糕(在许多其他方面)。我不知道这作为一个答案是否公平,但我想向您提出一个不同的解决方案:让 GUI 工具包运行它想在自己的线程或进程中运行的任何事件循环. 由于 GUI 库是出了名的糟糕(崩溃或退出而没有警告),“自己的进程”版本实际上可能是最好的主意——您可以通过管道与您的 UI 通信,并像在主要过程。线程当然有自己的好处:不需要序列化与 GUI 共享的数据,也不需要担心用户在不杀死 GUI 的情况下杀死主程序或反之亦然的情况(因为不能单独杀死线程)。
https://github.com/Immediate-Mode-UI/Nuklear
Nuklear 是一个 GUI 工具包,它只创建小部件、按钮、标签和类似的东西,但不使用自己的渲染后端。您必须为其提供渲染后端。您可以使用 Xlib/X11 进行渲染。Xlib 不需要主循环。你可以这样做:
Nuklear 有一个示例头文件,它提供了组合 Nuklear 和 Xlib 所需的功能,可以帮助您完成第 4 步和第 6 步: https ://github.com/Immediate-Mode-UI/Nuklear/blob/master/demo/x11 /nukear_xlib.h
Nukear 有这个特点和缺点:
所有工具包都支持这种操作模式。
您需要在自己的事件引擎中观察 X 服务器连接套接字。一旦数据可用,您就可以(在伪代码中)
while (PendingEvent())
ProcessEvent()
每个工具包都有自己的 ProcessEvent() 版本,也许还有 PendingEvent() 版本(但您始终可以使用XPending(Display*)
它)。即,
gtk_events_pending()
和gtk_main_iteration()
XtAppPending()
和XtDispatchEvent()
wxApp::.Pending()
和wxApp::Dispatch()
QApplication::processEvents()
,你也可以实现你自己的QAbstractEventDispatcher
和/或QEventLoop
类积极开发的 C 工具包并不多,我认为 Gtk+ 是唯一合理的选择。
编辑至少使用 GTK,此技术不适用于添加工具包的超时,即闪烁光标不会闪烁,除非有一些其他工具包事件要处理。即使没有未决事件的定期调用gtk_main_iteration_do(FALSE)
也可以“修复”这个问题,但是在不同的线程中执行工具包循环会更加健壮。
我没试过,但GTK+至少有这个gtk_main_iteration_do()
功能,它消耗一个事件。该事件虽然是 GDK 事件(不是原始 X11 事件),但可能不是您想要的。
另一方面,GTK 也有一些处理事件的函数,所以也许你可以把一些东西粘在一起。我对libev不是很熟悉,所以我不确定。