add_custom_target ALL:
ALL
Indicate that this target should be added to the default build target so that it will be run every time (the command cannot be called ALL
).
cmake --system-information 了解当前平台、默认编译器和语言的默认组合是什么,还有很多其他信息
cmake --help-module <name-of-module>会打印模块的手册页(帮助页面),很有用哦
cmake --build . 编译可执行文件
1. glib是Gtk+的基础,可以在多个平台上使用,相当于c++标准模板库,提供了容器类型,字符串(自动增长)。基本类型等等。GTree是基本的平衡二叉树。
参考https://baike.baidu.com/item/glib/1765577?fr=aladdin
2. gtk官网https://www.gtk.org/
3. 通过语言绑定特性,可以选择自己喜欢的语言开发。
4. GTK/GTK+ 和 GTK2是同一套API的不同版本,GTK是老版本, GTK2是以前的版本, GTK+ 3/GTK3是当前版本.参看讨论https://stackoverflow.com/questions/5830731/what-is-the-relation-between-gtk-gtk-and-gtk2#:~:text=GTK%20is%20an%20old%2C%20deprecated%20version%2C%20GTK2%20is,for%20GTK%2B%20are%20part%20of%20the%20project%20GTKmm.
5. gdk_init()初始化gdk并连接到窗口系统,gtk+在gtk_init()函数中初始化了gdk,所以在gtk+应用中不需要调用gdk_init()函数。
6. gtk+和visual studio配合,需要按照vcpkg,
cd c:\dev\
git clone https://github.com/microsoft/vcpkg
cd vcpkg
bootstrap-vcpkg.bat
vcpkg integrate install
cmake项目应该使用: -DCMAKE_TOOLCHAIN_FILE=C:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake
参考:https://gamefromscratch.com/vcpkg-cpp-easy-mode-step-by-step-tutorial/
7. bgfx, glfw, opengl, cairo
8. gvsbuild编译过程中很多错误,需要安装vs2017尽可能多的模块,否则大概率报错,我的安装大小为21G左右
已经执行了vcpkg integrate install的需要remove
vcpkg integrate remove
中间碰到639代码页错误的需要保存为带签名的unicode文件
需要把控制面板里面那个非unicode程序的语言由中文改为English
9. vcpkg的方法,把源码下载到本地例如:c:\src
然后像上面第8步一样,安装vs2017尽可能多的模块,再把语言设置改一下
vcpkg install gtk
vcpkg integrate intall
就行了
ok!
10. 第一个用vs开发出来的helloworld右上侧三个按钮缺失,解决方案就是运行msys2
位于vcpkg/downloads/tools/msys2目录下:
pacman -S mingw32/mingw-w64-i686-adwaita-icon-theme 或者 mingw64/mingw-w64-x86_64-adwaita-icon-theme
安装完成后,复制icons
从\msys64\mingw64\share\icons
复制到 <VS2017Project>\x64\Release\share\icons目录
icons下面由2个目录 hicolor
和 Adwaita,再次运行就可以了。
参考:
https://github.com/Microsoft/vcpkg/issues/4417
https://stackoverflow.com/questions/59314408/theme-and-icons-problem-with-gtk3-installed-with-vcpkg
https://www.reddit.com/r/GTK/comments/dymepb/how_to_install_gtk_themes_for_windows/ (没多大用)
进一步阅读:
https://www.linux.org/threads/installing-obtaining-and-making-gtk-themes.11811/ (没来得及看)
11. 由一个网页里面有一些字体包,不过还不知道怎么用:
https://icon-theme.freedesktop.org/releases/
12. 有用的库xtensor!!
13. 强制redraw, gtk_widget_queue_draw()
https://stackoverflow.com/questions/9561999/redraw-gtkwidget
https://stackoverflow.com/questions/3118182/redrawing-a-widget-in-gtk?rq=1
14. 多线程更新一个按钮的方法,一个线程把数据丢到一个全局的数据结构里面,然后UI线程从那个结构里面取出东西绘制按钮就行。
https://stackoverflow.com/questions/14282748/gtk-win32-threads
官方介绍多线程:https://developer.gimp.org/api/2.0/gdk/gdk-Threads.html
15. 介绍gtk绘制的文章,很棒,特别是问题下面的comment,
16. 过时的多线程调用:
gdk_threads_enter/gdk_threads_leave
has been deprecated since version 3.6 and should not be used in newly-written code.
All GDK and GTK+ calls should be made from the main thread
https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk-threads-enter
17. void gtk_widget_draw (GtkWidget *widget
, cairo_t *cr
); draw widget to cr.
18. gtk_widget_new 创建一个widget
19. gtk_drawing_area_new , Creates a new drawing area. 返回一个GtkDrawingArea
20. "draw"事件的回调函数第二个参数是一个cairo_t的绘制上下文, perfect!
21. GtkWindow是顶级窗口
22. 在“draw”信号里面总会获取到cairo的上下文context,就可以绘画了,另外建议总是使用双缓冲:
gtk_widget_set_double_buffered()
https://developer.gnome.org/gtk3/stable/gtk-question-index.html
23. 在主线程中更新UI要用
gdk_threads_add_idle_full
https://www.yhi.moe/en/2019/01/23/async-gui-update-in-gtk.html
24. There are multiple ways to drive the clock, at the lowest level you can request a particular phase with gdk_frame_clock_request_phase() which will schedule a clock beat as needed so that it eventually reaches the requested phase.但是该函数不会自动触发重绘(只是update),如果想重绘,由不想改变widget的属性(改变属性会触发重绘),就需要自己调用gtk_widget_queue_draw_area()
函数。https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-add-tick-callback
但是大部分情况下,如果做动画,可以用gtk_widget_add_tick_callback() 调用update,就是说,在gtk_widget_add_tick_callback() 注册的回调函数里面绘制动画。
注意回调函数的格式,参考GtkTickCallback, 返回值是gboolean型,有三个参数,但是为什么一个参数也行呢?
https://developer.gnome.org/gtk3/stable/GtkWidget.html#gtk-widget-add-tick-callback
If some state changes so you need to redraw some area of your widget you use the normal gtk_widget_queue_draw() set of functions. These will request a Paint phase and mark the region as needing redraw.
25. gdk利用双缓冲避免闪烁Double buffering
Two basic functions in GDK form the core of the double-buffering mechanism: gdk_window_begin_paint_region()
and gdk_window_end_paint()
.
https://developer.gnome.org/gtk3/stable/chap-drawing-model.html
26. 如果你想在某些widget上自己画,而不是让widget自己画,需要调用gtk_widget_set_app_paintable()告诉gtk不要覆盖你画的。
27. gtk中用线程的方法,
g_thread_new("thread",threadcompute,data);
https://stackoverflow.com/questions/30607429/gtk3-and-multithreading-replacing-deprecated-functions
上面这个帖子里面讲到了如何用gdk_threads_add_idle替换老的gdk_threads_enter/leave函数。
28. 建一个新的GObject类型
实现一个GObject的子类型,或者一个gtk+ widget的子类型。
类名叫做ViewerFile, ViewerEditable接口
先写头文件,包括类型,函数和宏
type instance: ViewerFile; 类: ViewerFileClass, 类和实例是不一样的。
#define VIEWER_TYPE_FILE viewer_file_get_type ()
这个宏定义了好几个函数,VIEWER_FILE(), VIEWER_FILE_CLASS() 主要用来cast,类型转换;
VIEWER_IS_FILE(), VIEWER_IS_FILE_CLASS()测试对象和类的正确类型;
VIEWER_FILE_GET_CLASS()从实例获取class结构。
G_DECLARE_FINAL_TYPE (ViewerFile, viewer_file, VIEWER, FILE, GObject)
声明了两个结构,ViewerFile和ViewerFileClass, 其中ViewerFile必须在.c文件中定义,ViewerFileClass已经在这个宏里面定义了。
初始化,构造函数,和c++同样的概念是instance_init,但是不能带参数,如果想带参数,请使用construction properties. 即,构造属性。这是构造属性是个什么玩意?
两个构造函数,一个是类的,一个是实例的:
static void viewer_file_class_init(....
static void viewer_file_init(....
应该在class_init()函数中安装特殊的构造属性。
属性IDs(property IDs)必须从1开始。
析构函数分为两个部分:dispose和finalize.
加载图片资源:https://riptutorial.com/gtk3/example/19806/-cplusplus--using-gtk--builder-in-gtkmm
api reference:
1. gtk_window_new
2. gtk_drawing_area
3. gtk_container_add 创建一个gtk窗口,并把cairo 绘制区域添加进那个窗口,注意,该窗口是作为一个容器存在的,必须有一个容器,否则什么也画不出来。
4. cairo_clip: 先定义一个path,然后调用cairo_clip, 表示随后的绘制只有落在这个path内才会看得见,其他地方都看不见,
之后你可以画一个其他图形,不过在画其他图形之前,需要先调用一下cairo_new_path, 这个函数的意思是清除当前的path,调用该函数之后,既没有path,也没有当前的点。
5. cairo_fill: 填充,调用该函数之后,当前path会被清除。
6. cairo_fill_preserve: 填充,调用该函数之后,当前path会被保留。
利用cmakelist.txt文件生成codeblocks工程文件
$ cd build/
$ cmake .. -G"CodeBlocks - Unix Makefiles"
cmake -G"Visual Studio 15 2017" ..
msys2 shell安装mingw的工具链:
pacman -S mingw-w64-i686-toolchain
pacman -S mingw-w64-i686-boost