6

我正在寻找一个我可以从纯 C 中使用的 GUI 工具包,它至少可以在 Linux 上运行,并且不会强迫我使用它自己的事件循环——我想将 libev 用于主循环并让它在何时通知工具包库X 事件进来左右。

我还没有找到类似的东西——我真的必须修补一个工具包库才能得到我想要的吗?

4

4 回答 4

4

不幸的是,这种需求可能严重限制了您可以选择的 GUI 工具包,因为它们在这方面都非常糟糕(在许多其他方面)。我不知道这作为一个答案是否公平,但我想向您提出一个不同的解决方案:让 GUI 工具包运行它想在自己的线程或进程中运行的任何事件循环. 由于 GUI 库是出了名的糟糕(崩溃或退出而没有警告),“自己的进程”版本实际上可能是最好的主意——您可以通过管道与您的 UI 通信,并像在主要过程。线程当然有自己的好处:不需要序列化与 GUI 共享的数据,也不需要担心用户在不杀死 GUI 的情况下杀死主程序或反之亦然的情况(因为不能单独杀死线程)。

于 2013-11-06T15:32:50.010 回答
1

核弹。

https://github.com/Immediate-Mode-UI/Nuklear

Nuklear 是一个 GUI 工具包,它只创建小部件、按钮、标签和类似的东西,但不使用自己的渲染后端。您必须为其提供渲染后端。您可以使用 Xlib/X11 进行渲染。Xlib 不需要主循环。你可以这样做:

  1. 创建到 X11-server 的连接并创建一个 windows
  2. 初始化窗口(设置事件掩码、加载字体等)
  3. 初始化核上下文
  4. 检查来自 X11 套接字的事件并将它们发送到 Nuklar
  5. 将您的 GUI 绘制到 Nuclear
  6. 将图形基元从 Nuklear 发送到 X11-Server。
  7. 做你需要做的所有其他事情
  8. 使用 XConnectionNumber() 获取 X11-Socket 的文件描述符
  9. 使用 pselect() 等待此文件描述符进行读取以及您等待的所有其他内容。
  10. 在第 4 步重复。

Nuklear 有一个示例头文件,它提供了组合 Nuklear 和 Xlib 所需的功能,可以帮助您完成第 4 步和第 6 步: https ://github.com/Immediate-Mode-UI/Nuklear/blob/master/demo/x11 /nukear_xlib.h

Nukear 有这个特点和缺点:

  • 您可以完全控制它。
  • 它是用 C89 编写的
  • 它本身不需要任何外部库,甚至不需要标准头文件
  • 单头实现
  • 您可以使用所需的渲染后端。
  • 没有不相关的功能,如文件处理或图像加载。您需要其他库或为此编写自己的函数。
  • 与 Qt 等工具包相比,图形可能性有限
于 2020-08-20T17:12:40.743 回答
0

所有工具包都支持这种操作模式。

您需要在自己的事件引擎中观察 X 服务器连接套接字。一旦数据可用,您就可以(在伪代码中)

while (PendingEvent())
  ProcessEvent()

每个工具包都有自己的 ProcessEvent() 版本,也许还有 PendingEvent() 版本(但您始终可以使用XPending(Display*)它)。即,

  • Gtk+ 有gtk_events_pending()gtk_main_iteration()
  • 基于 Xt 的工具包具有XtAppPending()XtDispatchEvent()
  • (c++) wxWidgets 有wxApp::.Pending()wxApp::Dispatch()
  • (c++) Qt 有QApplication::processEvents(),你也可以实现你自己的QAbstractEventDispatcher和/或QEventLoop

积极开发的 C 工具包并不多,我认为 Gtk+ 是唯一合理的选择。

编辑至少使用 GTK,此技术不适用于添加工具包的超时,即闪烁光标不会闪烁,除非有一些其他工具包事件要处理。即使没有未决事件的定期调用gtk_main_iteration_do(FALSE)也可以“修复”这个问题,但是在不同的线程中执行工具包循环会更加健壮。

于 2013-11-06T21:58:13.403 回答
0

我没试过,但GTK+至少有这个gtk_main_iteration_do()功能,它消耗一个事件。该事件虽然是 GDK 事件(不是原始 X11 事件),但可能不是您想要的。

另一方面,GTK 也有一些处理事件的函数,所以也许你可以把一些东西粘在一起。我对libev不是很熟悉,所以我不确定。

于 2013-11-06T15:39:52.253 回答