Open3D 界面编程之控件详解

发布时间:2025-12-09 16:50:03 浏览次数:5

文章目录

      • 基础控件
      • 树形图
      • 图像显示控件
      • ColorEdit

基础控件

根据控件的使用难度和功能的复杂度,这里挑选出九种最简单,同时使用最为频繁的九种控件

入门控件备注输入参数
Label文本标签
TextEdit文本输入框
Button按钮
Checkbox单选框
Combobox下拉选框
Slider数字滚动条Slider.Type
VectorEdit向量编辑框
NumberEdit数字编辑框
ToggleSwitch开关

其中,大部分控件的输入参数为控件上显示出来的文本,这些控件都可以通过外挂函数的方式来添加交互动作。

Combobox为下拉选框,下拉选框的内容通过add_item来添加。

Slider为滚动条,创建之后,其初始值默认为0,取值范围是负无穷到正无穷,通过set_limits来添加最大值和最小值。

为了集中展示这些控件的功能,将其写入一个字典中,并为每个控件分配一个控件,向命令行输出一些反馈。

import open3d as o3dimport open3d.visualization.gui as guiimport open3d.visualization.rendering as renderingapp = gui.Application.instanceapp.initialize()# 准备演示的九种控件CTRLS = {"label" : gui.Label("label"),"text" : gui.TextEdit(),"button" : gui.Button("button"),"check" : gui.Checkbox("checkbox"),"combo" : gui.Combobox(),"slider" : gui.Slider(gui.Slider.Type(0)),"vector" : gui.VectorEdit(),"number" : gui.NumberEdit(gui.NumberEdit.Type(0)),"toggle" : gui.ToggleSwitch("ToggleSwitch")}# 为combobox添加内容for i in range(5):CTRLS["combo"].add_item(str(i))# 为 slider 添加取值范围CTRLS["slider"].set_limits(0,20)win = app.create_window("Open3d Test", 500, 100)vert = gui.Vert(0, gui.Margins(2,2,2,2))win.add_child(vert) # 将布局加载到窗口for key in CTRLS:vert.add_child(CTRLS[key])app.run()

效果如下

这九种控件,除了Label之外,均可注册回调函数,在发生动作时执行

接下来为这些控件分别注册一些函数,其基础函数如下

控件函数执行条件回调函数参数
TextEditset_on_value_changed敲击回车控件文本
Buttonset_on_clicked点击按钮
Checkbox单选框点击单选框状态
Combobox下拉选框值发生变动选中的item序号和值
Slider数字滚动条位置发生变动当前值
VectorEdit向量编辑框敲击回车控件向量
NumberEdit数字编辑框值发生变化控件的值
ToggleSwitch开关点击开关状态

其演示函数如下,可写在app.run()之前。

# TextEdit的测试函数,其输入为改动后的内容def text_test(txt):print(CTRLS["text"].text_value)CTRLS["text"].set_on_value_changed(print)# VectorEdit的测试函数,输入为改动后的向量def vector_test(vec):print(CTRLS["vector"].vector_value)CTRLS["vector"].set_on_value_changed(vector_test)# Slider的测试函数,输入为改动后的值def slider_test(val):print(CTRLS["slider"].int_value)passCTRLS["slider"].set_on_value_changed(slider_test)# val 和 ind 分别为combo选中的位置和选中的值def combo_test(val, ind):print(CTRLS["combo"].selected_index)print(CTRLS["combo"].selected_text)CTRLS["combo"].set_on_selection_changed(combo_test)# Checkbox的测试函数,chk为选中后的值def check_test(chk):print(CTRLS["check"].checked)CTRLS["check"].set_on_checked(check_test)def toggle_test(isOn):# 当打开toggle时,is_on为True,否则为Falseprint(CTRLS["toggle"].is_on) CTRLS["toggle"].set_on_clicked(toggle_test)

树形图

TreeView是树形图中最为基础的,树的每个节点都只包含一个标签,其基本形式如下

代码如下

import open3d as o3dimport open3d.visualization.gui as guiimport open3d.visualization.rendering as renderingapp = gui.Application.instanceapp.initialize()win = app.create_window("tree view", 500, 200)tree = gui.TreeView()tree.add_text_item(tree.get_root_item(), "uncle")father = tree.add_text_item(tree.get_root_item(), "father")big = tree.add_text_item(father, "big son")tree.add_text_item(big, "grandson 1")tree.add_text_item(big, "grandson 2")tree.add_text_item(big, "grandson 3")little = tree.add_text_item(father, "little son")tree.can_select_items_with_children = Truedef _on_tree(self, item):print(item)tree.set_on_selection_changed(self._on_tree)tree.selected_item = littlewin.add_child(tree)app.run()

其中,gui.TreeView用于生成一个树形图,add_text_item用以添加树形图的节点,其输入参数有二,分别是父节点和节点名称。

tree.add_text_item(tree.get_root_item(), "uncle")

上面这条代码中,tree.get_root_item()用于获取根节点,整体而言的意思是,在根节点下面添加一个子节点,标签为uncle。

add_text_item函数返回的是新建子节点这个对象,由于uncle节点没有子节点,无需新建一个变量为其标识。而father有三个子节点,为了让他的两个儿子挂载到他这个节点上,需要新建一个变量名。

最后,为树形图添加了一个动作,即当选择的节点发生变化时,执行_on_tree这个函数。

树的成员can_select_items_with_children设为True,说明每个节点都可以被选中,如果设为False,那么当点击节点的标签时,会直接打开或者关闭这一层节点。当然这是官网说的,我其实并没有感觉出来二者有什么不同。

CheckableTextTreeCell

在treeview的节点中,除了朴实无华的标签之外,还可以添加勾选框,只需将add_text_item替换为add_item,就可以添加CheckableTextTreeCell作为节点

效果为

代码如下

app = gui.Application.instanceapp.initialize()win = app.create_window("tree view", 500, 200)check = lambda str : lambda isChecked : print(str, isChecked)tree = gui.TreeView()root = tree.get_root_item()tree.add_item(root, gui.CheckableTextTreeCell("uncle", False, check("uncle")))father = tree.add_item(root, gui.CheckableTextTreeCell("father", False, check("father")))tree.add_item(father, gui.CheckableTextTreeCell("big son", False, check("big son")))tree.add_item(father,gui.CheckableTextTreeCell("little son", False, check("little son")))tree.can_select_items_with_children = Truedef _on_tree(self, item):print(item)tree.set_on_selection_changed(self._on_tree)tree.selected_item = littlewin.add_child(tree)app.run()

add_item的输入参数分别是父节点和子节点对应的对象,gui.CheckableTextTreeCell的输入参数有三个,分别是标签字符串,选框是否选中,以及一个回调函数。

考虑到学习open3d的同学一般都是老手,故而这里用了lambda表达式,相当于对每个节点都生成一个专门的回调函数,例如

check("uncle")相当于

# 由于是匿名函数,所以函数名姑且用_表示def _(isChecked):print("uncle", isChecked)

ColormapTreeCell

只要学会了CheckableTextTreeCell,那么理解ColormapTreeCell也就毫无难度。

ColormapTreeCell的构造函数中包括四个输入参数,分别是

  • value:数值
  • color:颜色
  • on_value_changed:数字变化时的回调函数
  • on_color_changed:颜色变化时的回调函数

LUTTreeCell

LUTTreeCell就更加综合了,将选框和颜色都排到了树形图的节点中,故而其构造函数更加复杂,包括

  • text 文本内容
  • is_checked 选框是否选中
  • color 颜色
  • on_enabled 选框状态变化时的回调函数
  • on_color 颜色变化时的回调函数

考虑到add_item添加节点的数据类型为gui.Widget,故而绝对不限于这些专门用于树形图的数据类型,这里只是做一个简要的介绍,其实际应用可以更加炫酷。

图像显示控件

ImageWidget

作为三维点云工具,Open3D连三维的形状都能画出来,那二维的图像就更不在话下了。ImageWidget是gui中显示图像的控件,和大多数控件不同的是,图像控件提供了多种构造函数

  • 无参数,将生成一个没有图像的占位区域
  • 输入路径,将打开该路径所对应的图像
  • 输入Image类型的数据
  • 输入t.geometry中的Image类型数据
  • 现以第二种为例,创建一个图像控件

    import open3d as o3dimport open3d.visualization.gui as guiimport open3d.visualization.rendering as renderingapp = gui.Application.instanceapp.initialize()win = app.create_window("Image")imgFrame = gui.ImageWidget("test.jpg")win.add_child(imgFrame)app.run()

    效果如下

    Image是open3d.geometry中的一种数据类型,其默认的初始化方式是通过矩阵,下面用随机数生成一个矩阵,并装载到图像中

    import numpy as npimg_data = (np.random.rand(300, 600)*255).astype(np.uint8)img = o3d.geometry.Image(img_data)imgFrame = gui.ImageWidget(img)

    效果如下

    ImageWidget中提供了update_image的方法,可以更新显示的图像内容,其输入参数同样为Image类型数据,

    ColorEdit

    顾名思义,颜色编辑控件,效果如下

    import open3d as o3dimport open3d.visualization.gui as guiimport open3d.visualization.rendering as renderingapp = gui.Application.instanceapp.initialize()win = app.create_window("color edit", 640, 360)clr = gui.ColorEdit()win.add_child(clr)app.run()

    在gui中,提供了Color类,用于表示颜色,ColorEdit控件绑定的函数输入值,就是这种数据类型。

    Color类有四个成员,即RGBA,表示四个通道:红色、绿色、蓝色以及透明度。

    def test(c):print(c.red)print(c.blue)print(c.green)print(c.alpha)clr.set_on_value_changed(test)

    效果为

    由于Gif压制的问题,无法表示过于细腻的颜色,故而颜色选择框有些异常,但无碍于理解。

    需要做网站?需要网络推广?欢迎咨询客户经理 13272073477