英文:
How does one paint underlying widgets when using go's exp/shiny?
问题
假设以下是要翻译的内容:
#假设以下是小部件布局:
type myLeaf struct {
node.LeafEmbed
// 其他一些字段
}
func NewMyLeaf() *myLeaf {
w := &myLeaf{}
w.Wrapper = w
return w
}
func (w *myLeaf) Paint(ctx *node.PaintContext, origin image.Point) error {
w.Marks.UnmarkNeedsPaint()
// 在ctx上绘制...
}
#在`driver.Main()`内部:
leafA := NewMyLeaf()
leafB := NewMyLeaf()
w := widget.NewFlow(widget.AxisVertical,
widget.NewSheet(leafA),
widget.NewSheet(leafB),
)
if err := widget.RunWindow(s, w, &widget.RunWindowOptions{
NewWindowOptions: screen.NewWindowOptions{},
}); err != nil {
log.Fatal(err)
}
如何在`driver.Main()`之外执行`func (w *myLeaf) Paint(...) error`,对于每个叶子(`myLeaf`)的小部件树?
同时,对于`leafA`、`leafB`和`w`使用指针是可能的。
以下是翻译的结果:
#假设以下是小部件布局:
type myLeaf struct {
node.LeafEmbed
// 其他一些字段
}
func NewMyLeaf() *myLeaf {
w := &myLeaf{}
w.Wrapper = w
return w
}
func (w *myLeaf) Paint(ctx *node.PaintContext, origin image.Point) error {
w.Marks.UnmarkNeedsPaint()
// 在ctx上绘制...
}
#在`driver.Main()`内部:
leafA := NewMyLeaf()
leafB := NewMyLeaf()
w := widget.NewFlow(widget.AxisVertical,
widget.NewSheet(leafA),
widget.NewSheet(leafB),
)
if err := widget.RunWindow(s, w, &widget.RunWindowOptions{
NewWindowOptions: screen.NewWindowOptions{},
}); err != nil {
log.Fatal(err)
}
如何在`driver.Main()`之外执行`func (w *myLeaf) Paint(...) error`,对于每个叶子(`myLeaf`)的小部件树?
同时,对于`leafA`、`leafB`和`w`使用指针是可能的。
英文:
#Asuming the folowing widget layout:
type myLeaf struct {
node.LeafEmbed
// some other fields
}
func NewMyLeaf() *myLeaf {
w := &myLeaf{}
w.Wrapper = w
return w
}
func (w *myLeaf) Paint(ctx *node.PaintContext, origin image.Point) error {
w.Marks.UnmarkNeedsPaint()
// draw to ctx ...
}
#Inside driver.Main()
:
leafA := NewMyLeaf()
leafB := NewMyLeaf()
w := widget.NewFlow(widget.AxisVertical,
widget.NewSheet(leafA),
widget.NewSheet(leafB),
)
if err := widget.RunWindow(s, w, &widget.RunWindowOptions{
NewWindowOptions: screen.NewWindowOptions{},
}); err != nil {
log.Fatal(err)
}
How does one execute func (w *myLeaf) Paint(...) error
on the widget tree for each leaf (myLeaf
) from outside driver.Main()
?
Also using pointers for leafA
, leafB
and w
is possible.
答案1
得分: 0
当我们查看这里时,我们发现widget.RunWindow( ... )
不能处理来自调用者的外部请求。
一个解决方法是实现一个类似的函数MyRunWindow( ... )
并将Window
分配给一个全局接口。像这样:
func MyRunWindow(s screen.Screen, root node.Node, opts *RunWindowOptions) (err error) {
var nwo *screen.NewWindowOptions
// ... 分配窗口选项 ...
if MyWindow, err = s.NewWindow(nwo); err != nil {
return err
}
// 事件循环,处理 'lifecycle.Event','input.Event' 等
// 你可以在类型开关中处理自己的 'Events'
for {
e := MyWindow.NextEvent()
if e = gef.Filter(e); e == nil {
continue
}
switch e := e.(type) {
case MyEvent:
// ... 在这里调用 'root'
}
}
}
在调用者的一侧,你可以像这样使用全局的Interface
:
MyWindow.Send(paint.Event{}) // 用于调用 root.Paint()
MyWindow.Send(MyEvent{}) // 用于处理自定义事件
英文:
When we look up here we see that widget.RunWindow( ... )
doesn't handle such external requests from the caller.
A workaraound could be to implement an analogous function MyRunWindow( ... )
and assign the Window
to an global Interface. Like this:
func MyRunWindow(s screen.Screen, root node.Node, opts *RunWindowOptions) (err error) {
var nwo *screen.NewWindowOptions
// ... assign window options ...
if MyWindow, err = s.NewWindow(nwo); err != nil {
return err
}
// event loop, processing 'lifecycle.Event', 'input.Event', etc.
// and you can process own 'Events' in a type switch
for {
e := MyWindow.NextEvent()
if e = gef.Filter(e); e == nil {
continue
}
switch e := e.(type) {
case MyEvent:
// ... call on 'root' here
}
}
On the caller side you can use your global Interface
like this:
MyWindow.Send(paint.Event{}) // for a needed call to root.Paint()
MyWindow.Send(MyEvent{}) // for your own event to be processed
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论