visualfc / atk Goto Github PK
View Code? Open in Web Editor NEWAnother Golang Tcl/Tk binding GUI ToolKit
License: GNU Lesser General Public License v2.1
Another Golang Tcl/Tk binding GUI ToolKit
License: GNU Lesser General Public License v2.1
代码如下:
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)
}
如下:
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"}},
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.
代码如下:
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窗口刷新 应该是一模一样的
I'm trying to set an attribute on a widget using a tk.WidgetAttr
but the key
and value
fields are not exported:
Lines 10 to 13 in 069a392
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
子窗口加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)
}
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,
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
The example code does not compile anymore.....
There something missing here:
mw.Center()
私想要用atk写GUI,但是无奈没有文档,又无法理解您的代码实现,所以希望给一个文档,帮助我们理解。
感恩不尽
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)?
For widgets that don't have background color as a NativeAttribute, like for instance Frames, how can that be set?
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
\[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
\[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
What the problem.
希望作者能添加system tray组件。
你好,我看了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
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
Failed to load tcl86t.dll: The specified module could not be found.
using activetcl 8.6.3.1
/usr/bin/ld: 找不到 -lmpich
collect2: error: ld returned 1 exit status
这个和配置有关吗
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.