Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否存在不需要使用自己的事件循环的GUI C库?_C_User Interface_X11_Toolkit_Event Loop - Fatal编程技术网

是否存在不需要使用自己的事件循环的GUI C库?

是否存在不需要使用自己的事件循环的GUI C库?,c,user-interface,x11,toolkit,event-loop,C,User Interface,X11,Toolkit,Event Loop,我正在寻找一个GUI工具包,我可以从纯C中使用它,它至少在Linux上工作,并且不强迫我使用它自己的eventloop–我想使用libev作为主循环,并让它在出现X事件时通知工具箱库 我还没有找到类似的东西——我真的需要修补工具包库才能得到我想要的吗?不幸的是,这种需求可能严重限制了您可以选择什么GUI工具包,因为它们在这方面都非常糟糕(在许多其他方面)。我不知道这是否是一个公平的答案,但我想向您提出一个不同的解决方案:让GUI工具包在它自己的线程或进程中运行它想要运行的任何事件循环。由于GUI

我正在寻找一个GUI工具包,我可以从纯C中使用它,它至少在Linux上工作,并且不强迫我使用它自己的eventloop–我想使用libev作为主循环,并让它在出现X事件时通知工具箱库


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

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

我没有尝试过,但GTK+至少有一个函数,它只消耗一个事件。但该事件是一个GDK事件(不是原始X11事件),所以这可能不是您想要的


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

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

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

每个工具箱都有自己版本的ProcessEvent(),可能还有PendingEvent()(但您可以始终使用
xpend(Display*)
)。即

  • Gtk+具有
    Gtk_事件\u挂起()
    Gtk_主迭代()
  • 基于Xt的工具包有
    XtAppPending()
    XtDispatchEvent()
  • (c++)wxWidgets具有
    wxApp::.Pending()
    wxApp::Dispatch()
  • (c++)Qt具有
    QApplication::processEvents()
    ,您还可以实现自己的
    QAbstractEventDispatcher
    和/或
    QEventLoop
没有那么多积极开发的C工具包,我认为Gtk+是唯一合理的选择

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

Nuklear。

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

  • 创建到X11服务器的连接并创建windows
  • 初始化窗口(设置事件掩码、加载字体等)
  • 初始化一个Nuklear上下文
  • 检查X11套接字中的事件并将其发送到Nuklear
  • 将您的GUI绘制到Nuklear
  • 将图形原语从Nuklear发送到X11服务器
  • 做所有其他你需要做的事情
  • 使用XConnectionNumber()获取X11套接字的文件描述符
  • 使用pselect()等待此文件描述符读取以及等待的所有内容
  • 重复步骤4
  • Nuklear有一个示例头文件,提供了组合Nuklear和Xlib所需的函数,可以帮助您完成步骤4和6:

    Nuklear有以下特点和缺点:

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

    我在自己的epoll事件循环中使用了ncurses——我只调用ncurses处理程序一次,只要stdin可以读取。@KerrekSB是的,我考虑过类似的事情。。。但是,我可能还必须至少修补工具箱的超时逻辑。即使gui工具箱有到自己的事件循环的连接,您也不必设置任何连接属性,例如,我使用的连接属性绑定到事件循环,但仅通过我绘制控件后设置的属性。因此,我可以完全避免使用事件循环,并选择以编程方式设置任何属性,因为我需要反映我的应用程序的状态。出于好奇,您为什么有这样的需要?“在额外线程和上下文切换上浪费资源”-您希望避免浪费的主要资源是您的时间。问题是我的程序/libev需要知道什么时候需要调用这个方法,除非我从libev或者busyloop上看到glib所看到的一切,一次又一次地调用该方法会浪费资源。@通过观察X连接套接字(仅)可以知道事件是否可用。一旦你在套接字上有了一些数据,就运行
    while(gtk_events_pending()){gtk_main_iteration()}
    @thejeh注意,例如glib/gtk还有一个事件循环,你可以用与使用libev相同的方式来集成它——你可以添加自己的套接字、计时器或其他东西,并以与libev类似的方式接收回调
    while (PendingEvent())
      ProcessEvent()