Mint_21.3 drawing-area和goocanvas的FB笔记(一)

news2025/2/23 22:30:33

一、关于freebasic和goocanvas

Linux下的FreeBasic是C的一种实现,有指针、类、线程,正则表达式,可内嵌asm和其它语言c等,c的h库几乎都能改写后使用(不能直接用,它的.bi可从h近乎自动转换),老的Quick Basic语句也能使用,屏幕方式增加了 screenres x, y 按屏幕尺寸像素定义大小, 比如 screenres 1920, 1080等, 其它语言写成的.so动态库可以类似.h一样写.bi, 然后即可调用,最后编译成本地二制执行文件,调用sqlite, mysql, postgreSQL也行。它free, 功能比较全,稳定性比较好。c能用的界面库它都能用,比较典型的是gtk库,基于cairo的goocanvas也比较有趣。下面的图一是freeBasic操作goocanvas实现的items分组、变换、和模拟运动。

(图一、goocanvas表格图)

下图的上部分是cairo渲染的png图,下部分是goocanvas画线、矩形和文字显示。

(图二、cairo png和goo canvas画图)

下图的上部分是cairo渲染的pixbuf像素数据,下部分是goocanvas画线、矩形和文字显示。

(图三、pixbuf作为cairo的surface渲染)

下图的上部分是cairo渲染的语句绘图,下部分是goocanvas画线、矩形和文字显示。

二、界面设计笔记

界面垂直分成四个部分,上部cairo绘图区、label显示区、goocanvas绘图区、操作区。设计时可用glade作界面设计, box1留一个空位并置入一个gtxbox, ID为canvasbox,在编程时将goocanvas作为一个gtkwidget放入其中,大小也是程序中直接写,glade只需留出带gtkbox的空位即可。设计好后存成文件 glade_newui.glade, 程序中gtk_builder会取出widget属性和信号,程序中也可改写。

将widget作为GObject,定义其指针; 建gtkbuilder; 将glade中的widget与定义的指针对应起来,然后定义一个goocanvas并将写放入到预留的canbox中,最后将界面最大化。

DIM AS STRING GUISTR
DIM SHARED AS GtkBuilder PTR XML
DIM SHARED AS GObject PTR window1
DIM SHARED AS GObject PTR box1
DIM SHARED AS GObject PTR canbox
DIM SHARED AS GObject PTR button1
DIM SHARED AS GObject PTR button2
DIM SHARED AS GObject PTR button3
DIM SHARED AS GObject PTR button4
DIM SHARED AS GObject PTR label1
DIM SHARED AS GObject PTR drawarea1
DIM SHARED AS Gerror PTR errptr
Dim shared as GtkWidget PTR canvas
Dim shared as GooCanvasItem PTR root

XML = gtk_builder_new()
GUISTR="glade_newui.glade"

window1 = gtk_builder_get_object(XML, @"window")
box1 = gtk_builder_get_object(XML, @"box1")
canbox = gtk_builder_get_object(XML, @"canvasbox")
drawarea1 = gtk_builder_get_object(XML, @"drawarea1")
button1 = gtk_builder_get_object(XML, @"button1")
button2 = gtk_builder_get_object(XML, @"button2")
button3 = gtk_builder_get_object(XML, @"button3")
button4 = gtk_builder_get_object(XML, @"button4")
label1 = gtk_builder_get_object(XML, @"label1")

canvas = goo_canvas_new ()
root = goo_canvas_get_root_item (GOO_CANVAS (canvas))

gtk_widget_set_size_request (canvas, 600, 250)
gtk_widget_show (canvas)
gtk_container_add (GTK_CONTAINER (canbox), canvas)

gtk_window_maximize(GTK_WINDOW(window1))

三、cairo绘图笔记

glade设计时上部分是 drawingarea1 ,它有个 draw 信号(gtk3),后面写个回调函数的名称。

下面是回调函数,draw信号带来widget指针,cairo-context, 和用户数据指针(如果在glade设计时指定的话),接下来是取得drawingarea1的宽和高(如果界面是sizeable可变的,需要在使用时先取尺寸),然后画个白色的矩形,接着是判断自定义DrawfunctionFlag值,并根据值调用相应的绘图function函数。

FUNCTION on_drawarea1_draw CDECL ALIAS "on_drawarea1_draw" ( _
  BYVAL widget AS GtkWidget PTR, _
  BYVAL cr AS cairo_t PTR, _
  BYVAL user_data AS gpointer) AS gboolean EXPORT

  'get drawingarea width and height
  VAR w = gtk_widget_get_allocated_width(widget)
  VAR h = gtk_widget_get_allocated_height(widget)
  
  'clear drawingarea surface
  DIM AS GdkRGBA col
  col.red = 1: col.green = 1: col.blue = 1: col.alpha = 1
  gdk_cairo_set_source_rgba(cr, @col)  
  cairo_rectangle(cr, 0, 0, w, h)
  cairo_fill(cr)
  cairo_stroke(cr)

  'do as per DrawfuctionFlag value
  If DrawfunctionFlag = 0 then
		on_drawarea1_draw1(widget, cr, user_data)
  elseif DrawfunctionFlag = 1 then
		on_drawarea1_draw2(widget, cr, user_data)
  elseif DrawfunctionFlag = 2 then
		on_drawarea1_draw3(widget, cr, user_data)
  End if
  
  'return a value as per function definition requirement			
  RETURN DrawfunctionFlag
 
END FUNCTION

功能一:用语句直接画个大圆,stroke 到界面上去。

FUNCTION on_drawarea1_draw1 CDECL ALIAS "on_drawarea1_draw1" ( _
  BYVAL widget AS GtkWidget PTR, _
  BYVAL cr AS cairo_t PTR, _
  BYVAL user_data AS gpointer) AS gboolean EXPORT

  VAR w = gtk_widget_get_allocated_width(widget)
  VAR h = gtk_widget_get_allocated_height(widget)

  DIM AS GdkRGBA col

  col.red = 1: col.green = 1: col.blue = 1: col.alpha = 1
  gdk_cairo_set_source_rgba(cr, @col)  
  cairo_rectangle(cr, 0, 0, w, h)
  cairo_fill(cr)
  
  col.red = 1: col.green = 0: col.blue = 0: col.alpha = 1
  gdk_cairo_set_source_rgba(cr, @col)  
  cairo_arc(cr, w/2, h/2, MIN(w/2, h/2), 0, 2 * G_PI)
  
  gdk_cairo_set_source_rgba(cr, @col)  		'Equal to ---> cairo_set_source_rgba (cr, 1 , 0 , 0 , 1)
  cairo_fill(cr)
  
  cairo_stroke(cr)
  RETURN FALSE

END FUNCTION

功能二:用pixbuf数据创建一个surface, 把创建的surface给 draw 信号的cr进行渲染,pixbuf 像素数据就用像素显示到界面上了。

Function on_drawarea1_draw2 cdecl( byval widget as GtkWidget ptr, _
								BYVAL cr AS cairo_t PTR, _
								byval userdata as gpointer) as gboolean 

	Dim surf as cairo_surface_t PTR
	surf = cairo_image_surface_create_for_data (@rgbbuf(0), CAIRO_FORMAT_ARGB32, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_WIDTH*4)
	cairo_set_source_surface(cr, surf, 50, 100)
	
	cairo_paint (cr)
	cairo_surface_destroy(surf)
	
	return TRUE
End function

pixbuf像素数据是个byte数组,一个彩色的像素点如果用rgb表示的话,需要r、g、b三个数据,每个数据一个byte,即8bit,三个数据是24位。数据表示为 Dim shared rgbbuf(IMAGE_WIDTH * IMAGE_HEIGHT * 3) as byte,是全部像素的字节数。

rgb格式加上alpha是rgba格式,因为多了个alpha, 所以Dim shared rgbbuf(IMAGE_WIDTH * IMAGE_HEIGHT * 4) as byte, 为全部像素的字节数。

函数cairo_image_surface_create_for_data的最后一个参数是一行像素的字节数,这样它就知道了断行显示,否则数据连在一起就分不开了。程序定义的是个数组,然后循环赋值。

#define IMAGE_WIDTH  256 
#define IMAGE_HEIGHT 256 

		Dim shared rgbbuf(IMAGE_WIDTH * IMAGE_HEIGHT * 4) as byte
		''create a 32-bit RGB image by adding alpha
		for y = 0 to IMAGE_HEIGHT-1 
			for x = 0 to IMAGE_WIDTH-1 
				rgbbuf(i+0) = y - (y and 31)					'' B
				rgbbuf(i+1) = (x \ 32) * 4 + y - (y and 31) 	'' G				
				rgbbuf(i+2) = x - (x and 31)					'' R
				rgbbuf(i+3) = &HFF								'' A
				
				i += 4
			next 
		next 	

上面的数据画出来的图是下面的格子图

功能三:调用png图片文件作为surface渲染

surf = cairo_image_surface_create_from_png("fblogo.png")

其它不用改动。

Function on_drawarea1_draw3 cdecl( byval widget as GtkWidget ptr, _
								BYVAL cr AS cairo_t PTR, _
								byval userdata as gpointer) as gboolean 
	
	Dim surf as cairo_surface_t PTR
	surf = cairo_image_surface_create_from_png("fblogo.png")
	cairo_set_source_surface(cr, surf, 200, 100)
	cairo_paint (cr)
	cairo_surface_destroy(surf)
	return TRUE
End function

这三个功能通过DrawFunctionFlag的值来选择,公共变量DrawFunctionFlag的值是由操作区的button press动作赋值的。代码写在了函数里,先是改变它的值,然后取得button click信号带过来的user_data这个widget的尺寸,在glade设计时带过来的drawingarea1,所以这里的user_data就是drawingarea1, 下面的一句是驱动drawingarea的draw信号动作的关键一句:

gtk_widget_queue_draw_area (GTK_WIDGET(user_data), 0, 0, w, h)

它是个需要重绘的矩形区,这里是全部区域,也可以是部分需要更新的区域,比如画实时曲线时的很小一部分变化,不过图小的时候全绘也不会有速度问题的。全绘的话,也可以去掉后面的_area,就直接是全绘了,后面的参数也省了。

Function setDrawfunctionFlag CDECL ALIAS "setDrawfunctionFlag" ( _
		BYVAL widget AS GtkWidget PTR, _
		BYVAL user_data AS gpointer) AS gboolean EXPORT

		if DrawfunctionFlag + 1 >2 then
			DrawfunctionFlag = 0
		else
			DrawfunctionFlag += 1
		end if
		
		VAR w = gtk_widget_get_allocated_width(GTK_WIDGET(user_data))
		VAR h = gtk_widget_get_allocated_height(GTK_WIDGET(user_data))
		gtk_widget_queue_draw_area (GTK_WIDGET(user_data), 0, 0, w, h)		

		Return TRUE
End Function

surface可以通过pixbuf产生,cairo-context可以由surface产生,可以操作cr在surface上绘图。如果释放掉surface产生的cr, 将surface作为界面送来cr的源surface,数据的图就渲染到界面上去了,类似内存考贝后叠加成新图片。goocanvas是基于cairo的,但用它绘图方式上有些不同,需要另外的方法处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1478030.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

图层基本知识

一、图层面板: 二、图层概念: 1.定义:图像的层次,可以单独调整和修改某一个图层,不会影响其他图层。 2.类型: 三、新建图层: 四、删除图层: 五、抓手工具: 快捷方式&a…

Java应用程序注册成Linux系统服务后,关闭Java应用程序打印系统日志

Java应用程序有自己的日志框架,有指定位置的日志文件,不需要在系统日志里记录,占用磁盘空间。 1.Linux系统文件目录 /etc/systemd/system/ 找到要修改的Java应用程序服务配置 比如bis-wz-80.service 2.设置不打印日志 StandardOutputnull S…

web安全学习笔记【20】——信息打点(10)

信息打点-公众号服务&Github监控&供应链&网盘泄漏&证书图标邮箱资产 #知识点: 1、业务资产-应用类型分类 2、Web单域名获取-接口查询 3、Web子域名获取-解析枚举 4、Web架构资产-平台指纹识别 ------------------------------------ 1、开源-CMS指纹…

【InternLM 实战营笔记】XTuner 大模型单卡低成本微调实战

XTuner概述 一个大语言模型微调工具箱。由 MMRazor 和 MMDeploy 联合开发。 支持的开源LLM (2023.11.01) InternLM Llama,Llama2 ChatGLM2,ChatGLM3 Qwen Baichuan,Baichuan2 Zephyr 特色 傻瓜化: 以 配置文件 的形式封装了大…

【Unity】实现从Excel读取数据制作年份选择器

效果预览: 此处利用Excel来读取数据来制作年份选择器,具体步骤如下。 如果只是制作年份选择器可以参考我这篇文章:构建简单实用的年份选择器(简单原理示范) 目录 效果预览: 一、 Excel准备与存放 1.1 …

IntelliJ IDEA上svn分支管理和使用

IntelliJ IDEA上svn分支管理和使用 从Subversion下载trunk下的代码 选择项目创建分支 右键 Subversion --> branch or Tag … 选择Repository Location:需要创建的项目 选择Any Location 分支的位置和名字 详细查看截图 切换到分支 选择项目右键Subversion --> Update …

初阶数据结构:链表相关题目练习(补充)

目录 1. 单链表相关练习题1.1 移除链表元素1.2 反转链表1.3 链表的中间结点1.4 链表的倒数第k个结点1.5 合并两个有序链表1.6 链表分割1.7 链表的回文结构1.8 相交链表1.9 判断一个链表中是否有环1.10 寻找环状链表相遇点1.11 链表的深度拷贝 1. 单链表相关练习题 注&#xff1…

低功耗微处理器复位检测电路D706,工作温度范围-40~+80℃,可与μP监控产品兼容

近年来,微处理器在IT业控制领域和智能化产品中得到了广泛的应用。在系统和产品的开发设计过程中,为了提高其抗干扰能力,使用μP监控是首选技术措施之一。监控芯片可为系统提供上电、掉电复位功能,也可提供其它功能,如后…

SpringBoot 自定义注解实现操作日志记录

文章目录 前言正文一、项目结构介绍二、核心类2.1 核心注解2.1.1 CLog 日志注解2.1.2 ProcessorBean 处理器bean 2.2 切面类2.3 自定义线程池2.4 工具类2.4.1 管理者工具类 2.5 测试2.5.1 订单创建处理器2.5.2 订单管理者2.5.3 订单控制器2.5.4 测试报文2.5.5 测试结果 附录1、…

Docker部署前后端服务示例

使用Docker部署js前端 1.创建Dockerfile 在项目跟目录下创建Dockerfile文件: # 使用nginx作为基础镜像 FROM nginx:1.19.1# 指定工作空间 WORKDIR /data/web# 将 yarn build 打包后的build文件夹添加到工作空间 ADD build build# 将项目必要文件添加到工作空间&a…

【Python】FastAPI 项目创建 与 Docker 部署

文章目录 前言&需求描述1. 本地FastAPI1.1 Python 环境准备1.2 本地 Pycharm 创建FastAPI项目 2. Python FastAPI 部署2.1 服务器配置Python环境2.2.1 下载与配置Git、Pyenv等工具2.2.2 下载与配置Python 2.2 FastAPI 打包成镜像2.2.1 项目准备所需环境文件2.2.2 编写Docke…

python matplotlib 三维实体圆柱图

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np from mpl_toolkits.mplot3d import Axes3D import matplotlib.ticker as tickerdef map_rate(X: list, to_min: float, to_max: float)…

Restful风格解释

示例对比 传统风格开发 Restful风格开发 结论: 传统风格开发中,前端不同操作使用不同的url来访问后端,使得访问变得麻烦restful风格中,前端使用相同的url来访问后端,但是用数据传送方式进行区分(get为请求…

DataGrip2023配置连接Mssqlserver、Mysql、Oracle若干问题解决方案

1、Mssqlserver连接 本人连的是Sql2008,默认添加时,地址、端口、实例、账号、密码后,测试连接出现错误。 Use SSL:不要勾选 VM option:填写,"-Djdk.tls.disabledAlgorithmsSSLv3, RC4, DES, MD5withR…

c#使用log4net的3种调用方法

https://blog.csdn.net/summer_top/article/details/107961245 第一步:下载log4net。 右键项目引用,进入管理NuGet包。 搜索log4net,下载安装。 第二步:创建LogHelper类。 public class LogHelper { private LogHelp…

说一说kong日志级别

Kong官网:The Platform Powering the API World | Kong Inc. Kong Gateway:Kong Gateway | Kong Docs Kong Admin API:Admin API - Kong Gateway - v3.4.x | Kong Docs Kong 企业版社区:API Community for Developers and Industr…

ad18学习笔记十六:如何放置精准焊盘到特定位置,捕抓功能的讲解

网上倒是一堆相关的指导 AD软件熟练度提升,如何设置板框捕捉?_哔哩哔哩_bilibili 关于Altium Designer 20 的捕抓功能的讲解_ad捕捉设置-CSDN博客 AD软件捕捉进阶实例,如何精确的放置布局元器件?_哔哩哔哩_bilibili AD绘制PCB…

android游戏开发大全pdf,赶紧学起来

面经分享 第一部分是我前端面试的经验总结,第二部分是我认为比较有思考空间的题目 经验总结 一份漂亮的简历,需要包括以下部分(排版由上而下) 个人亮点(专精领域,个人博客,开源项目&#xff09…

jmeter 压测数据库

当前版本: jmeter 5.6.3mysql 5.7.39 简介 JMeter 是一个开源的 Java 应用程序,主要用于进行性能测试和负载测试。它支持多种协议,包括但不限于 HTTP、HTTPS、FTP、JDBC 以及各种 Web Services。对于数据库的压力测试可以使用 JDBC 协议与数…

Python算法题集_组合总和

Python算法题集_组合总和 题39:组合总和1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【值传递回溯】2) 改进版一【引用传递堆栈回溯】3) 改进版二【过程值列表缓存遍历后检索】 4. 最优算法5. 相关资源 本文为Python算法题集之一的…