Giter Club home page Giter Club logo

atk's Introduction

atk

Another Golang Tcl/Tk binding GUI ToolKit

go get github.com/visualfc/atk

Go docs: https://pkg.go.dev/github.com/visualfc/atk/tk

Install Tcl/Tk

http://www.tcl-lang.org

Demo

https://github.com/visualfc/atk_demo

Sample

package main

import (
	"github.com/visualfc/atk/tk"
)

type Window struct {
	*tk.Window
}

func NewWindow() *Window {
	mw := &Window{tk.RootWindow()}
	lbl := tk.NewLabel(mw, "Hello ATK")
	btn := tk.NewButton(mw, "Quit")
	btn.OnCommand(func() {
		tk.Quit()
	})
	tk.NewVPackLayout(mw).AddWidgets(lbl, tk.NewLayoutSpacer(mw, 0, true), btn)
	mw.ResizeN(300, 200)
	return mw
}

func main() {
	tk.MainLoop(func() {
		mw := NewWindow()
		mw.SetTitle("ATK Sample")
		mw.Center(nil)
		mw.ShowNormal()
	})
}

atk's People

Contributors

aquilax avatar jopbrown avatar mark-summerfield avatar pwiecz avatar visualfc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

atk's Issues

custom TCL and TK dll path?

i have a problem where if I don't install my tcl86.dll and tk86.dll from ActiveState installer and instead copy those to folder where the binary is it just wouldn't load those dll that I give it and instead always tries to load it somewhere else.
so of instead of loading same path as always. can you make it supports to find dll in program's folder or maybe give an option to load from the bytearray (so i can go:embed it)?

关于font.go

你好,我看了tk/font.go,

func NewUserFont(family string, size int, attributes ...*FontAttr) *UserFont
func NewUserFontFromClone(font Font) *UserFont

这两个函数返回*UserFont,我大概明白

下面几个设置*UserFont属性的函数:

func (w *UserFont) SetFamily(family string) *UserFont 
func (w *UserFont) SetSize(size int) *UserFont
func (w *UserFont) SetBold(bold bool) *UserFont 
func (w *UserFont) SetItalic(italic bool) *UserFont 
func (w *UserFont) SetUnderline(underline bool) *UserFont
func (w *UserFont) SetOverstrike(overstrike bool) *UserFont 

都返回了*UserFont,设置字体属性完毕后我感觉应该不需要返回*UserFont
如有错误,请见谅

我看了下font的demo,这里面:
https://github.com/visualfc/atk_demo/blob/master/font/font.go, 第三十八行

是这样写的,w.font.SetFamily(cmbFamily.CurrentText())
而不是 w.font = w.font.SetFamily(cmbFamily.CurrentText())

https://github.com/visualfc/atk/blob/master/tk/layout.go, 51行至81行的几个Set函数也是这样

func (w *LayoutSpacer) SetSpace(space int) *LayoutSpacer
func (w *LayoutSpacer) SetExpand(expand bool) *LayoutSpacer
func (w *LayoutSpacer) SetWidth(width int) *LayoutSpacer
func (w *LayoutSpacer) SetHeight(height int) *LayoutSpacer

设置Spinbox属性不起作用,widget_meta.go中TSpinbox需要修改

如下:
widget_meta.go
TSpinbox的属性: []string{"-from", "-to", "-increment", ...},不应该有“-”

	typeMetaMap[WidgetTypeSpinBox] =
		&MetaType{
			Type: "SpinBox",
			Tk: &MetaClass{"tk::spinbox", "Spinbox",
				[]string{"activebackground",
					"background",
					"borderwidth",
					"buttonbackground",
					"buttoncursor",
                                         ....
					"xscrollcommand"}},
			Ttk: &MetaClass{"ttk::spinbox", "TSpinbox",
				[]string{"-values",
					"-from",
					"-to",
					"-increment",
					"-format",
					"-command",
					"-wrap",
					"-exportselection",
                                        ......
					"-foreground",
					"-background",
					"-takefocus",
					"-cursor",
					"-style",
					"-class"}},

可不可以给个文档

私想要用atk写GUI,但是无奈没有文档,又无法理解您的代码实现,所以希望给一个文档,帮助我们理解。
感恩不尽

Canvas控件方法的补充

\[email protected]\tk\canvas.go

func (w *Canvas) PlotLine(xy map[int]int, options map[string]string) error {
    // canvas create line x1 y1... xn yn ?option value ...? // 不闭合折线
    // canvas create line 10 10 200 50 -fill red -width 3 -tags line1
    
    var tmp1 = ""
    for x,y := range xy {
        tmp1 = tmp1 + strconv.Itoa(x) + " " + strconv.Itoa(y) + " "
    }
    var tmp2 = ""
    for k,v := range options {
        tmp2 = tmp2 + "-" +k+ " " + v + " "
    }
    
	return eval(fmt.Sprintf("%v create line %v%v", w.id, tmp1, tmp2))
}

func (w *Canvas) PlotRectangle(x1,y1,x2,y2 int, options map[string]string) error {
    // canvas create rectangle x1 y1 x2 y2 ?option value ...? // 矩形
    // canvas create rectangle 10 10 200 50 -fill red -outline blue -tags rec1

    var tmp2 = ""
    for k,v := range options {
        tmp2 = tmp2 + "-" +k+ " " + v + " "
    }
    
	return eval(fmt.Sprintf("%v create rectangle %v %v %v %v %v", w.id, x1,y1,x2,y2, tmp2))
}


func (w *Canvas) PlotOval(x1,y1,x2,y2 int, options map[string]string) error {
    // canvas create oval x1 y1 x2 y2 ?option value ...?   // 矩形内切椭圆或圆
    // canvas create oval 10 10 200 50 -fill red -outline blue -tags oval1

    var tmp2 = ""
    for k,v := range options {
        tmp2 = tmp2 + "-" +k+ " " + v + " "
    }
    
	return eval(fmt.Sprintf("%v create oval %v %v %v %v %v", w.id, x1,y1,x2,y2, tmp2))
}

func (w *Canvas) PlotPolygon(xy map[int]int, options map[string]string) error {
    // canvas create polygon x1 y1 ... xn yn ?option value ...?  // 多边形
    // canvas create polygon 10 10 180 90 20 45 -fill red -width 3 -tags pol1 
    
    var tmp1 = ""
    for x,y := range xy {
        tmp1 = tmp1 + strconv.Itoa(x) + " " + strconv.Itoa(y) + " "
    }
    var tmp2 = ""
    for k,v := range options {
        tmp2 = tmp2 + "-" +k+ " " + v + " "
    }
    
	return eval(fmt.Sprintf("%v create polygon %v%v", w.id, tmp1, tmp2))
}


func (w *Canvas) PlotText(x1,y1 int, options map[string]string) error {
    // canvas create text x y ?option value ...?  // 文字
    // canvas create text 100 100 -text "A wonderful story" -anchor nw -fill black -tags txt1

    var tmp2 = ""
    for k,v := range options {
        tmp2 = tmp2 + "-" +k+ " " + v + " "
    }
    // v 值含有空格时使用{}, "text":"{A wonderful story}"
    
	return eval(fmt.Sprintf("%v create text %v %v %v", w.id, x1,y1, tmp2))
}

func (w *Canvas) PlotImage(x1,y1 int, options map[string]string) error {
    // canvas create image x y ?option value ...?
    // canvas create image 10 10 -image myimg -anchor nw
    var tmp2 = ""
    for k,v := range options {
        tmp2 = tmp2 + "-" +k+ " " + v + " "
    }
    
	return eval(fmt.Sprintf("%v create image %v %v %v", w.id, x1,y1, tmp2))
}


func (w *Canvas) PlotWidget(x1,y1 int, options map[string]string) error {
    // canvas create window x y ?option value ...?
    // canvas create window 10 10 -anchor nw -window .canvas.b
    var tmp2 = ""
    for k,v := range options {
        tmp2 = tmp2 + "-" +k+ " " + v + " "
    }
    
	return eval(fmt.Sprintf("%v create window %v %v %v", w.id, x1,y1, tmp2))
}

几个例子

    canvas := tk.NewCanvas(mw)
    canvas.SetNativeAttribute("background","red")
    canvas.SetNativeAttribute("width","200")
    canvas.SetNativeAttribute("height","200")
    canvas.SetNativeAttribute("height","200")

    // canvas.PlotLine(map[int]int{10:10,50:50}, map[string]string{"fill":"yellow","width":"3","tags":"line1"})

    // canvas.PlotRectangle(15,15,180,90,map[string]string{"fill":"green","outline":"blue","tags":"rec1"})

    canvas.PlotOval(15,15,180,90,map[string]string{"fill":"green","outline":"blue","tags":"oval1"})

    canvas.PlotPolygon(map[int]int{10:10,180:90,25:45}, map[string]string{"fill":"yellow","width":"3","tags":"pol"})

    canvas.PlotText(100,100, map[string]string{"fill":"black","text":"{A wonderful story}","anchor":"nw","tags":"txt1"})
    
    img, _ := tk.LoadImage("./btn02.png")
    
    canvas.PlotImage(70,100, map[string]string{"image":img.Id(),"anchor":"nw","tags":"img1"})
    
    canavsbtn := tk.NewButton(canvas,"canvasbtn",tk.WidgetAttrInitUseTheme(false))

    canvas.PlotWidget(50,50, map[string]string{"window":canavsbtn.Id(),"anchor":"nw","tags":"widget1"})

参考:
http://www.tcl-lang.org/man/tcl8.6/TkCmd/canvas.htm
https://tkdocs.com/tutorial/canvas.html

misc.go属性定义反馈

misc.go
行:217-228
是不是少加了 Anchor :const AnchorCenter Anchor = iota

type Anchor int
const (
	AnchorCenter = iota
	AnchorNorth
	AnchorEast
	AnchorSouth
	AnchorWest
	AnchorNorthEast
	AnchorNorthWest
	AnchorSouthEast
	AnchorSouthWest
)

类似还有:

type Direction int
type Compound int
type State int
type ListSelectMode int
type DisplyCursor int
type LineWrapMode int
type TreeSelectMode int

Not download atk

For command "go get github.com/visualfc/atk" reaction:
can't load package: package github.com/visualfc/atk: no Go files in d:\coding\go\_home\src\github.com\visualfc\atk

WidgetAttr fields are unexported

I'm trying to set an attribute on a widget using a tk.WidgetAttr but the key and value fields are not exported:

atk/tk/widget_attr.go

Lines 10 to 13 in 069a392

type WidgetAttr struct {
key string
value interface{}
}

Outside of the tk package, how is one supposed to create and use these widgets?

This:

disabled := tk.WidgetAttr{"state", "disabled"}

gets this:

implicit assignment to unexported field key in struct literal of type tk.WidgetAttr

and this:

disabled := tk.WidgetAttr{key: "state", value: "disabled"}

gets this:

unknown field key in struct literal of type tk.WidgetAttr

VMware win7 Tcl_Init failed

tkgo.go
package main

import (
"github.com/visualfc/atk/tk"
)

type Window struct {
*tk.Window
}

func NewWindow() *Window {
mw := &Window{tk.RootWindow()}
lbl := tk.NewLabel(mw, "Hello ATK")
btn := tk.NewButton(mw, "Quit")
btn.OnCommand(func() {
tk.Quit()
})
tk.NewVPackLayout(mw).AddWidgets(lbl, tk.NewLayoutSpacer(mw, 0, true), btn)
mw.ResizeN(300, 200)
return mw
}

func main() {
tk.MainLoop(func() {
mw := NewWindow()
mw.SetTitle("ATK Sample")
mw.Center()
mw.ShowNormal()
})
}

go build tkgo.go --> tkgo.exe
put tkgo.exe in VMware win7
error: Tcl_Init failed

ttk主题风格的设置方法补充

\[email protected]\tk\theme_ttk.go

func (w *BaseWidget) StyleName() string {
    // ttk::button .b; winfo class .b  // ==> TButton
	r, _ := evalAsString(fmt.Sprintf("winfo class %v", w.id))
	return r
}

func (w *BaseWidget) StyleLookUp(name, option string) string {
    // ttk::style lookup style -option
    // ttk::style lookup 1.TButton -font  // [---> helvetica 24]
    r1, _ := evalAsString(fmt.Sprintf("ttk::style lookup %v -%v", name,option))
    return r1
}


func StyleConfigure(name string, options map[string]string) error {
    // ttk::style configure style ?-option ?value option value...? ?
    // ttk::style configure Emergency.TButton -foreground red -padding 10
    // ttk::button .b -text "Hello" -style "Fun.TButton"
    var tmp = ""
    for k,v := range options {
        tmp = tmp + "-" + k + " " + v + " "
    }
    
    return eval(fmt.Sprintf("ttk::style configure %v %v", name,tmp))
}

func StyleMap(name string, options map[string]map[string]string) error{
    // ttk::style map style ?-option { statespec value... }?
    // ttk::style map TRadiobutton -foreground [list !pressed blue pressed yellow] -background [list selected black !selected white]
    var tmp1 = ""
    var tmp2 = ""
    for k1,v1 := range options {
        tmp2 = "[list "
        tmp1 = tmp1 + "-" + k1 + " "
        for k2,v2 := range v1 {
            tmp2 = tmp2 + k2 + " " + v2 + " "
        }
        tmp2 = tmp2 + "] "
        tmp1 = tmp1 + tmp2
    }
    // fmt.Println(fmt.Sprintf("ttk::style map %v %v", name,tmp1))
    return eval(fmt.Sprintf("ttk::style map %v %v", name,tmp1))
}

例子

fmt.Println(tk.TtkTheme.ThemeIdList(),tk.TtkTheme.ThemeId()) // 返回当前平台可用ttk主题,及默认使用的ttk主题
==> [xpnative clam alt classic default winnative vista] vista
tk.TtkTheme.SetThemeId("alt") // 设置ttk主题

// 为Radiobutton控件设置一个名为”1.TRadiobutton“ 风格
tk.StyleConfigure("1.TRadiobutton",map[string]string{"font":"{consolas 10}","foreground":"red","background":"white"})

// 为Radiobutton控件设置一个名为”1.TRadiobutton“ map风格
tk.StyleMap("1.TRadiobutton",map[string]map[string]string{"foreground":{"pressed":"yellow","!pressed":"blue"},
    "background ":{"selected":"black","!selected":"white"}})

rtn1 := tk.NewRadioButton(mw,"rtn1",)
rtn2 := tk.NewRadioButton(mw,"rtn2",)
rtn3 := tk.NewRadioButton(mw,"rtn3",)

rtn1.SetNativeAttribute("style","1.TRadiobutton")
rtn2.SetNativeAttribute("style","1.TRadiobutton")
rtn3.SetNativeAttribute("style","1.TRadiobutton")

参考:
https://tkdocs.com/tutorial/styles.html
http://www.tcl-lang.org/man/tcl8.6/TkCmd/ttk_style.htm
https://tkdocs.com/shipman/ttk-map.html

Bind for Text Selection and Tag

Hi,

Thank you for the work, it looks good.

I am trying to build a small editor using this to replace / an alternative to gtksourceview. However I did not see how I can do:

Many thanks,

链接错误

github.com/visualfc/atk/tk/interp

/usr/bin/ld: 找不到 -lmpich
collect2: error: ld returned 1 exit status

这个和配置有关吗

Are scrollbars on frames doable?

Working off of Bryan Oakley's TKinter example here: https://stackoverflow.com/questions/3085696/adding-a-scrollbar-to-a-group-of-widgets-in-tkinter/3092341#3092341 I only got this far:

`
func NewWindow() *Window {
mw := &Window{tk.RootWindow()}
mw.ResizeN(800, 600)
canvas := tk.NewCanvas(mw, tk.WidgetAttrWidth(800), tk.WidgetAttrHeight(600), tk.CanvasAttrBorderWidth(0), tk.CanvasAttrBackground("white"))
frame := tk.NewFrame(canvas, tk.WidgetAttrWidth(750), tk.WidgetAttrHeight(270), tk.WidgetAttrInitUseTheme(false))
frame.SetNativeAttribute("background", "black")
// populate with some labels
for i := 0; i < 40; i++ {
lbl := tk.NewLabel(frame, "label "+strconv.Itoa(i))
lbl.SetBackground("#ccc")
tk.Grid(lbl, tk.GridAttrRow(i), tk.GridAttrColumn(0), tk.GridAttrPadx(5), tk.GridAttrPady(5), tk.GridAttrSticky(tk.StickyAll))
}
vertScrollbar := tk.NewScrollBar(mw, tk.Vertical, tk.WidgetAttrInitUseTheme(false))
vertScrollbar.SetNativeAttribute("command", "canvas yview") // bad window pathname error
tk.Grid(canvas, tk.GridAttrRow(0), tk.GridAttrColumn(0), tk.GridAttrSticky(tk.StickyAll))
tk.Grid(frame, tk.GridAttrRow(0), tk.GridAttrColumn(0), tk.GridAttrPadx(15), tk.GridAttrPady(15))
tk.Grid(vertScrollbar, tk.GridAttrRow(0), tk.GridAttrColumn(1), tk.GridAttrSticky(tk.StickyNS))
return mw
}

func main() {
tk.MainLoop(func() {
mw := NewWindow()
mw.SetTitle("ATK Sample")
mw.Center(nil)
mw.ShowNormal()
mw.BindKeyEvent(func(e *tk.KeyEvent) {
if e.Event.KeyCode == 9 { // esc key
tk.Quit()
}
})
})
}

The problem is these Python/TKinter lines:
vsb = tk.Scrollbar(root, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=vsb.set)
frame.bind("", lambda event, canvas=canvas: onFrameConfigure(canvas))
`

Any help appreciated.

If the focus of the question feels too narrow then how about example code showing attaching a scrollbar to anything?

I'm sorry that my code isn't appropriately indented. I clicked the "<>" icon, copy/pasted and lost the indents.

用go程去刷下控件内容没有作用

代码如下:

package main

import "github.com/visualfc/atk/tk"
import "strings"
import "strconv"
import "time"
import "fmt"

type Window struct { *tk.Window }


func f1(x float64) float64 {
   return x * x - x
}

func integrate_f1(a, b  float64, N int) float64 {
   // 0 23 10000000001
   var s float64 = 0
   dx := (b - a) / float64(N)

   for i:=0; i<N; i++ {
       s += f1(a + float64(i) * dx)
   }
   
   return s * dx
}

func cal(input string, resch chan string) {
    start := time.Now()

    inputnum := strings.Split(input," ")
    a,_ := strconv.ParseFloat(inputnum[0], 64)
    b,_ := strconv.ParseFloat(inputnum[1], 64)
    N,_ := strconv.Atoi(inputnum[2])
    res := integrate_f1(a, b, N)

    end := time.Now()
    
    delta := end.Sub(start)
    
    resch <- fmt.Sprintf("计算结果: \nres is %v \ntime: %s", res, delta)
    
}

func NewWindow() *Window {
    
    s1 := make(chan string)
    
    mw := &Window{}
    mw.Window = tk.RootWindow()
    
    labelf := tk.NewLabel(mw, "计算阻塞")
    entryf := tk.NewEntry(mw,)
    labels := tk.NewLabel(mw, "计算结果: ")
    btn1 := tk.NewButton(mw,"开始计算",tk.WidgetAttrInitUseTheme(true))
    btn2 := tk.NewButton(mw,"退出",tk.WidgetAttrInitUseTheme(true))

    btn1.SetTakeFocus(false)
    btn2.SetTakeFocus(false)

    // go运行耗时函数,然后go刷新label控件内容,但是内容没有刷新
    // labels.SetText(<-s1)这样的话可以刷新,但是界面会阻塞
    // go func() { fmt.Println(<-s1) }() 这样打印结果也没问题,界面不会阻塞
    btn1.OnCommand(func() { 
        go cal(entryf.Text(),s1)
        go func() { labels.SetText(<-s1) }()
    })
    
    btn2.OnCommand(func() { tk.Quit() })

    vbox := tk.NewVPackLayout(mw)
    vbox.SetPaddingN(5, 5)
    vbox.AddWidgetEx(labelf, 0, false, 6)
    vbox.AddWidgetEx(entryf, 0, false, 6)
    vbox.AddWidgetEx(labels, 0, false, 6)
    vbox.AddWidgetEx(btn1, 0, false, 6)
    vbox.AddWidgetEx(btn2, 0, false, 6)

    return mw
}

func main() {
    win := func() {
        mw := NewWindow()
        mw.SetTitle("阻塞窗口例子")
        mw.ResizeN(600, 600)
        mw.Center(nil)
        mw.ShowNormal()
    }
    
    tk.MainLoop(win)
}

如何创建一个顶级子窗口像 NewToplevel 这样

子窗口加ShowNormal()就成功了,昨天折腾大半天

package main

import "github.com/visualfc/atk/tk"
import "fmt"

type Window struct { *tk.Window }


func NewSubWin()  *Window {
    mw := &Window{}
    mw.Window = tk.NewWindow()
    
    lbl1 := tk.NewLabel(mw, "Hello ATK 01")
    btn := tk.NewButton(mw,"Destroy",tk.WidgetAttrWidth(20))
    btn.SetTakeFocus(false)
    btn.OnCommand(func() { mw.Destroy() })
    
    vbox := tk.NewHPackLayout(mw)
    vbox.AddWidget(lbl1,tk.PackAttrPadx(5),tk.PackAttrPady(5),tk.PackAttrAnchor(6))
    vbox.AddWidget(btn,tk.PackAttrPadx(5),tk.PackAttrPady(5),tk.PackAttrAnchor(6))
    return mw
}


func NewWindow() *Window {
    mw := &Window{}
    mw.Window = tk.RootWindow()
    
    lbl1 := tk.NewLabel(mw, "Hello ATK 01")
    
    btn := tk.NewButton(mw,"Quit",tk.WidgetAttrWidth(20))
    

    btn.SetNativeAttribute("cursor","hand1")
    btn.SetNativeAttributes(tk.NativeAttr{"width","42"},tk.NativeAttr{"underline","1"})
    fmt.Println(btn.NativeAttributes("cursor","width","underline"))

    btn.SetTakeFocus(false)

    btn.OnCommand(func() { tk.Quit() })
    btn2 := tk.NewButton(mw,"关于子窗口",tk.WidgetAttrWidth(20))
    btn2.SetTakeFocus(false)
    
    subwin := func() {
        sw := NewSubWin()
        sw.SetTitle("ATK Subwin Sample")
        sw.ResizeN(600, 600)
        sw.Center(nil)
        sw.ShowNormal()
    }
    
    btn2.OnCommand(func() { tk.MainLoop(subwin) })
    
    hbox := tk.NewVPackLayout(mw)
    hbox.SetPaddingN(5, 5)
    hbox.AddWidgetEx(lbl1, 0, false, 6)
    hbox.AddWidgetEx(btn, 0, false, 6)
    hbox.AddWidgetEx(btn2, 0, false, 6)

    vbox := tk.NewHPackLayout(mw)
    
    vbox.AddWidgetEx(hbox, 0, false, 6)
    lbl3 := tk.NewLabel(mw, "Hello ATK 02")
    vbox.AddWidget(lbl3,tk.PackAttrPadx(5),tk.PackAttrPady(5),tk.PackAttrAnchor(6))
    return mw
}

func main() {
    win := func() {
        mw := NewWindow()
        mw.SetTitle("ATK Sample")
        mw.ResizeN(600, 600)
        mw.Center(nil)
        mw.ShowNormal()
    }
    
    tk.MainLoop(win)
}

tk.Async 函数刷新GUI控件问题反馈

代码如下:

func tobpg(label tk.Widget, infotext *tk.TextEx, cmdargs []string, inputimgs []string) {
    start := time.Now()
    
    for i, in := range inputimgs {
        cmdargs1 := append(cmdargs, []string{"-o", in + ".bpg", in}...)
        
        cmd := exec.Command("bpgenc", cmdargs1...)
        cmd.Start()
        
        cmd.Wait() // 阻塞至cmd命令完成
        
        fmt.Println(inputimgs[i],": finished") // cmd打印第【i】个完成信息
        
        // GUI显示第【i】个完成信息
        tk.Async(func() { 
            infotext.AppendText(inputimgs[i] + ": finished\n") 
            infotext.SetSeeEnd()
        })
        
    }
    
    end := time.Now()
    delta := end.Sub(start)
    
    v := fmt.Sprintf("转码进度: 完成%v个图片转码,耗时:%s", len(inputimgs), delta)
    
    tk.Async(func() { label.SetNativeAttribute("text",v) })
}



for循环执行cmd命令,每完成一个cmd命令,就在Text控件刷新第几个cmd命令完成信息

StartBtn.OnCommand(func() { 
     go tobpg(......) 
})

点击这个StartBtn按钮之后,结果如下图:

Text控件刷新和cmd窗口刷新 应该是一模一样的

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.