FLTK的UI设计工具FLUID使用方法总结
tags: FLTK C++ GUI
写在前面
终于又捡起来FLTK
了, 先来看看怎么通过FLUID
创建一个图形界面并完成回调函数的创建, 参考的是官方教程中关于创建一个CubeView
程序的例子, 教程里面很多都与最新版本的FLTK界面不太一致, 但是通过我的摸索还是找出了方法. 下面来分享一下.
创建类
直接点New
新建各种类型即可, 一些注意事项在官方文档中给出了, 一些类或者组件的名称都用粗体标出来了(如下图), 需要对应, 不然后面回调函数连接不上.
在CubeViewUI
类中主要实现了构造函数以及一个show
方法, 用于显示窗体.
最后的结果如下, 这里其实主要是要看清楚是水平组件还是垂直组件, 这个很重要, 其次就是主窗体的大小, 配比要合适.
回调函数
其实就是两行, 主要用于五个主要组件中, 分为两组:
slider
Zoom:
cube->size=((Fl_Value_Slider *)o)->value(); cube->redraw();
ypan:
cube->pany(((Fl_Value_Slider *)o)->value()); cube->redraw();
xpan:
cube->panx(((Fl_Value_Slider *)o)->value()); cube->redraw();
roller
vrot:
cube->v_angle(((Fl_Roller *)o)->value()); cube->redraw();
hrot
cube->h_angle(((Fl_Roller *)o)->value()); cube->redraw();
CubeView类(显示图形)
最后是主要的显示窗体的类, 这需要在extra Code
部分添加头文件声明:
#include "CubeView.h"
这部分代码如下:
// CubeView.h
#include <FL/gl.h>
#include <FL/Fl_Gl_Window.H>
#include <math.h>class CubeView : public Fl_Gl_Window {public:CubeView(int x, int y, int w, int h, const char *l = 0);// this value determines the scaling factor used to draw the cube.double size;/* Set the rotation about the vertical (y ) axis.** This function is called by the horizontal roller in CubeViewUI* and the initialize button in CubeViewUI.*/void v_angle(float angle) { vAng = angle; };// Return the rotation about the vertical (y ) axis.float v_angle() { return vAng; };/* Set the rotation about the horizontal (x ) axis.** This function is called by the vertical roller in CubeViewUIand the* initialize button in CubeViewUI.*/void h_angle(float angle) { hAng = angle; };// the rotation about the horizontal (x ) axis.float h_angle() { return hAng; };/* Sets the x shift of the cube view camera.** This function is called by the slider in CubeViewUI and the* initialize button in CubeViewUI.*/void panx(float x) { xshift = x; };/* Sets the y shift of the cube view camera.** This function is called by the slider in CubeViewUI and the* initialize button in CubeViewUI.*/void pany(float y) { yshift = y; };/* The widget class draw() override.* The draw() function initialize Gl for another round of* drawing then calls specialized functions for drawing each* of the entities displayed in the cube view.*/void draw();private:/* Draw the cube boundaries* Draw the faces of the cube using the boxv[] vertices, using* GL_LINE_LOOP for the faces. The color is #defined by* CUBECOLOR.*/void drawCube();float vAng, hAng;float xshift, yshift;float boxv0[3];float boxv1[3];float boxv2[3];float boxv3[3];float boxv4[3];float boxv5[3];float boxv6[3];float boxv7[3];
};
// CubeView.cxx
#include "CubeView.h"CubeView::CubeView(int x, int y, int w, int h, const char *l): Fl_Gl_Window(x, y, w, h, l) {vAng = 0.0;hAng = 0.0;size = 10.0;/* The cube definition. These are the vertices of a unit cube* centered on the origin.*/boxv0[0] = -0.5;boxv0[1] = -0.5;boxv0[2] = -0.5;boxv1[0] = 0.5;boxv1[1] = -0.5;boxv1[2] = -0.5;boxv2[0] = 0.5;boxv2[1] = 0.5;boxv2[2] = -0.5;boxv3[0] = -0.5;boxv3[1] = 0.5;boxv3[2] = -0.5;boxv4[0] = -0.5;boxv4[1] = -0.5;boxv4[2] = 0.5;boxv5[0] = 0.5;boxv5[1] = -0.5;boxv5[2] = 0.5;boxv6[0] = 0.5;boxv6[1] = 0.5;boxv6[2] = 0.5;boxv7[0] = -0.5;boxv7[1] = 0.5;boxv7[2] = 0.5;
};
// The color used for the edges of the bounding cube.
#define CUBECOLOR 255, 255, 255, 255
void CubeView::drawCube() {/* Draw a colored cube */
#define ALPHA 0.5glShadeModel(GL_FLAT);glBegin(GL_QUADS);glColor4f(0.0, 0.0, 1.0, ALPHA);glVertex3fv(boxv0);glVertex3fv(boxv1);glVertex3fv(boxv2);glVertex3fv(boxv3);glColor4f(1.0, 1.0, 0.0, ALPHA);glVertex3fv(boxv0);glVertex3fv(boxv4);glVertex3fv(boxv5);glVertex3fv(boxv1);glColor4f(0.0, 1.0, 1.0, ALPHA);glVertex3fv(boxv2);glVertex3fv(boxv6);glVertex3fv(boxv7);glVertex3fv(boxv3);glColor4f(1.0, 0.0, 0.0, ALPHA);glVertex3fv(boxv4);glVertex3fv(boxv5);glVertex3fv(boxv6);glVertex3fv(boxv7);glColor4f(1.0, 0.0, 1.0, ALPHA);glVertex3fv(boxv0);glVertex3fv(boxv3);glVertex3fv(boxv7);glVertex3fv(boxv4);glColor4f(0.0, 1.0, 0.0, ALPHA);glVertex3fv(boxv1);glVertex3fv(boxv5);glVertex3fv(boxv6);glVertex3fv(boxv2);glEnd();glColor3f(1.0, 1.0, 1.0);glBegin(GL_LINES);glVertex3fv(boxv0);glVertex3fv(boxv1);glVertex3fv(boxv1);glVertex3fv(boxv2);glVertex3fv(boxv2);glVertex3fv(boxv3);glVertex3fv(boxv3);glVertex3fv(boxv0);glVertex3fv(boxv4);glVertex3fv(boxv5);glVertex3fv(boxv5);glVertex3fv(boxv6);glVertex3fv(boxv6);glVertex3fv(boxv7);glVertex3fv(boxv7);glVertex3fv(boxv4);glVertex3fv(boxv0);glVertex3fv(boxv4);glVertex3fv(boxv1);glVertex3fv(boxv5);glVertex3fv(boxv2);glVertex3fv(boxv6);glVertex3fv(boxv3);glVertex3fv(boxv7);glEnd();
}; // drawCube
void CubeView::draw() {if (!valid()) {glLoadIdentity();glViewport(0, 0, w(), h());glOrtho(-10, 10, -10, 10, -20000, 10000);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);}glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix();glTranslatef(xshift, yshift, 0);glRotatef(hAng, 0, 1, 0);glRotatef(vAng, 1, 0, 0);glScalef(float(size), float(size), float(size));drawCube();glPopMatrix();
};
主文件(main)
#include "CubeViewUI.h"static int my_handler(int event) {if (event == FL_SHORTCUT) return 1;// eat all shortcut keysreturn 0;
}int main(int argc, char **argv) {CubeViewUI ui;Fl::add_handler(my_handler);ui.show(argc, argv);return Fl::run();
}
这里我加上了句柄函数, 这个函数用来使esc
键失效, 否则在窗体中按下esc
会直接关闭窗口.
编译链接
重点要说一下编译链接这块.
官方Makefile
先给出官方文档1中的Makefile
, 其实用Cmake要方便一些, 但是Makefile也要会写才行.
CXX = $(shell fltk-config --cxx)
DEBUG = -g
CXXFLAGS = $(shell fltk-config --use-gl --use-images --cxxflags ) -I.
LDFLAGS = $(shell fltk-config --use-gl --use-images --ldflags )
LDSTATIC = $(shell fltk-config --use-gl --use-images --ldstaticflags )
LINK = $(CXX)TARGET = cube
OBJS = CubeMain.o CubeView.o CubeViewUI.o
SRCS = CubeView.cxx CubeViewUI.cxx.SUFFIXES: .o .cxx
%.o: %.cxx$(CXX) $(CXXFLAGS) $(DEBUG) -c $<all: $(TARGET)$(LINK) -o $(TARGET) $(OBJS) $(LDSTATIC)$(TARGET): $(OBJS)
CubeMain.o: CubeMain.cxx CubeViewUI.h
CubeView.o: CubeView.cxx CubeView.h CubeViewUI.h
CubeViewUI.o: CubeViewUI.cxx CubeView.hclean: $(TARGET) $(OBJS)rm -f *.o 2> /dev/nullrm -f $(TARGET) 2> /dev/null
CmakeLists
再给出Cmake文件(之前其实就介绍过)
cmake_minimum_required(VERSION 3.24)
project(fltk_proj)set(CMAKE_CXX_STANDARD 17)FIND_PACKAGE(FLTK REQUIRED)# 相当于gcc `-I`参数
include_directories("/opt/homebrew/include")
# 相当于gcc `-L`参数
link_directories("/opt/homebrew/lib")# 相当于gcc `-l`参数
link_libraries("fltk")
link_libraries("Xext")
link_libraries("X11")
link_libraries("m")# 添加可执行程序
add_executable(test1 CubeMain.cxx CubeViewUI.cxx CubeView.cxx)# MESSAGE(${FLTK_LIBRARIES})
TARGET_LINK_LIBRARIES(test1 ${FLTK_LIBRARIES})
最后如果想生成MacOS下的test.app
目录, 那么只需要在命令行中输入:
fltk-config --post <前面生成的可执行文件名>
就会在同级目录下生成xxx.app
了, 还是相当方便的.
部署.app目录的Shell脚本
后来我发现这个步骤可以通过Shell脚本来完成(fltk-config
本质是就是一个可执行的脚本文件)
具体参考了fltk-config
源码, 以及2. 脚本如下:
#!/bin/shcompile=$1
case "$compile" in
*.cxx)prog=$(basename "$compile" .cxx);;
*.cpp)prog=$(basename "$compile" .cpp);;
*.cc)prog=$(basename "$compile" .cc);;
*.C)prog=$(basename "$compile" .C);;
*)echo "ERROR: Unknown/bad C++ soure file extension on \"$compile\"!"exit 1;;
esacpost=$prog
echo Creating "$post.app" bundle for desktop...id=$(echo $post | tr ' ' '_')
echo $id# Make the bundle directory and move the executable there
rm -rf "$post.app/Contents/MacOS"
mkdir -p "$post.app/Contents/MacOS"
mv "$post" "$post.app/Contents/MacOS"# Make a shell script that runs the bundled executable
echo "#!/bin/sh" >"$post"
echo 'dir="`dirname \"$0\"`"' >>"$post"
echo 'exec "$dir/'"$post.app/Contents/MacOS/$post"'" "$@"' >>"$post"
chmod +x "$post"# Make the simplest Info.plist needed for an application
cat >"$post.app/Contents/Info.plist" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<plist version="0.9"><dict><key>CFBundleInfoDictionaryVersion</key><string>6.0</string><key>CFBundleExecutable</key><string>$post</string><key>CFBundleIdentifier</key><string>org.fltk.$id</string><key>CFBundleName</key><string>$post</string><key>CFBundlePackageType</key><string>APPL</string><key>NSHighResolutionCapable</key><true/></dict>
</plist>
EOFecho "done!"
用法为:(保存为gen_app.sh
)
./gen_app.sh test.cpp
终极版Makefile(集合编译链接与部署)
但是不够简洁, 于是想着把Shell集成在Makefile里面, 于是就有: (部分较官方文档有改动)
CXX = $(shell fltk-config --cxx)
DEBUG = -g
CXXFLAGS = $(shell fltk-config --use-gl --use-images --cxxflags ) -I.
LDFLAGS = $(shell fltk-config --use-gl --use-images --ldflags )
LDSTATIC = $(shell fltk-config --use-gl --use-images --ldstaticflags )
LINK = $(CXX)TARGET = cube
OBJS = CubeMain.o CubeView.o CubeViewUI.o
SRCS = CubeMain.cxx CubeView.cxx CubeViewUI.cxxAPP_NAME= $(TARGET)define info_plist
<?xml version="1.0" encoding="UTF-8"?> \
<plist version="0.9"> \<dict> \<key>CFBundleInfoDictionaryVersion</key> \<string>6.0</string> \<key>CFBundleExecutable</key> \<string>APP_NAME</string> \<key>CFBundleIdentifier</key> \<string>org.fltk.APP_NAME</string> \<key>CFBundleName</key> \<string>APP_NAME</string> \<key>CFBundlePackageType</key> \<string>APPL</string> \<key>NSHighResolutionCapable</key> \<true/> \</dict> \
</plist>
endef.SUFFIXES: .o .cxx
compile: $(SRCS)@echo "compiling..."@$(CXX) $(CXXFLAGS) $(DEBUG) -c $^all: compile link runbundle_app: clean_app package_apprun: compile link $(TARGET)./$(TARGET)package_app: compile link@echo "bundling..."@mkdir -p $(APP_NAME).app/Contents/{MacOS,Resources}@echo '$(info_plist)' > "$(APP_NAME).app/Contents/Info.plist"@sed -e "s/APP_NAME/$(APP_NAME)/g" -i "" "$(APP_NAME).app/Contents/Info.plist"@cp $(TARGET) "$(APP_NAME).app/Contents/MacOS/$(APP_NAME)"
# cp -R "$(FRAMEWORK_PATH)/SDL2.framework" "$(APP_NAME).app/Contents/Resources/"link: $(OBJS)@echo "linking..."@$(LINK) -o $(TARGET) $(OBJS) $(LDSTATIC)clean: clean_app@echo "Delete *.o $(TARGET)..."@rm -f *.o 2> /dev/null@rm -f $(TARGET) 2> /dev/nullclean_app:@echo "Delete $(APP_NAME).app..."@rm -rf $(APP_NAME).app
用这套Makefile, 配合clion, 简直无敌!
效果
几点注意
- Makefile缩进需要用制表符, 如果要用空格需要在开头加上
.RECIPEPREFIX := $(.RECIPEPREFIX)<space>
, 其中<space>
是一个空格. - FLUID界面也会被
esc
关闭, 注意保存, 可以通过快捷键⌘+S保存, 然后⌘+⇧+C生成头文件和源码. - 控件通过拖放完成布局, 需要调整部分控件的范围与
step
, 例如roller和slider. - 布局应该和回调函数分离, 便于维护, 后续会写相关文章.
ref
FLTK 1.3.8: FLTK Basics; ↩︎
带有生成文件的应用程序捆绑包 - Joseph Long (joseph-long.com); ↩︎
FLTK的UI设计工具FLUID使用方法总结相关推荐
- ui设计师常用的设计工具_2020年应该使用哪个UI设计工具?
ui设计师常用的设计工具 重点 (Top highlight) It's 2020, the market today is saturated with UI design tools. Ever ...
- figma、sketch、xd哪个UI设计工具比较好入门
UI设计师们正在做UI你担心选择设计工具软件吗?尤其是新手UI设计师,设计工具现在真的是眼花缭乱,看不见了. 下面我们重点看下三款UI设计师常用的UI设计工具. Sketch Sketch它是一款适合 ...
- UI设计工具比较:Sketch、Adobe XD、墨刀、Mockplus、Axure RP
UI设计工具,分为2个派系. 其中,最大.最主流的派系,是Sketch.Adobe XD.墨刀这个派系. 这个派系的软件,操作方式.思路都非常接近,连常用快捷键都一样,会一个就等于都会了. 在一个无限 ...
- 轻量而敏捷的工业组态软件UI设计工具-ConPipe Studio 2022
WPF实现组态软件-逼真的管道和速度可变流体(五) 轻量而敏捷的工业组态软件UI设计工具-机械组态篇 ConPipe Studio 2022和ConPipe控件下载地址(Trial版):ConPipe ...
- 8个强大的UI设计工具-设计师利器
设计良好的用户界面始终是一个具有挑战性的过程,因为总是会影响最终用户的Web服务器或应用.要执行此,这些资源是非常有用的 ,设计人员可以用它来 实现自己的目标.今天分享8个设计师利器-UI设计工具 ...
- 仿真及设计工具下载安装方法详细说明
标题仿真及设计工具下载安装方法详细说明 软件的下载: 物流仿真的软件下载请进入:链接: https://pan.baidu.com/s/12iP3TTkXw-D5DAMu3mQbwQ 提取码: 888 ...
- LVGL 官方UI设计工具 EdgeLine代码移植
LVGL 官方UI设计工具EdgeLine代码移植 一.Tools LVGL v7.8 Edgeline bata 0.3b 二.Porting 准备移植好的LVGL8-MDK工程.(必须是v7版本, ...
- 非常有用的免费UI设计工具和资源
原文地址为: 非常有用的免费UI设计工具和资源 这篇文章要与大家分享的都是一些很棒的免费UI设计工具和资源,有Web开发方面的,也有移动开发方面的,非常丰富,相信你能从中发现有用的资源.记得推荐一下哦 ...
- UML建模、数据库设计和UI设计工具
1.Rational Rose 很多人说Rose不好用,但是我觉得还是挺好用的,用了七八年了,主要是用熟了,而且也没有什么大毛病 2.XDE 2003 .Net里面,你可以用XDE,但是只有for v ...
最新文章
- phpmyadmi 上传大文件
- php5.4.16执行shell脚本
- VC++动态创建和删除菜单(转)
- 【Java】求解N皇后问题
- jenkins中使用rsync, scp命令
- Android程序员视角的Apple发布会
- Lesson 1- exchange 2010 installing
- java 社招 简历_招聘java简历模板
- 408计算机考试科目英语数学,关于计算机考研408的那些事儿
- 八字 十二长生 详解
- vue中如何设置鼠标经过切换样式
- win7c盘空间越来越小_C盘空间越来越小怎么办,5个步骤无损扩容1招就搞定
- 服务器出现漏洞如何处理
- css+html工商银行小项目
- Android8.1 MTK平台 WLAN热点定制
- Ubuntu 开机自动开启数字键小键盘
- 渭师院的计算机专业学什么课程,【三名+建设工作】渭南初级中学教师郭晓辉走进渭师院给大学生上课...
- NKOJ 2703 (WC 2014)紫荆花之恋 (点分治+平衡树+替罪羊)
- Coin Change
- linux搭建天地伟业easy7,easy7视频监控系统客户端|天地伟业easy7监控客户端简洁版(Easy7 Smart Client Express)下载 V7.12 官方版 - 比克尔下载...