Widget和回调函数
书接上文,我们创建了一个窗口用来显示三维模型,除了可以在窗口中拖动,没有其他交互。
o3d.gui
中提供了很多的方便易用Widget
,可以构建菜单栏,按钮,文本框,文件拾取器等,完成复杂的功能与交互。
这次我们创建一个按钮和文本框,设置按钮的点击事件弹出一个MessageBox。
1.导入模块
这次不需要加载模型和渲染,所以只用导入gui
模块
import open3d.visualization.gui as gui
2.添加Widget与事件
import open3d.visualization.gui as gui
class App:
count = 0
def __init__(self):
# 初始化
gui.Application.instance.initialize()
self.window = gui.Application.instance.create_window(
"Event and Widget", 300, 600)
# 使用相对大小避免直接设置像素,因为不同显示器像素大小可能不同
em = self.window.theme.font_size
# 文本框和按钮
self._push_edit = gui.TextEdit()
push_button = gui.Button('...')
push_button.horizontal_padding_em = 0.5
push_button.vertical_padding_em = 0
push_button.set_on_clicked(self._on_push_button)
# 文本框和按钮水平布局
push_button_layout = gui.Horiz()
push_button_layout.add_child(gui.Label('Push Button'))
push_button_layout.add_child(self._push_edit)
push_button_layout.add_fixed(0.25*em)
push_button_layout.add_child(push_button)
# 总体垂直布局
self.pannel = gui.Vert()
self.pannel.add_fixed(0.5*em)
self.pannel.add_child(push_button_layout)
self.window.add_child(self.pannel)
def _on_push_button(self):
self.count += 1
# 设置文本框文字
self._push_edit.text_value = f'push count {self.count}'
# 弹出消息框
self.window.show_message_box('Push Info', 'Hello World!')
def run(self):
gui.Application.instance.run()
if __name__ == "__main__":
app = App()
app.run()
2.1创建Button
创建一个Button是十分容易的。
btn = gui.Button(str)
- str是显示在Button上的文本
创建好button之后,最好设置一下水平和垂直padding,否则显示会比较诡异。设置padding可以通过Button.horizontal_padding_em
和Button.vertical_padding_em
设置。
未设置:
设置horizontal_padding_em=0.5
,vertical_padding_em=0
2.2 回调事件
按钮的回调事件通过Button.set_on_clicked()
进行设置,函数原型为:
set_on_clicked(self, Callable[], None) -> None
处理该事件的函数没有参数也没有返回值。
所以我们代码中设置的回调函数是没有参数和返回的:
def _on_push_button(self) -> None
我们在这个事件中做了两件事,更新文本框的文字并且弹出一个消息框。文本框的文字可以直接通过gui.TextEdit.text_value
访问和修改。弹出消息框需要调用主窗口self.window
的show_message_box
方法,该方法的两个参数分别是标题(title)和消息内容(message)。
self._push_edit.text_value = f'push count {self.count}'
self.window.show_message_box('Push Info', 'Hello World!')
2.3 界面布局(Layout)
最主要两种布局是水平布局gui.Horize()
和垂直布局gui.Vert()
。
add_child()
来向布局中添加子控件;add_fixed()
添加一个固定填充来调整控件之间的距离;add_stretch()
添加空格来占用布局中的剩余空间;
在调整控件间距的过程中,如使用
add_fixed()
,最好用相对大小来调整距离,避免直接设置像素大小的距离,以免由于不同的显示器像素大小不同导致奇怪的效果。相对大小可以通过
em = self.window.theme.font_size
来获得。
代码中有一个总体的垂直布局self.pannel
,一个按钮的水平布局push_button_layout
。按钮的布局中依次添加了文本控件gui.Label(text)
,文本框,固定间距0.25*em
和按钮。
将push_button_layout
作为self.pannel
的子控件添加到总体布局中,然后将self.pannel
添加到窗口就完成了整个布局过程。
3.运行结果
Open3d版本:0.13.0
运行这个程序,你将得到一个带有按钮的界面,点击按钮会弹出消息框(Message Box)并修改文本框中的文字。