libui是一个 C 中简单且可移植(但并非不灵活)的 GUI 库,它使用每个平台原生的GUI技术进行绘制。
官网地址:链接
相关文件:链接

一、配置说明

1. 所需链接的库

在使用libui的过程中至少需要链接以下库

user32.lib
kernel32.lib
gdi32.lib
comctl32.lib
uxtheme.lib
msimg32.lib
comdlg32.lib
d2d1.lib
dwrite.lib
ole32.lib
oleaut32.lib
oleacc.lib
uuid.lib
windowscodecs.lib
libui.a

2. 静态库的使用

静态库在使用时还需要在项目中加入资源文件,下面的 文件 选择其中之一即可

  • static.manifest
  • resources.res

如果使用resources.res出现问题,请见 解决办法

二、简单使用

1. 空白窗口

#include <stdio.h>
#include "ui.h"int onClosing(uiWindow* w, void* data)
{uiQuit();return 1;
}int main(void)
{uiInitOptions o = { 0 };const char* err;uiWindow* window;// 初始化uierr = uiInit(&o);if (err != NULL) {fprintf(stderr, u8"初始化错误: %s\n", err);uiFreeInitError(err);return 1;}// 创建一个新窗口window = uiNewWindow("Hello World!", 300, 300, 0);uiWindowOnClosing(window, onClosing, NULL);// 显示窗口uiControlShow(uiControl(window));// 启动主循环uiMain();// 释放内存空间uiUninit();return 0;
}

2. 绘制文本

#include <stdio.h>
#include "ui.h"int onClosing(uiWindow* w, void* data)
{uiQuit();return 1;
}int main(void)
{uiInitOptions o = { 0 };const char* err;uiWindow* window;uiLabel* label;// 初始化uierr = uiInit(&o);if (err != NULL) {fprintf(stderr, u8"初始化错误: %s\n", err);uiFreeInitError(err);return 1;}// 创建一个新窗口window = uiNewWindow("Hello World!", 300, 300, 0);uiWindowOnClosing(window, onClosing, NULL);// 添加标签label = uiNewLabel("Hello, World!");uiWindowSetChild(window, uiControl(label));// 显示窗口uiControlShow(uiControl(window));// 启动主循环uiMain();uiUninit();return 0;
}

三、控件介绍

1. 容器控件

uiWindow

一个代表顶层窗口的控件,可包含其他控件。

uiBox

一个容纳一组控件的盒状容器。

uiTab

一个多页面控制界面容器,一次显示一个页面。

uiGroup

向所包含的子控件添加标签的控件容器。

uiForm

将包含的控件组织为带标签的字段的控件容器。

uiGrid

要在网格中排列的包含控件的控件容器。

2. 数据输入

uiCheckbox

带有用户可选框并带有文本标签的控件。

uiEntry

具有单行文本输入字段的控件。

uiSpinbox

通过文本字段或 +/- 按钮显示和修改整数值的控件。

uiSlider

通过用户可拖动的滑块显示和修改整数值的控件。

uiCombobox

通过下拉菜单从预定义项目列表中选择一项的控件。

uiEditableCombobox

用于从预定义的项目列表中选择一个项目或输入自己的项目的控件。

uiRadioButtons

复选按钮的多选控件,一次只能从中选择一个。

uiDateTimePicker

输入日期和/或时间的控件。

uiMultilineEntry

具有多行文本输入字段的控件。

uiFontButton

单击时打开字体选择器的类似按钮的控件。

uiColorButton

带有颜色指示器的控件,单击时会打开颜色选择器。

uiTable

以表格方式显示数据的控件。

3. 静态控件

uiLabel

显示非交互式文本的控件。

uiProgressBar

通过水平条的填充级别可视化任务进度的控件。

uiSeparator

用于在视觉上水平或垂直分隔控件的控件。

uiMenuItem

与uiMenu结合使用的菜单项。

uiMenu

应用程序级菜单栏。

uiImage

要在屏幕上显示的图像的容器。

4. 按钮控件

uiButton

uiFontButton

uiColorButton

5. 对话框窗口

6. 菜单

7. 表格

四、综合案例

1. 直方图

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "ui.h"uiWindow* mainwin;
uiArea* histogram;
uiAreaHandler handler;
uiSpinbox* datapoints[10];
uiColorButton* colorButton;
int currentPoint = -1;// some metrics
#define xoffLeft 20         /* 直方图的左边缘 */
#define yoffTop 20          /* 直方图的上边缘 */
#define xoffRight 20        /* 直方图的右边缘 */
#define yoffBottom 20       /* 直方图的下边缘 */
#define pointRadius 10      /* 点的大小 */// 命名颜色
#define colorWhite 0xFFFFFF
#define colorBlack 0x000000
#define colorDodgerBlue 0x1E90FF// 设置画刷的颜色
static void setSolidBrush(uiDrawBrush* brush, uint32_t color, double alpha)
{uint8_t component;brush->Type = uiDrawBrushTypeSolid;component = (uint8_t)((color >> 16) & 0xFF);brush->R = ((double)component) / 255;component = (uint8_t)((color >> 8) & 0xFF);brush->G = ((double)component) / 255;component = (uint8_t)(color & 0xFF);brush->B = ((double)component) / 255;brush->A = alpha;
}// 根据给定的宽度和高度,计算出每个数据点在绘图区域中的位置坐标
static void pointLocations(double width, double height, double* xs, double* ys)
{double xincr, yincr;int i, n;xincr = width / 9;       // 10 - 1 to make the last point be at the endyincr = height / 100;for (i = 0; i < 10; i++) {// get the value of the pointn = uiSpinboxValue(datapoints[i]);// because y=0 is the top but n=0 is the bottom, we need to flipn = 100 - n;xs[i] = xincr * i;ys[i] = yincr * n;}
}// 据给定的宽度和高度以及当前界面上的数据点,构建一个绘制折线图的路径
static uiDrawPath* constructGraph(double width, double height, int extend)
{uiDrawPath* path;double xs[10], ys[10];int i;pointLocations(width, height, xs, ys);path = uiDrawNewPath(uiDrawFillModeWinding);uiDrawPathNewFigure(path, xs[0], ys[0]);for (i = 1; i < 10; i++)uiDrawPathLineTo(path, xs[i], ys[i]);if (extend) {uiDrawPathLineTo(path, width, height);uiDrawPathLineTo(path, 0, height);uiDrawPathCloseFigure(path);}uiDrawPathEnd(path);return path;
}// 根据介绍的客户区域计算图形大小
static void graphSize(double clientWidth, double clientHeight, double* graphWidth, double* graphHeight)
{*graphWidth = clientWidth - xoffLeft - xoffRight;*graphHeight = clientHeight - yoffTop - yoffBottom;
}static void handlerDraw(uiAreaHandler* a, uiArea* area, uiAreaDrawParams* p)
{uiDrawPath* path;uiDrawBrush brush;uiDrawStrokeParams sp;uiDrawMatrix m;double graphWidth, graphHeight;double graphR, graphG, graphB, graphA;// fill the area with whitesetSolidBrush(&brush, colorWhite, 1.0);path = uiDrawNewPath(uiDrawFillModeWinding);uiDrawPathAddRectangle(path, 0, 0, p->AreaWidth, p->AreaHeight);uiDrawPathEnd(path);uiDrawFill(p->Context, path, &brush);uiDrawFreePath(path);// figure out dimensionsgraphSize(p->AreaWidth, p->AreaHeight, &graphWidth, &graphHeight);// clear sp to avoid passing garbage to uiDrawStroke()// for example, we don't use dashingmemset(&sp, 0, sizeof(uiDrawStrokeParams));// make a stroke for both the axes and the histogram linesp.Cap = uiDrawLineCapFlat;sp.Join = uiDrawLineJoinMiter;sp.Thickness = 2;sp.MiterLimit = uiDrawDefaultMiterLimit;// draw the axessetSolidBrush(&brush, colorBlack, 1.0);path = uiDrawNewPath(uiDrawFillModeWinding);uiDrawPathNewFigure(path,xoffLeft, yoffTop);uiDrawPathLineTo(path,xoffLeft, yoffTop + graphHeight);uiDrawPathLineTo(path,xoffLeft + graphWidth, yoffTop + graphHeight);uiDrawPathEnd(path);uiDrawStroke(p->Context, path, &brush, &sp);uiDrawFreePath(path);// now transform the coordinate space so (0, 0) is the top-left corner of the graphuiDrawMatrixSetIdentity(&m);uiDrawMatrixTranslate(&m, xoffLeft, yoffTop);uiDrawTransform(p->Context, &m);// now get the color for the graph itself and set up the brushuiColorButtonColor(colorButton, &graphR, &graphG, &graphB, &graphA);brush.Type = uiDrawBrushTypeSolid;brush.R = graphR;brush.G = graphG;brush.B = graphB;// we set brush->A below to different values for the fill and stroke// now create the fill for the graph below the graph linepath = constructGraph(graphWidth, graphHeight, 1);brush.A = graphA / 2;uiDrawFill(p->Context, path, &brush);uiDrawFreePath(path);// now draw the histogram linepath = constructGraph(graphWidth, graphHeight, 0);brush.A = graphA;uiDrawStroke(p->Context, path, &brush, &sp);uiDrawFreePath(path);// now draw the point being hovered overif (currentPoint != -1) {double xs[10], ys[10];pointLocations(graphWidth, graphHeight, xs, ys);path = uiDrawNewPath(uiDrawFillModeWinding);uiDrawPathNewFigureWithArc(path,xs[currentPoint], ys[currentPoint],pointRadius,0, 6.23,      // TODO pi0);uiDrawPathEnd(path);// use the same brush as for the histogram linesuiDrawFill(p->Context, path, &brush);uiDrawFreePath(path);}
}static int inPoint(double x, double y, double xtest, double ytest)
{// TODO switch to using a matrixx -= xoffLeft;y -= yoffTop;return (x >= xtest - pointRadius) &&(x <= xtest + pointRadius) &&(y >= ytest - pointRadius) &&(y <= ytest + pointRadius);
}static void handlerMouseEvent(uiAreaHandler* a, uiArea* area, uiAreaMouseEvent* e)
{double graphWidth, graphHeight;double xs[10], ys[10];int i;graphSize(e->AreaWidth, e->AreaHeight, &graphWidth, &graphHeight);pointLocations(graphWidth, graphHeight, xs, ys);for (i = 0; i < 10; i++)if (inPoint(e->X, e->Y, xs[i], ys[i]))break;if (i == 10)      // not in a pointi = -1;currentPoint = i;// TODO only redraw the relevant areauiAreaQueueRedrawAll(histogram);
}static void handlerMouseCrossed(uiAreaHandler* ah, uiArea* a, int left)
{// do nothing
}static void handlerDragBroken(uiAreaHandler* ah, uiArea* a)
{// do nothing
}static int handlerKeyEvent(uiAreaHandler* ah, uiArea* a, uiAreaKeyEvent* e)
{// reject all keysreturn 0;
}static void onDatapointChanged(uiSpinbox* s, void* data)
{uiAreaQueueRedrawAll(histogram);
}// 回调函数,当颜色按钮改变时调用
static void onColorChanged(uiColorButton* b, void* data)
{uiAreaQueueRedrawAll(histogram);
}// 回调函数,用户关闭窗口时,销毁主窗口,再执行释放内存
static int onClosing(uiWindow* w, void* data)
{uiControlDestroy(uiControl(mainwin));uiQuit(); //关闭整个 UI 程序并释放所有分配的内存return 0;
}static int shouldQuit(void* data)
{uiControlDestroy(uiControl(mainwin));  // 销毁窗口对象return 1;
}int main(void)
{uiInitOptions o;const char* err;uiBox* hbox, * vbox;int i;uiDrawBrush brush;handler.Draw = handlerDraw;handler.MouseEvent = handlerMouseEvent;handler.MouseCrossed = handlerMouseCrossed;handler.DragBroken = handlerDragBroken;handler.KeyEvent = handlerKeyEvent;memset(&o, 0, sizeof(uiInitOptions));err = uiInit(&o);if (err != NULL) {fprintf(stderr, "error initializing ui: %s\n", err);uiFreeInitError(err);return 1;}// 通过回调函数判断程序是否退出uiOnShouldQuit(shouldQuit, NULL);mainwin = uiNewWindow("libui Histogram Example", 640, 480, 1);uiWindowSetMargined(mainwin, 1);uiWindowOnClosing(mainwin, onClosing, NULL);hbox = uiNewHorizontalBox();uiBoxSetPadded(hbox, 1);uiWindowSetChild(mainwin, uiControl(hbox));vbox = uiNewVerticalBox();uiBoxSetPadded(vbox, 1);uiBoxAppend(hbox, uiControl(vbox), 0);// 设置10组数据框,添加到vboxsrand(time(NULL));for (i = 0; i < 10; i++) {datapoints[i] = uiNewSpinbox(0, 100);uiSpinboxSetValue(datapoints[i], rand() % 101);uiSpinboxOnChanged(datapoints[i], onDatapointChanged, NULL); // 设置数据区域变化时发生的操作uiBoxAppend(vbox, uiControl(datapoints[i]), 0);}// 设置颜色选择按钮,添加到vboxcolorButton = uiNewColorButton();setSolidBrush(&brush, colorDodgerBlue, 1.0);uiColorButtonSetColor(colorButton, brush.R, brush.G, brush.B, brush.A);uiColorButtonOnChanged(colorButton, onColorChanged, NULL);  // 设置颜色按钮变化时执行的操作uiBoxAppend(vbox, uiControl(colorButton), 0);// 设置绘图区域,添加到hboxhistogram = uiNewArea(&handler);uiBoxAppend(hbox, uiControl(histogram), 1);// 显示窗口uiControlShow(uiControl(mainwin));// 执行循环uiMain();// 释放内存空间uiUninit();return 0;
}

附录

其他分支:

  • https://github.com/neroist/uing
  • https://github.com/libui-ng/libui-ng

参考文档:https://libui-ng.github.io/libui-ng/annotated.html

libui的简单使用相关推荐

  1. 在docker上安装部署tomcat项目 超简单,拿来主义

    在docker中部署tomcat,非常简单,而且省去了手动安装jdk等步骤,只需要将war包复制在容器tomcat实例中的webapps下面即可.以下将详细讲解流程: 在windows中打好包以后用w ...

  2. Linux下tomcat的安装与卸载以及配置(超简单)

    无敌简单的几步 1.安装 //首先你需要下载好tomcat包 sudo tar -xvzf apache-tomcat-7.0.85.tar.gz(这里是包名) -C 你要放的位置 2.卸载 rm - ...

  3. Docker安装Apache与运行简单的web服务——httpd helloworld

    Docker运行简单的web服务--httpd helloworld目录[阅读时间:约5分钟] 一.Docker简介 二.Docker的安装与配置[CentOS环境] 三.Docker运行简单的web ...

  4. Docker的安装、镜像源更换与简单应用

    Docker的安装.镜像源更换与简单应用[阅读时间:约20分钟] 一.概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 三.Docker的安装 四.Docker的简单应用 1. ...

  5. 基于Golang的简单web服务程序开发——CloudGo

    基于Golang的简单web服务程序开发--CloudGo[阅读时间:约10分钟] 一.概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 (1)基本要求 (2)扩展要求 三.具体 ...

  6. 简单图文配置golang+vscode【win10/centos7+golang helloworld+解决install failed等情况】

    博客目录(阅读时间:10分钟) 一.win10 0.系统环境 1. win10配置golang环境 ①下载相关软件 ②创建gowork工作空间 ③配置环境变量(GOPATH+PATH) ④验证环境配置 ...

  7. 简单介绍互联网领域选择与营销方法

    在我看来,互联网领域的选择是"安家",而营销方法的不同则表现了"定家"的方式多种多样,只有选对了,"家"才得以"安定". ...

  8. JAVA用最简单的方法来构建一个高可用的服务端,提升系统可用性

    一.什么是提升系统的高可用性 JAVA服务端,顾名思义就是23体验网为用户提供服务的.停工时间,就是不能向用户提供服务的时间.高可用,就是系统具有高度可用性,尽量减少停工时间.如何用最简单的方法来搭建 ...

  9. java发送简单邮件_Java程序实现发送简单文本邮件

    /** * Java程序实现发送简单文本邮件 * * @author Administrator * */ public class SendTextMail { // 定义发件人地址 public  ...

最新文章

  1. 安全框架 - Shiro与springMVC整合的注解以及JSP标签
  2. linux python fcntl模块 程序加锁 简介
  3. Java Class文件结构
  4. Python 08 面向对象
  5. vuex modules ajax,VUE项目爬坑---6、vuex的真正存在的意义是什么
  6. oracle表空间状态如何离线,六步了解Oracle表空间状态
  7. upc组队赛5 Election of Evil【搜索】
  8. Vue.js 2.0版
  9. 谷歌浏览器设置信任_Win10谷歌浏览器添加信任网址/站点的方法
  10. c# 中通快递对接_物流快递单号智能识别快递公司API接口 C#
  11. D - Inna and Alarm Clock
  12. Jsoup实现网络爬虫抓取数据
  13. 你所不了解的微服务架构
  14. Unity小游戏-平衡大师(安卓、PC、web)2D益智类游戏 项目展示+完整项目源码
  15. XX市智慧环卫管理系统解决方案V1.0
  16. eclipse的小知识点
  17. Android Studio链接夜神模拟器
  18. 滴水逆向学习总结第一期
  19. (脑肿瘤阅读笔记:四十六)KIU-Net用于医学图像分割和体积分割的过完备卷积网络架构
  20. 解决Chrome浏览器启动页被劫持篡改为360

热门文章

  1. 计算机二级front和rear什么意思,计算机二级公共基础选择题31-40
  2. 四.爬虫--破解新浪微博登录加密
  3. 放弃支持旧机型,Win11需英特尔8代CPU起步
  4. 【正点原子FPGA连载】 第三十章双目OV5640摄像头LCD显示实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南
  5. windows 2003 server 搭建php环境,windows server 2003 php 环境搭建
  6. 盛大格子客或将继开心农场之后又一疯狂游戏
  7. 关于OneNote笔记本名称不同步
  8. 360wifi插入没反应
  9. 4月15日csol服务器维护中,csol2017年2月15日更新内容一览 csol2.15更新公告
  10. 女神特辑 | 弘衍科技张雁:是情怀,更是责任,数字化让教育更公平、更个性、更智慧