#

如果您有任何關於Tcl的問題或是想法,歡迎在這邊和大家一起討論分享。

190 個意見

dai | 2009年12月19日 下午12:56

To terrywang : 請試試下面的範例,看能不能解答你的疑惑。
set ::var 0
::ttk::progressbar .pbr -maximum 100 -variable ::var
::ttk::button .btn -text "go" -command {
set ::var 0
while {$::var < 100} {
incr ::var
update
after 50
}
}
pack .pbr .btn -fill both -expand 1

TerryWang | 2009年12月19日 下午4:12

Hi Dai大...您提供的語法我會使用..但我要尋找的不是這樣..嗚嗚!!

簡單舉例:
我設計了一個Button 叫做update..當我按下update鈕時..開始執行本來
有關update的程式碼之外..而整個update完成的時間假設是50秒..於是將
進度秀在progressbar上

我的想法是在執行update程式碼的同時..帶入一個進度的proc
但不知道如何讓按鈕去判定說..當我按下update時.同時去啟動進度bar

目前只要將processbar加在update原先的程式碼之後..就會發生processbar消失在
畫面上...

dai | 2009年12月19日 下午4:49

有一個前題你要先知道,預設tcl是單一執行緖在跑,所以同一時間永遠只會有1個命令被執行,也就是說如果你的程式忙於某些程式或迴圈,你必需要適當的地方執行update命令,讓tcl有空閒去執行其它事件。我猜你想要的功能比較接近這個程式:

#每0.1秒執行1次
proc pbar_start {} {
incr ::var

after 100 pbar_start
}

proc upload {} {
pbar_start

#====這邊做你的事======
while {$::var < 100} {
update
}
#======================

after cancel pbar_start
}

set ::var 0
::ttk::progressbar .pbr -maximum 100 -variable ::var
::ttk::button .btn -text "go" -command {upload}
pack .pbr .btn -fill both -expand 1

dai | 2009年12月19日 下午4:58

哦,對了!! 如果是我的的話,我會這樣寫:

1.要upload的檔案大小是已知的,假設是100MB
2.所以我會用upload的size來決定pbr的進度,例如:每完成1MB就incr ::var
3.剩餘時間可以用算的,例如:目前已經上傳完2MB,而且花費了5秒,那還剩幾秒的公式如下:
(總上載大小 - 已上載大小 )/已上載大小*目前花費時間
ex.
(100-2)/2*5 就是剩餘時間

TerryWang | 2009年12月19日 下午9:58

感謝D大..不過我要update的檔案大小不會一定..且我要計算的並非上傳時間..而是
更新完包含重開機的時間..我會再根據您的教學試試看!!感謝感謝...

dai | 2009年12月20日 上午12:22

唉呀 ~ 我眼花了,把你的update看成upload @@

對了!! 我程式裡的update是tcl內建的命令,猜想你是知道的。

翊翾 | 2009年12月20日 上午11:41

Dai你好
最近剛學TCL,想寫個小程式,但有點問題
其中有個部分還請幫忙解答一下。

我想做輸入數值
由一個按鈕案判斷數值長度
最後輸出在標籤上

寫法如下
entry .im -textvariable ::show
button .btn -text "Entry" -command {set ::export [string length $::show]}
label .lbl -text $::export

但我按下按鈕之後,程式有計算字串長度
但並不會更新lbl上面的訊息
我也嘗試過label .lbl -textvariable 的用法
不過不知道是我使用錯誤還是怎樣,連顯示都沒有
請Dai能幫我解惑一下嗎? 謝謝

dai | 2009年12月20日 下午1:02

你可以這樣寫:

entry .im -textvariable ::show
button .btn -text "Entry" -command {set ::export [string length $::show]}
label .lbl -textvariable ::export
pack .im .btn .lbl -expand 1 -fill both

或是這樣寫:

entry .im -textvariable ::show
button .btn -text "Entry" -command {.lbl configure -text [string length $::show]}
label .lbl
pack .im .btn .lbl -expand 1 -fill both

翊翾 | 2009年12月20日 下午1:54

原來-textvariable ::export
我寫成-textvariable $::export

沒想到多了$就無法顯示,感謝Dai的解惑呢
那在請問一下
我再一個label中,有辦法做出捲軸的顯示嗎?
因為輸出超過label大小會看不見,還是必須使用entry才能做到?

dai | 2009年12月20日 下午6:22

是的 ~ label沒辦法加上捲軸,如果文字很多的話,我比較常用text顯示。

TerryWang | 2009年12月20日 下午9:34

Dear Dai大..根據您熱心的教學我目前已完成自己需要的部分..接下來想要的是
1. 進度條可否除了進度變化之外..同時顯示百分比呢??

2. 我想要當進度條跑到百分之百時..跳出視窗顯示更新成功..又該如何做到呢?
我有在demo中找到跳出視窗的範例..卻不知道如何寫出判斷進度條跑至百分之百

dai | 2009年12月20日 下午10:00

1.你可以用一個label來顯示目前的百分比,方法是每次你增加pbr目前值的時候,就重新計算百分比,然後設定給label顯示。

2.pbr的最大值是你設定的,它的目前值也是你設定的,所以你只要判斷目前值等於最大值的時候,就知道目前已經是百分之百了。

翊翾 | 2009年12月20日 下午11:07

感謝Dai~現在只是初學者,但此網站讓我學習到甚多技巧
能在短短的時間內,寫出一些基本的程式,感謝囉~

dai | 2009年12月21日 上午11:26

不用客氣,有空多交流 ^ ^

TerryWang | 2009年12月24日 下午5:10

請問D大...ttk語法是否也可以設計出 像activeTCL demo中的tabnotebook

我想使用類似那樣的標籤切換頁面..但覺得demo中的好醜..ttk也有嗎??

dai | 2009年12月24日 下午5:28

試試看ttk::notebook可以滿足你的需求嗎!!

TerryWang | 2009年12月25日 上午9:33

D大...可以給個簡單範例嗎?? 看不太懂ttk:notebook的說明..囧

不好意思...

TerryWang | 2009年12月25日 上午9:59

D大我搞出來了..但目前遇到問題..若我想在頁面tab1中編輯...該如何做呢??

意思就是假設我有tab 1 2 3..分別要在1 2 3中編輯...how to do ??

拜託解惑了??

dai | 2009年12月25日 上午10:44

是指文字編輯嗎? 像這樣 :

ttk::notebook .nb
.nb add [text .nb.t1] -text "tab1"
.nb add [text .nb.t2] -text "tab2"
pack .nb -expand 1 -fill both

聖誕快樂 ^^

TerryWang | 2009年12月25日 上午10:51

.........XD...沒說清楚...我不是要文字..我要在tab中放button entry..一些東西

D大也聖誕快樂^^ 喝喝

dai | 2009年12月25日 上午11:01

那就...改成這樣:

ttk::notebook .nb
.nb add [ttk::frame .nb.f1] -text "frame1"
.nb add [ttk::frame .nb.f2] -text "frame2"
pack .nb -expand 1 -fill both

# 放兩個widget到frame1
ttk::button .nb.f1.btn1 -text "button"
ttk::entry .nb.f1.txt1
pack .nb.f1.btn1 .nb.f1.txt1

TerryWang | 2009年12月25日 上午11:10

我試過了..沒用...我用的是place..有關係嗎??我貼程式碼麻煩D大看一下囉

place [ttk::notebook .nb] -x 0 -y 40
.nb add [frame .nb.f1] -text "TAB1"
.nb add [frame .nb.f2] -text "TAB2"
.nb add [frame .nb.f3] -text "TAB3"
.nb select .nb.f1
ttk::notebook::enableTraversal .nb

ttk::button .nb.f1.btn1 -text "button"
ttk::entry .nb.f1.txt1
place .nb.f1.btn1 -x 100 -y 100 -width 50 -height 50
place .nb.f1.txt1 -x 100 -y 200 -width 200 -height 20

dai | 2009年12月25日 上午11:23

不要緊pack,place,grid都可以用,只要符合階層路徑命名的規則就不會有問題。不過說真的place雖然直覺,但排放的視窗元件變多的時候,就會開始讓你頭痛。比較建議使用pack,grid。如果你有興趣的話可以參考文件的16章,它有說明place,pack,grid的使用方法。

翊翾 | 2009年12月25日 上午11:26

Dai你好,想請問一下
如果我想做另存新檔的功能
那麼選取路徑的視窗是有特殊的語法嗎?

Peter | 2009年12月25日 上午11:36

Dai 您好
剛學tcl
想尋問一下
如果我想作個跑馬燈 例如3個
我是用標籤去製作
目前先產生三個標籤 但後來想去改變三個標籤能夠一直去跑
就會有問題 我沒辦法改變標籤的狀態
請問有沒有什麼方法可以解決?

餅乾 | 2009年12月25日 上午11:46

dai大你好:
假若我想使用exec指令來cat一個linux中的DNS資訊,
但是在抓取的過程中,
一直發生問題,
我的程式如下:
exec cat /etc/resolv.conf
我要抓裡面的nameserver後的IP值,
請問要如何正確抓取?
謝謝。
聖誕快樂

dai | 2009年12月25日 下午12:47

to 翊翾 :

可以使用tk_getSaveFile 命令,例如:

set f [tk_getSaveFile -title "儲存"]
puts $f

聖誕快樂 ^^

dai | 2009年12月25日 下午12:59

to Peter

請試試看這個程式:

package require img::png
set ::icon1 [image create photo -file red.png]
set ::icon2 [image create photo -file green.png]
set ::idx 0

foreach {i} [list 0 1 2] {
ttk::label .lbl$i -compound none -image $::icon1
pack .lbl$i -side left
}
.lbl0 configure -image $::icon2
ttk::button .btn -text "go!!" -command {go}
pack .btn

proc go {} {
.lbl$::idx configure -image $::icon1
set ::idx [expr ($::idx + 1) % 3]
.lbl$::idx configure -image $::icon2
after 1000 go
}

聖誕快樂 ^^

dai | 2009年12月25日 下午1:11

to 餅乾 :

我請學弟回答你的問題 ~ 聖誕快樂 ^^

jky777 | 2009年12月25日 下午1:14

to 餅乾 :

foreach {item} [split [exec cat resolv.conf] "\n"] {
set item [string trim $item]
if {[string index $item 0] == "#"} {continue}
lassign $item serv ip
puts "serv = $serv , ip = $ip"
}

翊翾 | 2009年12月25日 下午1:36

Dai你好,感謝你提供的訊息^^
也祝你聖誕快樂唷~

peter | 2009年12月25日 下午1:43

Dai 您好
我剛執行程式 不能執行
錯在這行
set ::icon1 [image create photo -file red.png]
找不到 red.png

又回過頭去看第17章 去看圖示按鈕
去安裝了Img 在執行 還是同樣的問題
沒辦法解決 我的TCL是8.5版
麻煩您了!

dai | 2009年12月25日 下午2:49

to peter:

因為red.png及green是你要自己準備的圖檔。請隨意找兩張小的圖示檔測試。

特別注意!! 圖示檔要和程式放在同一個資料夾裡,然後在這個資料夾裡啟動程式。

Peter | 2009年12月25日 下午4:48

Dai
剛剛測試 有修改一下
可以跑了 但我是想用標籤寫出來
不過這個方法可以給我參考
非常感謝!

聖誕節快樂 ^^

dai | 2009年12月25日 下午5:03

看來我誤解了,那我們換個方法,是這樣嗎?

set ::bg1 red
set ::bg2 green
set ::idx 0

foreach {i} [list 0 1 2] {
ttk::label .lbl$i -compound none -background $::bg1 -width 2
pack .lbl$i -side left -padx 2
}
.lbl0 configure -background $::bg2
ttk::button .btn -text "go!!" -command {go}
pack .btn

proc go {} {
.lbl$::idx configure -background $::bg1
set ::idx [expr ($::idx + 1) % 3]
.lbl$::idx configure -background $::bg2
after 1000 go
}

Peter | 2009年12月25日 下午5:31

Dai 您好
這個就是我要的
非常感謝!
在這地方真的學到很多 從無到有!

dai | 2009年12月25日 下午6:00

請不用客氣,歡迎常來 ~ 呵呵

翊翾 | 2009年12月26日 下午11:49

Dai你好,最近我想用到dialog的語法
有參考TCL中的Help
他使用到iwidgets::dialog .d
代表之後做的視窗元件只要是.d
就會出現在Dialog的視窗嗎?

那我想用Button呼叫一個Dialog視窗
就如同ezdit中的關於選項,能Show出視窗
Button的command要怎麼下呢?

還是有其他較簡單的寫法,拜託Dai解惑,感恩

dai | 2009年12月27日 上午11:33

嗯~其實我很少在用iwidgets,用標準的tk就可以做到,像這樣:

button .btn -text "Toplevel" -command {
if {![winfo exists .t]} {
toplevel .t
button .t.btn -text "destroy" -command {destroy .t}
pack .t.btn
}
}

pack .btn

翊翾 | 2009年12月28日 上午11:48

Dai你好,Tk的方法簡單許多
感謝提供一個簡單的範例,往後可能還有許多問題
還要多多麻煩囉^^~

dai | 2009年12月28日 下午12:18

別客氣,有空多多交流 ^^

TerryWang | 2009年12月28日 下午7:20

請問D大...若我想要在清單ttk treeview 中的其中一個選項按左鍵或右鍵可以執行指令..該如何做呢??
treeview是否只能view清單而無法內含執行指令..

簡單說就是 一個清單中 我對任一選擇按下右鍵 會跳出一個選單視窗 讓我選擇複製或貼上..類似這樣的功能

dai | 2009年12月28日 下午8:57

這是一個簡單的例子,請研究看看:

ttk::treeview .t
.t insert {} end -text item1
.t insert {} end -text item2
pack .t

bind .t <Button-3> {
catch {destroy .t.m}
menu .t.m -tearoff 0
.t.m add command -label "Copy" -command {puts Copy}
tk_popup .t.m %X %Y
}

TerryWang | 2009年12月29日 上午9:04

感謝D大..我試試看!! WOW...這裡要專門研究TCL了耶...真高興!!

TerryWang | 2009年12月29日 上午9:51

Dear D大我試過了...看來又往前邁進了一步 ^^

目前遇到的問題是D大給的範例是整個tree 按右鍵可選擇copy (=puts XXX)

但我想要的是在tree底下的任一item 選擇右鍵copy時..所輸出的值不一樣

又該如何做呢??

dai | 2009年12月29日 上午10:34

恭喜你功力又進步了,那我可以放心的貼完整版的程式,請看:

proc btn_click {x y X Y} {
catch {destroy .t.m}
set item [.t identify item $x $y]
set state "disabled"
set data ""
if {$item != ""} {
set state "normal"
set data [.t item $item -text]
}
clipboard clear
menu .t.m -tearoff 0
.t.m add command \
-state $state \
-label "Copy" \
-command [list clipboard append $data]
tk_popup .t.m $X $Y
}

ttk::treeview .t
.t insert {} end -text item1
.t insert {} end -text item2
pack .t

bind .t <Button-3> {btn_click %x %y %X %Y}

我剛剛突然發現2009/12/25那天,你問notebook + place的問題我沒有回答 @@ ,補一下...

place [ttk::notebook .nb] -x 0 -y 40 -width 300 -height 300

加上寬和高就可以了。

TerryWang | 2009年12月29日 上午11:03

D大..您留的完整版大致我看的懂意思..但好像不是我想追尋的結果..我要的是

當我選擇item1時..copy按下出現一個我設的值..當我選擇item2時..copy按下出現另一個我設的值

...呵呵關於寬高...我後來也解決了!! 感謝D大關心!!

dai | 2009年12月29日 下午12:02

那就...再來個修正版,這次我把你說的 "出現" 解譯成 "輸出" :

proc btn_click {x y X Y} {
catch {destroy .t.m}
set item [.t identify item $x $y]
set state "disabled"
set data ""
if {$item != ""} {
set state "normal"
set data $::map($item)
}

menu .t.m -tearoff 0
.t.m add command \
-state $state \
-label "Copy $data" \
-command [list puts $data]
tk_popup .t.m $X $Y
}

ttk::treeview .t
set item [.t insert {} end -text item1]
set ::map($item) "Value1"
set item [.t insert {} end -text item2]
set ::map($item) "Value2"
pack .t

bind .t <Button-3> {btn_click %x %y %X %Y}

TerryWang | 2009年12月29日 下午5:48

感謝D大..又往前走了一大步..
請問若我要選擇item2 中的copy這個選項後跳出另一個視窗 裡頭可以做別的事情

例如 放各entry給人輸入...這又該如何做呢??

dai | 2009年12月29日 下午6:35

跳出視窗的例子如下 :

toplevel .t
button .t.btn -text "destroy" -command {destroy .t}
pack .t.btn

你就把這樣子的程式加在menu的-command裡,就可以了。

TerryWang | 2009年12月30日 下午5:31

請問D大...我想設計一個search的entry..當我輸入要尋找的資訊時自動幫我開啟ie並連線到google搜尋..請問該如何做??就像某些瀏覽器一樣..有search bar..當你在search bar填入要找的資料時...自動連線到goole尋找相關的資料!!

dai | 2009年12月30日 下午9:39

大概類似這樣:

注意!! url encoding 要自己處理。

entry .txt -textvariable ::txt
bind .txt <Return> {
set url "http://www.google.com.tw/search?hl=zh-TW&source=hp&q=${::txt}&btnG=Google+%E6%90%9C%E5%B0%8B&meta=&aq=f&oq="
exec "C:/Program Files/Internet Explorer/iexplore.exe" $url &
}
pack .txt

TerryWang | 2009年12月31日 上午10:16

哈囉..D大早安..先祝你今晚跨年快樂 ^^

想問一下..我想在treeview中做出ctrl+f 的尋找功能..請問該如何做呢??

dai | 2009年12月31日 下午12:22

這需要把treeview元件bind一個ctrl+f的事件,大概像這樣:

bind .tv <Control-f> {
if {![winfo exists .win]} {
toplevel .win
entry .win.txt -textvariable ::txt
pack .win.txt
}
}

dai | 2009年12月31日 下午12:23

預祝你新年快樂 ^^

翊翾 | 2010年1月6日 上午9:39

Dai你好^^
想請問一下如果我做一個文字視窗程式如下
set mes [text .list -yscroll .list.yscroll set" -xscroll "list.xscroll set"]
ttk::scrollbar .list.yscroll -command ".list yview"
ttk::scrollbar .list.xscroll -orient horizontal -command ".list xview"

放好以下的位置
pack .list -fill both -expand 1
pack .list.xscroll -side bottom -fill x
pack .list.yscroll -side right -fill y

要把文字內容放進去時
$mes insert end "I am IShung"

我的想法是把捲軸放在.list裡面,不知道是不是這樣做
因為上面的方法沒有辦法正常工作所以想請問一下我的順序或者路徑是否定義有錯

翊翾 | 2010年1月6日 上午9:52

Dai你好 我嘗試修改你的範例
set mes [text .list]
set sh [::ttk::scrollbar .sh -orient horizontal -command [list $mes xview]]
set sv [::ttk::scrollbar .sv -orient vertical -command [list $mes yview]]
$mes configure -yscrollcommand [list $sv set]
$mes configure -xscrollcommand [list $sh set]
grid $mes $sv -sticky "news"
grid $mes $sh -sticky "news"
grid rowconfigure . 0 -weight 1
grid columnconfigure . 0 -weight 1
$mes insert end "I am IShung !!!"
$mes delete end

但如果我想要x軸的捲軸可以使用 不要自動換行 要加上其他指令嗎?
還有插入刪除的指令有時候有0.0 $mes delete 0.0 end
士什麼意思呢? 不好意思 每次來問題都有點多

dai | 2010年1月6日 上午10:35

只要建立text的時候加上-wrap選項就可以了,像這樣:

set mes [text .list -wrap none]


然後 $mes delete 1.0 end 的意思是:刪除文字方塊($mes)第1行第0個位置到最後一個位置的內容。

別客氣歡迎常來交流^^

翊翾 | 2010年1月6日 下午3:51

Dai你好,我又有新問題了^^||
是關於元件排列的方式,如果我想做一個text在一個視窗的右上角
其他的地方是空白的,如果用place可以輕易做到
但我使用pack 中的-anchor ne沒有什麼改變
有嘗試用grid 想把text擺在一個3*3的空間中的0,1位置 再把它拉寬到左上
不過都沒有成功,不知道Dai有什麼好的建議呢?

dai | 2010年1月6日 下午8:35

請試試下面的範例:

text .t -width 5 -height 5 -relief groove -bd 2
pack .t -anchor ne
wm geometry . 100x100+0+0

Peter | 2010年1月7日 上午11:22

Dai 您好
現在嘗試作一個介面,
目前想把滑鼠移動到某一個地方(例如按鈕)
它便會跳出一個簡短的說明視窗或者去告訴使用者
這個按鈕是在作什麼的

我試用過bind這個指令
但最多只能多做一個固定標籤顯示在標籤上
但我不想做這個標籤 想跳過這一步
我想讓使用者直接在滑鼠下面有個說明視窗
直接告訴使用者
這個問題困擾我ㄧ個上午了。。

感謝回答

dai | 2010年1月7日 下午1:22

hi你好
這個功能有現成的套件可以用叫 tooltip 用法像這樣 :

package require tooltip

button .btn -text "hello" -command {exit}
::tooltip::tooltip .btn "說明文字"
pack .btn

Peter | 2010年1月7日 下午1:42

Dai 您好
非常感謝
就是要這種
方便多了!!

翊翾 | 2010年1月8日 下午5:27

Dai你好
想請問一下,如果我寫好一支程式
但會source到其他檔案,或者是圖檔
我想把它包成一個exe檔
就像是Dai做的編輯器一樣,請問我需要什麼程式嗎?
因為我目前找到的只能單純包一個tcl檔
麻煩Dai推薦一下~

dai | 2010年1月8日 下午6:23

首先你要把整個程式專案會用到的圖檔、文檔及其它檔案放在同一個資料夾裡面:類似這樣:

project \ (專案資料夾)
---------- main.tcl (主程式)
---------- images \ (用來放圖檔的資料夾)
---------------------- a.png (測試用的圖檔)
---------- lib \ (用來放library的資料夾)
---------------------- img1.3 (因為我用到png所以我把img1.3套件放一份在這邊)

ps.主程式一定要命令main.tcl

這邊的重點在於main.tcl裡載入a.png的檔案路徑還有lib的路徑必需是動態決定的,請看我的範例程式:

# info script 會回傳目前正在執行程式的檔案路徑
# 然後透過 file normalize 確保檔案路徑中的 . 及 .. 會被處理掉
set appPath [file normalize [info script]]
# 如果目前的程式檔是透過連結啟動的,就讀取連結的目標
if {[file type $appPath] == "link"} {set appPath [file readlink $appPath]}
# 如果是在tclkit裡appPath要多退一層
if {[namespace exists ::vfs]} {set appPath [file dirname $appPath]}

# Ok! $appPath 就是我們要的檔案路徑了
puts $appPath

#把project\lib的路徑加入 ::auto_path
lappend ::auto_path [file join $appPath lib]

package require Tk
package require img::png ;#它會去project\lib裡引入img套件

button .btn -text "Hello" -image [image create photo -file [file join $appPath images a.png]]
pack .btn

這些都準備好了以後,就可以用tclkit及sdx來打包了:

$ tclkit.exe sdx.kit wrap project.exe -vfs project -runtime tclkit2.exe

注意!! 你要在存放專案(project)的資料夾執行上面的命令,然後tclkit2.exe是tclkit.exe的複本。

關於tclkit及sdx的資訊請參考這裡還有這裡

翊翾 | 2010年1月11日 下午1:02

感謝Dai,我會先嘗試著你的方法試過一次的
感謝這麼詳盡的教學^^~

翊翾 | 2010年1月18日 下午3:25

Dai你好^^~ 有個問題想請教一下
如果我在鍵盤按下某個按鍵
我希望他會發出聲音 直到我的手離開按鍵
我的寫法是
bind . {
twapi::beep -duration 5000
}
bind . {
twapi::stop_sound
}
但TCL他一定會執行完beep聲
不知道有什麼方法試可以我按下發聲鬆開就中斷呢?

dai | 2010年1月18日 下午9:49

用這樣的方法可以嗎?

package require twapi

proc beep {} {
if {$::flag == 0} {return}
twapi::beep
after 100 beep
}

bind . <ButtonPress-1> {
set ::flag 1
after 100 beep
}
bind . <ButtonRelease-1> {
set ::flag 0
}

翊翾 | 2010年1月19日 上午9:03

Dai你好^^
我試過上面的方法,不過可能是我說的不夠詳細所以讓你有點誤解
如果我打算寫一個類似音樂鍵盤的程式
那我按下A按鍵,聲音會持續不斷直到我鬆開A的按鍵

現在在Bind中或副程式中
她總是會執行一段聲音完再跳出
有辦法寫成中斷她的模式嗎?

dai | 2010年1月19日 上午11:53

如果是這樣子的話~~你可能會需要用到thread
邏輯是這樣子的:
1.用一個thread來服務聲音
2.當你press某一個鍵就送一個訊息給服務聲音的thread通知開始播放
3.當你release剛剛的按鍵就送一個訊息給服務聲音的thread通知結束播放

其實用上一個程式去修改也辦得到
邏輯是這樣的:
1.當你press某一個鍵就啟動某一個聲音檔的播放(這個聲音檔要夠長)
2.然後你透過after啟動某一個程序不斷的檢查按鍵是否放開
3.如果放開的話就停止聲音的播放

dai | 2010年1月19日 上午11:55

補充一下 ~ 你可能需要用snack這樣的播放功能,而不能使用twapi::beep -duration 5000這樣的方式。

Peter | 2010年1月20日 下午2:19

Dai 您好
目前遇到兩個問題

問題1
嘗試做兩台電腦互連 A電腦(server) B電腦(client)
條件(1) 在知道對方IP情況下
條件(2) 我可以任意更改B電腦設定下 (已關防火牆)

我要怎麼做送一個封包或者信息
讓B電腦能夠跳出一個視窗或者物件 (有點類似MSN)
讓B電腦的使用者知道A電腦正在與它互通
方便我以後做出物件來連線之類的東西

問題2
有一篇文章存在變數(簡稱var)中
gets沒辦法一次讀取這個var的一行
目前的方法是 將var存入txt檔
在讀取txt檔 才能使用gets
請問有沒有什麼好方法
能避開開讀檔的動作 而直接抓取var的一行

dai | 2010年1月20日 下午3:07

hi
關於問題2。如果var裡儲存了一堆文字+斷行,你可以用下面的方法一次處理一行。

foreach line [split $var "\n"] {
puts $line
}

注意!! gets 只能用來讀channel不能用來讀變數內容。

關於問題1。我想你應用要寫socket吧!!請參考下面的文章

http://wiki.tcl.tk/15315

這篇文章示範了最簡單的client/server兩端的socket程式。

Peter | 2010年1月20日 下午3:45

Dai 您好
關於問題一 就是需要使用socket
目前還在看這相關的文章
因為TCL很適合用在開發網路相關的
我會先看您推薦的 到時有問題在向您請教

問題二
感謝您的回答讓我程式能縮短很多行
而執行效率也比較高

dai | 2010年1月20日 下午5:33

hi Peter

不用客氣~歡迎常來交流 ^^

sam | 2010年1月25日 下午6:02

Hi Dai:
我把tclkit加入big5繁體字型,然後試著編了一個Dai大大的例子如下(example.tcl):

set ::val 0
::ttk::progressbar .pbr -maximum 100 -mode determinate -variable ::val
button .btn -text "按一下加 5" -command {incr ::val 5}
pack .pbr .btn -expand 1 -fill both

然後打包:
sdx gwrap example.tcl -runtime tclkit-gui-854.big5.exe
註:tclkit-gui-854.big5.exe為已加入big5的tclkit.exe

打包完會產生出"example"這個檔案(不明的檔案類型無法直接點二下執行),若直接在命令提示字元輸入"example"這個檔案名稱,程式與繁體中文可正常的執行與顯示,若我將其改名為"example.exe"再執行就會發生錯誤,應該是無法判別繁中的訊息。
但是奇怪的是,我把"按一下加 5" 改成 "Add 5"後,產生出的"example",再改名為"example.exe",雙擊這個檔案可正常執行,想請問Dai大大是否知道是哪裡出了問題?
謝謝~

sam | 2010年1月25日 下午6:11

補充一下:

若我把"按一下加 5" 改成 "按一下加五",
然後把打包完產生的example改成"example.exe",
則是可以執行,但是文字變成亂碼了~

dai | 2010年1月25日 下午7:37

hi sam

我猜你用點兩下的方式啟動tclkit-gui-854.big5.exe並不是跑在big5下,你可以試試看點兩下執行tclkit-gui-854.big5.exe然後在互動模式下輸入:

puts [encoding system]

先確定你包的tclkit預設是跑在big5的模式下。如果不是跑在big5下你可以試試下面的方法:

step1.先建立一個資料夾 "example"
step2.把你的example.tcl放在裡面
step3.在example裡建立一個main.tcl內容如下:

set appPath [file normalize [info script]]
if {[file type $appPath] eq "link"} {set appPath [file readlink $appPath]}
set appPath [file dirname $appPath]
source -encoding big5 [file join $appPath example.tcl]

step4.打包執行檔

sdx wrap example.exe -vfs example -runtime tclkit-gui-854.big5.exe

這樣包出來的執行檔應該就沒問題了。

TerryWang | 2010年2月3日 下午4:48

請問D大..我想在menu bar製作全選.複製.貼上的功能

請問該如何做呢?

青怡 | 2010年2月3日 下午5:47

作者已經移除這則留言。

sam | 2010年2月3日 下午5:54

Hi Dai:
請問一下,我有看到一段有關tcl特色的敘述,內文為"可內嵌(embed)到應用程式中,讓軟體使用者透過程式員提供的高階 TCL 指令,自訂應用程式的行為",這一句我有點不太懂,所謂的應用程式是指自已開發的VB GUI或其它程式的GUI,還是指一般的Word、Excel應用程式? 而我爬文也有看到有些人有問到如何將tk embed into applications中? 或是指tcl/c與tcl/c++,embed? 小的我才疏學淺有點不太明白,有請Dai大大開示,謝謝Dai大大。

IShung | 2010年2月3日 下午7:29

哈囉Dai好久沒來請益了
這次是關於text裡面的問題
Ex :
$::mes tag configure title -font "Arial 15 bold" -foreground #345803
$::mes insert end "Hello" title
$::mes insert end "How are you" title
現在我的文字已經變成我想要的字型
當我滑鼠移過去Hello的時候我希望背景會變色
$::mes tag bind D1 "$::mes tag configure D1 -background {} -relief flat"
$::mes tag bind D1 "$::mes tag configure D1 -background #ffb9b9 -relief flat"
$::mes tag configure D1 -background {} -font "Arial 11 bold" -foreground #34382c -relief flat
我要怎麼把D1套用到Hello上面去呢?

還是有什麼其他的方法呢?

dai | 2010年2月3日 下午9:44

Hi TerryWang 請參考這個範例:

menu .mbar -type menubar
menu .mbar.edit

.mbar add cascade -label "Edit" -menu .mbar.edit

.mbar.edit add command -label "Select all" -command {.txt tag add sel 1.0 end}
.mbar.edit add command -label "Cut" -command {tk_textCut .txt}
.mbar.edit add command -label "Paste" -command {tk_textPaste .txt}

pack [text .txt] -expand 1 -fill both
. configure -menu .mbar

bind Text <Control-a> {}
bind .txt <Control-a> {.txt tag add sel 1.0 end}

dai | 2010年2月3日 下午10:02

Hi sam,
個人對"容易內嵌"的解釋是「開發應用程式的人,可以很容易在自己熟悉的言語,使用Tcl的直譯器」。例如:你可以寫一個c/c++的程式,引入tcl.h建立Tcl interpreter或是Tcl App,這樣你就可以使用像DString或是Hash、Channel等更高階的C API,甚至是在你的程式裡執行更高階的Tcl Script。 相信~這樣的開發模型你應該很熟才對。

dai | 2010年2月3日 下午10:13

Hi IShung 請試試下面的範例 ~
text .txt

.txt tag configure title -foreground blue
.txt insert end "Hello" title
.txt insert end "\n"
.txt insert end "Hi" title

.txt tag bind cmd <Button-1> {puts Hello}

foreach {idx1 idx2} [.txt tag ranges title] {
set t [.txt get $idx1 $idx2]
if {$t == "Hello"} {.txt tag add cmd $idx1 $idx2}
}

pack .txt

有空常來交流哦 ^ ^

翊翾 | 2010年2月4日 下午1:30

哈囉Dai~
我想我表達的能力有點問題造成你的誤解
目前我想寫出一個程式如下(參照你給的範例)
text .txt

.txt tag configure title -font "Arial 15 bold" -foreground #345803
.txt insert end "Hello" title
.txt insert end "\n"
.txt insert end "Hi,Dai." D1

.txt tag bind D1 ".txt tag configure D1 -background {} -relief flat "
.txt tag bind D1 ".txt tag configure D1 -background #ffb9b9 -relief flat "
.txt tag configure D1 -background {} -relief flat
pack .txt

如果當我的滑鼠移到Hi,Dai.的文字上就會改變成粉紅色的背景
那我現在的問題是,我把D1這個設定套用上去
那我就不能在套用title的設定
Ex : .txt insert end "Hello" title D1
有什麼辦法可以既設定title之後再設定D1呢?

dai | 2010年2月4日 下午2:52

翊翾你的意思是指 "Hello" 現在用

.txt insert end "Hello" title

套用了title這個tag

但你想在程式的執行過程中再把 D1 再套用在 "Hello" 上,也就是讓Hello同時套用上title及D1.

你想表達的是這樣子嗎? 如果是的話,上一個範例就是做這件事。我把它改一下,看你會不會比較好接受.

text .txt

.txt tag configure title -foreground blue
.txt insert end "Hello" title
.txt insert end "\n"
.txt insert end "Hi" D1

.txt tag bind D1 <Button-1> {puts Hello}

# 以下把title套用到 "Hi"
# 所以結果是Hi會套用title及D1
foreach {idx1 idx2} [.txt tag ranges D1] {
set t [.txt get $idx1 $idx2]
if {$t == "Hi"} {.txt tag add title $idx1 $idx2}
}

pack .txt

翊翾 | 2010年2月5日 下午1:15

^^~Dai你好呀~
原來我誤解了你的意思,我已經成功運用你的範例
成功套用在我自己寫的小程式裡面了,又多學了一條指令(笑)

dai | 2010年2月6日 上午2:47

其實我也滿怕會錯意的 @@ ~

sam | 2010年2月12日 上午8:56

Hi Dai

不要緊張,沒什麼問題,只是祝Dai大大新年快樂,
另外,謝謝Dai大大給我在TCL上面很大的幫忙,

祝大家在新的一年都虎虎生風,科科。

匿名 | 2010年2月12日 下午2:41

Dear:
祝您新年快樂,希望今年有更好的資訊可以分享出來!!
也祝您心想事成,早日達成目標0.0

匿名 | 2010年2月12日 下午2:43

希望今年有更好的資訊可以分享出來!!


寫錯了~是更多


殘唸>///<

dai | 2010年2月12日 下午4:55

謝謝大家~~也祝你們新年快樂,事事如意~~~

sam | 2010年2月24日 下午6:04

Hi Dai
有個Thread的問題想請教你,如下例程式:

while {1} {
set t [thread::create]
thread::send $t { "tcl的程式" }
#thread::release $t
}

想請問Dai大大,要如何讓thread $t執行完就自行結束呢,
不知為何我這樣子的寫法,當執行完"tcl的程式"後,thread不會自已結束,
若用thread::release $t的話,感覺會release到其它的thread,
想請問Dai大大,有沒有比較好解決的方法,謝謝。

dai | 2010年2月24日 下午8:28

你的程式應該是對的不會有問題 ~ 除非"tcl的程式"裡面有無窮迴圈。下面是另一種寫法


set t [thread::create]
thread::send $t {
....
thread::exit 或是 thread::release
....
}

sam | 2010年2月26日 下午3:13

Hi Dai
我找到原因了,改成Asynchronous Message Sending(-async)好像就OK了,
想請問Dai大大另一個Thread的問題,
不知道Dai大大有沒有用過TCL的DDE(Dynamic Data Exchange),

程式一:可正常執行版
----------------------------
package require dde
package require Thread

proc OnIO {} {
 dde execute "DDE要傳送資料的程式"
}

OnIO
----------------------------



程式二:錯誤訊息發生 "dde command failed"
--------------------------------------------------------
package require Thread

set t [thread::create]
thread::send -async $t {
  package require dde
  proc OnIO {} {
   dde execute "DDE要傳送資料的程式"
  }
  OnIO

--------------------------------------------------------

不知為何把dde包在thread裡會發生錯誤,
另外想請問,在新建立的Thread中有辦法執行在Main Thread所執行程式中的Proc OnIO嗎
我孤狗都孤不出來…
謝謝…

dai | 2010年2月26日 下午4:48

DDE...很久以前在玩PLC的圖控軟體常用到,其實現在CrowAMP裡也有使用啦 呵呵!!

我用ActiveTcl 8.6b2 先執行

===== b.tcl ======

package require dde

proc ::dde_handler {args} {puts $args}
dde servername -handler ::dde_handler MyTopic

再執行

===== a.tcl ======

package require Thread

set t [thread::create]
thread::send -async $t {
package require Thread
package require dde

proc OnIO {} {
dde execute TclEval MyTopic "Data"
}
OnIO
thread::release
}

一切正常~~~

在slave thread呼叫main thread的proc可以這樣:

package require Thread

proc ::bb {} {puts abc}

set t [thread::create]
thread::send $t [list set ::mainTid [thread::id]]

thread::send -async $t {
package require Thread
thread::send $::mainTid [list ::bb]
thread::release
}

重點在要把main thread的ID送到slave thread,這樣slave thread就可以和main thread通訊。

sam | 2010年3月1日 下午12:01

Hi Dai:

謝謝你的詳細回答,
我把我的問題簡化成一個下面無窮迴圈的例子,

------------------------------------
package require Thread
package require dde

while {1} {

 set t [thread::create]
 thread::send -async $t {
   package require Thread
   package require dde
   dde execute iexplore WWW_OpenURL "C:/a.html"
 }

}
------------------------------------


不知為何會產生如下例的會誤訊息
Error from thread tid00000E04
dde command failed
while executing
"dde execute iexplore WWW_OpenURL "C:/a.html""

我看有關TCL Thread的文章有提到,建立一個新的Thread同等於建立一個新的TCL直譯器,
而我在新建立的Thread中,也把dde與thread包進去了,但為什麼還會發生錯誤呢?

sam | 2010年3月1日 下午1:34

Hi Dai:

我發現好像是迴圈的問題ㄟ

-----------------------
package require Thread

for {set i 1} {$i <= 1} {incr i} {

 set t [thread::create]
 thread::send -async $t {
   package require dde
   set DStream [dde request VB_Server VB_Server_Topic label1]
   #上面的指令為抓VB label1的值
   puts $DStream
   thread::release
 }
}
-----------------------

若把 for {set i 1} {$i <= 1} {incr i} {
改成 for {set i 1} {$i <= 2} {incr i} {

則會成功的印出第一次,第二次就會出現錯誤如下:
0 --------------------------------->for迴圈第一次印出
Error from thread tid00002168   ----->for迴圈第二次出錯
dde command failed
while executing
"dde request VB_Server VB_Server_Topic label1"
invoked from within
"set DStream [dde request VB_Server VB_Server_Topic label1]"

小的目前是有找到好像是這個原因,不過還沒想出解決的方法...

dai | 2010年3月1日 下午10:46

嗯 ~ 這應該不是迴圈的問題,用dde比較好的方式是都由 某個 thread 統一處理,若有兩個thread同時使用dde會出現問題,請看我的範例 ~

我很久不寫VB了, 所以請先用execl開啟一個Book1.xls,然後在 Sheet1 : A1 隨意輸入一些內容. 然後執行下面的程式:

package require Thread
package require dde

proc ::dde_request {} {
puts [dde request EXCEL Book1 R1C1]
}

for {set i 1} {$i <=2} {incr i} {
set t [thread::create]
thread::send $t [list set ::tid [thread::id]]

thread::send -async $t {
package require Thread

thread::send $::tid ::dde_request

thread::release

}

}

統一由main thread處理就不會出現問題了。

sam | 2010年3月2日 下午5:40

Hi Dai:

我改寫我的程式已經把問題解決了,
卡了一陣子一直找不出原因,原來是dde不支援Multi-Thread,
很保貴的經驗,謝謝Dai的幫忙。

dai | 2010年3月3日 下午4:25

呵~別客氣 ^ ^

翊翾 | 2010年3月11日 下午4:52

哈囉Dai~
好久都沒什麼碰程式,今天心血來潮想寫一個可以跳出日曆視窗
然後點選上面日期puts出來

有找到一個語法
package require widget::calendar
widget::calendar .t
pack .t -fill x -expand 1

但試了半天,就是沒有辦法把選到的日期存進某變數或者是印出來
可以幫我看一下嗎^^?

dai | 2010年3月11日 下午8:59

來~請看下面的範例:

package require widget::calendar
widget::calendar .t -textvariable ::tt
pack .t -fill x -expand 1
button .btn -text "hello" -command {puts $::tt}
pack .btn -fill x -expand 1

翊翾 | 2010年3月12日 上午10:53

Dai你好^^~
我現在想寫成這樣的功能
package require widget::calendar
ttk::entry .en -textvariable ::date
ttk::button .btn -text "Date" -command {cal}
proc cal {} {
if {![winfo exists .cal_date]} {
toplevel .cal_date
wm title .cal_date "Select init date"
wm deiconify .cal_date
widget::calendar .cal_date.t -textvariable ::date
pack .cal_date.t -fill x -expand 1
bind .cal_date <1> {destroy .cal_date}
}
}

但是我一點日期結束視窗的時候都會出現以下錯誤訊息
namespace "::widget::calendar::Snit_inst3" not found
namespace "::widget::calendar::Snit_inst3" not found
while executing
"namespace upvar $selfns Snit_instance self"
(procedure "::snit::RT.CallInstance" line 2)
invoked from within
"::snit::RT.CallInstance ::widget::calendar::Snit_inst3 Refresh"
("after" script)

請問是我程式寫法有問題嗎?

dai | 2010年3月12日 下午12:39

嗯 ~ 這是因為時間差所引起的問題,把倒數第3行改成:

bind .cal_date <1> {after idle [list destroy .cal_date]}


就可以了

翊翾 | 2010年3月12日 下午1:18

哇@@||| 所以是因為我太快刪除視窗所導致的錯誤阿
感謝Dai呢,不過滿好奇的是Dai都有遇過類似的問題嗎?
像我們比較沒經驗的話,有什麼能力可以自己Debug呢~

dai | 2010年3月12日 下午1:46

嗯!! 我有遇到類似的問題 ~

其實很多時候我也都是用嘗試錯誤法來Debug - 多想、多試、不斷的排除可能的錯誤,然後猜測可能的原因。 這個方法可能有點笨拙,不過應該是滿普遍的做法,不管是初學者或是老手都適用。初學者和老手的差異應該只是老手猜得比較快,比較準。因為老手猜多了有經驗嘛 ~

我想你知道的Debug的能力,是要靠時間累積的。這是程式工程式最有價值的能力之一,也是最不容易被取代的能力。

加油!!

lbboy | 2010年3月12日 下午9:16

請問剛有問一個 有關 read excel file的 並打包成單一 kit file的問題
有成功的發布嗎
謝謝

lbboy | 2010年3月12日 下午9:21

我有一個tcl 用來read excel file的內容 並put out 出來

但是 將它用tclkit sdx.kit wrap -vfs 成kit file 後
用tclkit 去執行 但是沒有output 出東西
與tclsh 版本有關嗎
請問這是什麼問題呢 要怎樣才能成功的將 含有tcom package的tcl file 包成單一file呢
謝謝

翊翾 | 2010年3月13日 下午3:19

Dai你好^^
感謝你的建議,那希望能在你這邊多吸收到一點你們有經驗人的經驗呢
既然都來了就再問一個問題吧XD

我之前有用過tablelist的語法
例如我叫出另外一個視窗
並把tablelist放在一個labelframe中
ttk::labelframe .win.f1
tablelist::tablelist .win.f1.table
這時候我用bind 想藉由滑鼠做一些判斷
bind .win.f1.table <1> {.....}
我認為這樣是沒有錯的~
但是實際執行bind是無作用的
必須把路徑改成 bind .win <1> {......}
這樣才會有作用~不知道Dai有沒有遇過這問題能幫我解決呢?

dai | 2010年3月13日 下午3:55

hi lbboy

你可以先在命令模式下,執行你包好的starpack,然後看有沒有錯誤訊息會跑出來 ~ 如果有的話就比較好辦,你可以把錯誤訊息貼出來我們可以一起討論

dai | 2010年3月13日 下午4:05

hi 翊翾

你binding的目標弄錯了,改成下面這樣就ok

bind [.win.f1.table bodypath] <1> {puts 1}

Peter | 2010年3月15日 上午11:53

Dai 您好:
很久沒來請安了....
最近我想做有關控制滑鼠問題,但遇到一些瓶頸,
想請問你一些問題,我有去wiki.tcl網站看過,網
路上的cursor的語法都沒看到我想要的,想問一下:
不曉得你有沒有這方面類似的經驗?

(1)怎麼樣隱藏滑鼠及開啟滑鼠(看wiki那些只是把cursor變個圖像並不是我想要的)
(2)怎麼樣在執行tcl後,可以跑回上一個頁面(此頁面可能是網頁,撥放器或其它)執行!
(3)或者提供有關這邊類似的網站供我參考

感激不盡 ^^

dai | 2010年3月15日 下午12:31

hi Peter

請安.... @@

1.隱藏滑鼠,我只有這樣用過

text .txt -wrap none -cursor none
button .btn -text "show" -command {.txt configure -cursor ""}
pack .txt .btn

在.txt上游標會隱藏

2.你指的是把某個應用程式的視窗,內嵌在Tk上嗎? 請參考 optcl

Peter | 2010年3月15日 下午5:58

Dai 您好:
關於第一個問題跟我之前找的一樣,我是用8.4,
但這語法在8.5才跑的動,我不曉得如果拿8.5的tk檔,
覆蓋8.4之後會有啥影響?
第二個問題是假設我先開啟一個視窗(例如mp3撥放器),
當我想對mp3作定時功能或案停止鍵,我怎麼利用tcl來
控制在執行tcl之後,能夠跳回上一個視窗(mp3撥放器),
去執行部分功能?

目前只想到
<1>tcl執行後,把tcl視窗縮到最小!
<2>記住cursor絕對位置,在進行控制!
但我覺得這方法比較笨一點,是否有其他方法,
想了解一下~~

dai | 2010年3月15日 下午11:14

Peter您好:

嗯~看起來好像是你想用tcl的程式來控制外部程式(mp3 player) ~ 除了你說的方法之外,我常用的方法有:

1. 開pipe去控制mp3 player,有些mp3 player允許你從command line啟動並控制。


2. 用twapi套件,twapi可以讓你傳送鍵盤上的key或是字串到某一個應用程式,如果你要控制的外部程式有快速鍵,那你就send一組快速鍵過去,就可以達到控制的功能。當然twapi也有模擬滑鼠點擊的功能。

lbboy | 2010年3月16日 下午4:53

hi Dai
我在windows的環境試starpack
tcl中有tk button 也有puts command
可是在用tclkit-win32.upx.exe 執行.kit時只會show視窗
但沒有看到puts out 的message
請問要怎麼樣才能show出message呢

2.
另外我用spectcl 寫gui,會產生兩個file, app.tcl/app_ui.tcl
想用starkit 包成一個檔案,可是只會show出空白視窗,沒有看到error message
請問一下 有哪些步驟需要做 才能成功的generate出starkit呢

thanks

dai | 2010年3月16日 下午5:49

嗯~你可以試試看在程式的最前面加入下方的兩行,這樣應該就可以看到錯誤訊息了

console show
update

Peter | 2010年3月16日 下午7:00

Dai 您好:
我會去試看看的,感謝您的回應,
我並不想去弄mp3 player @@
那只是舉個例子,主要目地還是用程式
來控制我常常去作,但又覺得厭煩的東西...

lbboy | 2010年3月17日 上午10:33

hi dai
已經可以看到message了 謝謝

另外我在windows工作管理員的處理程序中
會看到很多的tclkit.exe
請問是否是程式沒有關乾淨呢!! 怎樣才能不要殘留這些程序在記憶體呢
thanks

dai | 2010年3月17日 上午11:57

hi lbboy

可能是程式關閉的過程中當掉的關系

這只能靠你自己把程式修好了

加油把問題找出來吧!!

lbboy | 2010年3月17日 下午10:29

我發現好像是使用 tclkit sdx.kit 結束後會留下tclkit.exe 程序在記憶體中,不知道這是否正常

另外 我想請問 tcl 寫的程式是否可以被其他的語言(language)所呼叫(call)
比如說用c language寫的程式,要如何利用tcl寫的procedule
如果不同語言 彼此可以利用 這將會很方便的
謝謝

Peter | 2010年3月17日 下午11:03

Dai 您好:
這陣子又在作新的東西,利用TCL在控制印表機
不過我測試都可以成功,但加上了有關圖形介面後
package require tile tk Iwidgets
感覺是這幾個的關係,都必須關掉圖形介面才能印出東西
想請問有沒有辦法同時並存圖形介面,並印出我想要的東西呢?

dai | 2010年3月18日 上午10:32

hi lbboy,

你是在視窗的右上角打x來關閉sdx嗎? 你試看看在console裡打exit,說不定就不會了。

dai | 2010年3月18日 上午10:34

hi Peter,

我大部份的情況都是在有圖形介面的情況下列印,都沒有遇到問題,我滿好奇你列印的方法?

Peter | 2010年3月18日 上午10:48

Dai 您好:
我是用Zebra系列的,在TCL介面下command ZPL II
結果我發現在有圖形介面時,所send的值只有到一半,
使ZPL語法無法完全傳到印表機列印,必需關調圖形介面才可以,
今天才想到一個方法,利用server/client方式,server(有圖形介面)
clinet(無圖形介面),當server呼叫client去執行,測試可以成功,

但我還是想在原本有圖形介面去控制印表機~~~

sam | 2010年3月18日 上午11:27

Hi lbboy:

你應該是想要用C去呼叫Tcl的程序吧,不過我不知你要的是哪一種作法,

第一種:在同一個程式開發軟體中撰寫C與TCL
作法:可以試著去把TCL Embed into C中,然後經由Tcl C App來作為二者間的溝通橋樑。

第二種:執行期間的溝通(例如c.exe呼叫tcl.exe中的程序)
作法:可以使用Dynamic Data Exchange(DDE)的方法,前提是你的程式開發軟體有支援DDE。

上面是一些作法,雖然可能不是最好,不過你可以參考看看。

dai | 2010年3月18日 下午6:08

謝謝sam提供的方法,希望你可以常常來給Tcl新手提供你的經驗 ~~

sam其實我早上醒來時看到lbboy的留言,還想說要不要請你幫忙回答的,因為你之前好像有研究這一塊,沒想到上來你就回答了哈哈!!

lbboy 我也來提供兩種方法:

1.從C呼叫Tcl script裡的程序
作法:你可以在C裡include "tcl.h",這樣你就可以使用Tcl提供的C API,在Tcl C API裡,你可以建立Tcl的直譯器,然後用這個直譯器來執行script level的程序。

2.從Tcl script裡呼叫C寫的函數
作法:Tcl有標準的方法,可以讓你呼叫C寫的函數,但前提是你得把C寫的函數包裝成Tcl script可以載入的dll或so檔。請參考這篇文章 :

Hello World as a C extension

dai | 2010年3月18日 下午6:21

hi Peter,

ZPL我沒有用過也,所以....


dai

Peter | 2010年3月20日 上午9:31

Dai 您好:
我已解決我想要問的問題了,理論上我的程式沒問題,
是印表機預設的baud rate太小,造成我的data沒辦
法即時送達,所以讓我誤判沒有輸出,事後我把印表
機調整到最高,跟我的程式在預設跟印表機同步,就
可以列印了。

dai | 2010年3月20日 下午11:12

原來是這樣 ~ 恭喜你成功了 ^o^

翊翾 | 2010年3月21日 上午11:19

哈囉Dai
原來還有這種用法bodypath
以前都不知道怎麼用,又多學了一招呢

順便再來問個問題^^ 我的問題源源不絕呢XD
我現在想寫一個介面,填入一些值之後會寫入到Excel中
現在我已經可以成功寫進去Excel部分,但不知道為什麼就是無法儲存到我想要的路徑
例如:
package require tcom
set application [::tcom::ref createobject "Excel.Application"]
$application Visible 1
set workbooks [$application Workbooks]
$workbooks Name Number
這裡顯示interface Workbooks does not have method or property Name

set workbook [$workbooks Add]
$workbook SaveAs "C:/ Number"
這裡顯示0x800a03ec {Microsoft Office Excel 無法存取檔案 'C:\//93DB4120'。可能原因如下:
‧檔案的名稱或路徑不存在。
‧這個檔案正被其他程式所使用中。
‧您要儲存的活頁簿名稱與現有開啟的活頁簿名稱相同。}
但以前曾經寫過是OK的,不知道是哪裡出問題呢@@|||

sam | 2010年3月22日 下午5:44

Hi 翊翾:

下面這個例子,你貼到Ezdit try try看...
--------------------------------------------------------------------
package require tcom

set application [::tcom::ref createobject "Excel.Application"]
$application Visible 1

set workbooks [$application Workbooks]
set workbook [$workbooks Add]
set worksheets [$workbook Worksheets]
set worksheet [$worksheets Item [expr 1]]

set cells [$worksheet Cells]
set i 0
foreach row {1 2 3} {
foreach column {A B C} {
$cells Item $row $column [incr i]
}
}

$workbook SaveAs {c:\tst.xls}
$application Quit
--------------------------------------------------------------------


SaveAS會另存一個新的Excel為tst.xls,所以一開始不用在C槽建立這個檔,
若存在,他會問你是否要覆蓋。

這個例子會在A1-C3的欄位中分別存入1-9的值,然後,另存新檔...
你看完這個例子應該會有一點Fu...

sam | 2010年3月22日 下午6:09

錯誤訊息:0x800a03ec

我試了一下,若c槽已存在這個檔案,然後系統問你是否要覆蓋,若選擇"否"的話,
就會發生這個錯誤代碼,若程式前面已指定檔案路徑與名稱開啟excel的話,
最後儲存可以用存檔的方式,而不是用另存的方式:

$workbook Save

小的只略懂些皮毛,可能有更好的方法也不一定。

dai | 2010年3月23日 上午12:11

sam ... 真是太感謝你了(淚)

我好久沒有開窗了一直懶得切過去...感謝你提供的範例,受益良多阿~

還以為..台灣只有我和學弟有在用ezdit...真是感謝你的捧場 呵呵

翊翾 | 2010年3月23日 下午1:02

ezdit很好用阿~尤其是Tab的功能,超方便的呢^^
透過sam的範例,我才知道我斜線打反了=口=|||||
好無言的錯誤阿~不過用Tcl控制Excel真的很方便呢~

感謝Sam幫我解惑呢~

dai | 2010年3月23日 下午2:07

翊翾 也有在用ezdit嗎? 感謝+1

翊翾 | 2010年3月23日 下午5:02

Hi Sam, Dai
我發現到一件很神奇的事情
我發問的那段程式碼,在XP底下可以正常執行
但是在Win7底下卻不能正常工作呢,Win7就是會出現我上面說的那些錯誤
XP就不會發生錯誤,斜線方向也不影響。是因為系統的關係嗎= =||

dai | 2010年3月23日 下午5:14

Hi 翊翾

我只有在XP下做過這些事,Win7則是沒有試過...要靠你試試,然後經驗分享了 哈哈

lbboy | 2010年3月25日 下午10:24

hi sam & dai
有兩個問題想請教一下
1.
感謝 sam and dai各提供兩種方法,可以在c 裡呼叫或使用TCL
知道有方法已經讓人覺得很有幫助了!!
只是不知道可否提供一些範例 還有就是哪裡有詳細的資料說明這一方面的用法
以空可以來練習一下
sam:
第一種:在同一個程式開發軟體中撰寫C與TCL
dai:
1.從C呼叫Tcl script裡的程序


2. 另外
最近在試 用tclkit sdx.kit 打包tcl 程式, 使用的過程感覺不是很順利
會有一些手動的動作需要做..有時候需要去修改VFS裡面的file
目前以碰到一個問題,包出的.kit file, BWidget 會說找不到
已經有把BWidget 的dir 放在/lib/的目錄下面,可是還是會說找不到,我猜是跟package index 這個file 有關吧!!不是很確定是何原因!!
不知道大家在使用starkit or starpack 會不會覺得不是很順利的感覺
當如果一次要包多個tcl files or tcl 裡面有用到一些path 的地方,或是有用到一些package時
包裝的過程就常常不是很順利.....
有沒有方便的tools 可以幫助呢!! 或詳細的guide呢
thanks

sam | 2010年3月26日 上午10:14

Hi lbboy:

TCL/C的方法就如同Dai大大所說的一樣。

Dai大大:你可以在C裡include "tcl.h",這樣你就可以使用Tcl提供的C API,在Tcl C API裡,你可以建立Tcl的直譯器,然後用這個直譯器來執行script level的程序。

小的我提供二本在網路上很容易找到的電子書給您參考一下:

第一本:Practical Programming in Tcl and Tk
    Chapter:C Programming and Tcl
第二本:TCL TK A Developer Guide
    Chapter:Writing a Tcl Extension

你可以參考一下,裡面有很多例子,應該對你很有幫助,
再來就可以參照Tcl Library(Tcl C API)去把你要的功能寫出來:
http://docs.activestate.com/activetcl/8.5/tcl/TclLib/contents.htm

用SWIG從C呼叫Tcl script的程序:
Dai大大的學弟(jky777大大)有發一篇SWIG教學,我就是看這篇學滴...
http://jky777.got7.org/2009/11/swig-tcl-c.html


打包成執行檔的問題我提供一個最簡單的解決方法:

請下載ezdit 0.9.0,新增加了把程式打包成執行檔的功能(EzSDX)
好像很讚的樣子,小的我剛剛才下載好還沒安裝,等會來試試,科科。
(Dai大大又要感動的哭了^^,ezdit的使用者再+l)

dai | 2010年3月26日 下午6:56

感謝sam這麼詳細的回答!! 只能說...好阿

sam 「大大」的稱呼太沈重了...還是叫我dai...比較親切的感覺 呵呵

EzSDX...可能沒有想像中的方便...希望不會讓你失望 哈哈

dai | 2010年3月26日 下午7:06

hi lbboy

如果你想要把BWidget或是額外的package加入starpack

比較保險的方法是,你要在被包入starpack的程式裡指定 ::auto_path 清單變數(串列)

這個清單裡記錄了所有package的搜尋路徑

舉例來說: 如果你包出來的檔案是 c:/test.exe

那你就需要在test.exe的執行過程中把 「c:/test.exe/放BWidget的資料夾」指定到::auto_path裡

我慣用的程式片斷如下:

set appPath [file normalize [info script]]
if {[file type $appPath] == "link"} {set appPath [file readlink $appPath]}

set appPath [file dirname $appPath]

set ::auto_path [linsert $::auto_path 0 [file join $appPath "lib"]]

這個程式片段假設主程式同一層目錄下有一個lib目錄

凡是放在lib目錄裡的package都會被正確的找到,不管有沒有包成starpack

lbboy | 2010年4月6日 下午10:24

hi dai

關於starpack 的問題
因為我用spectcl 寫ui介面 ,它會產生兩個tcl file,我再將這兩個file打包成starkit or starpack
打包的過程中發現 spectcl自動產生的code 中有下面這一行的敘述
造成直接將file打包會有問題,因為tcl file的path 經過打包後已經移到.vfs/ 下面的路徑了..
也就是說 有可能某些寫法的tcl不能直接打包 在打包的時後需要經過修改相關的code
這樣感覺上 在某些case打包的時候 有可能會有需要額外的手動工作 去修改code
如果 全部都是自己寫的code 可能還好!!
可是一但這些code可能是自動產生的 或是來自別人的source 時,這樣的工作,就會顯得打包不那麼方便
不知道 大家有沒有碰過這樣的問題!!!
thanks



..................
elseif {$::argv0 == [info script]} {
.............................

dai | 2010年4月8日 下午12:43

hi lbbly,

不管是用starpack或是由script的方式執行,我都會在程式的一開頭先找出目前程式的執行路徑,像這樣:

set appPath [file normalize [info script]]
if {[file type $appPath] eq "link"} {set appPath [file readlink $appPath]}
set appPath [file dirname $appPath]

有了appPath以後,接下來凡是用到專案資料夾裡的檔案,都用這個appPath裡的值組出正確的路徑。如些一來就不會有問題了。

匿名 | 2010年4月15日 下午4:03

Hi Dai,

因為是TCL新手, 有個問題想請教一下, 不知道會不會是個笨問題, 請包含.

若我有兩支tcl script, 分別為ap1.tcl及ap2.tcl
我想在ap1.tcl run完後再run ap2.tcl, 不知有沒有可能, 該如何作到,
[ap1.tcl psudocode]
puts "I am ap1"
call ap2.tcl
[/psudocode]

[ap2.tcl psudocode]
puts "I am ap2"
[/psudocode]

感謝提供一個很棒的TCL教學文件及技術交流平台

JC

dai | 2010年4月15日 下午7:00

hello JC

在我剛開始學Tcl也有遇到這個問題 ~ 方法如下,假設app1.tcl及app2.tcl放在一樣的目錄下面:

app1.tcl的程式

puts "app1"
source app2.tcl


app2.tcl的程式

puts "app2"

TerryWang | 2010年4月15日 下午8:05

請問D大...

若我想要即時動態顯示目前活動該如何做呢??

舉例來說...假設我的程式要像cmd底下ping xxx.xxx.xxx.xxx
即時動態顯示每次ping出來的結果...(預設是四次)
如何能像cmd底下那樣..一次一次的出來!!!

dai | 2010年4月16日 上午10:50

hi Terry

嗯 ~ 我猜想你是要類似這樣的程式吧:

text .t
pack .t -expand 1 -fill both


for {set i 0} {$i<10} {incr i} {
.t insert end "Hello $i \n"
update
after 1000
}

翊翾 | 2010年4月16日 上午11:57

哈囉囉,Dai你好~
Terry的意思是我們想執行一段程式
exec ping 127.0.0.1
希望會輸出結果,但TCL會等到ping全部完成後才會一次輸出結果

我們希望執行exec ping 127.0.0.1後
能及時的回傳每次每行的結果,不知道能不能做到呢?
我們有嘗試過exec ping 127.0.0.1 &
但他只會在背景繼續執行,不知道怎叫出最新的回傳值呢?

sam | 2010年4月16日 下午3:02

提供一個很爛的方法:
將ping的結果輸出到一個txt檔中,每隔一定的時間再去讀取這個txt。
剛有試了一下,ping的結果好像不會等到全部結束才存到txt檔中,會慢慢的ping慢慢的存。


set address 127.0.0.1

#這行程式開一條Thread來作
puts [exec ping $address > a.txt]

#Main Thread的工作
做讀取txt的動作,讀一行,刪一行,或讀全部再刪全部(即時),重覆這個動作。


以上是小弟提供的一個爛方法,正解還是有請Dai大大。

dai | 2010年4月16日 下午7:58

呵 我果然誤解了Terry的問題~

sam 其實...只要能達到功能,就是個好程式,也沒有所謂的正解啦!!

我也來提供一個,自己常用的方法 它可以適用在Windows , Linux , Mac ~

首先你要在 http://unxutils.sourceforge.net/ 下載win32版的cat.exe (在UnxUtils.zip裡面),把它放在PATH環境變數找得到的位置。

然後再開pipe到ping:

set fd [open "| ping 127.0.0.1 |& cat" r]
fconfigure $fd -blocking 0
while {![eof $fd]} {
update
if {[gets $fd buf] == -1} {continue}
puts [string trim $buf]
}
close $fd

這樣就可以一次讀一行輸出了,當然你也可以用blocking mode去讀也行。

翊翾 | 2010年4月19日 上午9:10

sam的方法也是有解決我們的問題
能想到這方法也是滿厲害的阿^^
至於Dai給的方法真的是連想都沒想過@@|||
靠著一個cat.exe檔就達到目的,真的是感到有點神奇阿

Dai和sam的方法都有試過了,最後還是採用Dai方法^^
因為最後包成一個單一檔的話會比較方便
感謝兩位的解答呢(笑)~

dai | 2010年4月19日 上午10:43

事實上以ping的這個例子來說,不用cat也是可行的,只是用cat的話,可以適用在大部份的狀態,例如,像這樣的也可以

set fd [open "| ping 127.0.0.1" r]

....

Midas | 2010年4月19日 上午11:56

Dai . 大大..
上面的 ping 我試過也 OK . ( 拜謝... )
但我有一個 需要有 input / output 的應用 , 以 ftp 來做 範例 .
試了以下幾個 .
(a)set fd [open "| ftp 10.10.30.16 |& cat" r]
errmsg ==>
|____________User (10.10.30.16:(none)):
|____________error getting console input handle, code 5
|____________Not logged in.
|____________Login failed.


(b)set fd [open "| ftp 10.10.30.16 |& cat" r+]
(c)set fd [open "| ftp 10.10.30.16 |& cat" w]
(d)set fd [open "| ftp 10.10.30.16 | 1<&2 |& cat" r+]
最後還是無法解 ... 看來 我對 pipe 還是 沒有全盤瞭解 .. 望 Dai 指點迷津一下.

dai | 2010年4月19日 下午12:51

用(b) 就可以了,輸出的時候記得要flush $fd ex.

set fd [open "| ftp 10.10.30.16 |& cat" r+]
.... 等到提示login
puts $fd "username"
flush $fd

ps. Tcl有ftp client 的 package可以使用。不用開pipe到ftp命令。

Midas | 2010年4月19日 下午2:17

謝謝Dai大大
剛剛試過(b) . 還是不行. 跟 (a) 的訊息類似.
error getting console input handle, code 5
Not logged in.
Login failed.
可能是pipe 裡面的導向出了問題.

dai | 2010年4月19日 下午3:28

如果是這樣的話...要不要試試用tcllib的ftp,像這樣:

package require ftp

set tok [::ftp::Open ftp.nsysu.edu.tw anonymous dai@tai.com.tw]
foreach item [::ftp::List $tok] {
puts $item
}
::ftp::Close $tok

如果你沒有裝ftp package的話,用下面的命令安裝

teacup install ftp

Midas | 2010年4月19日 下午5:16

謝謝大大的 建議 . 我目前是用 curl . 但 你建議 的這個 更好用.
這個 FTP 用法 先收下了 .
我之前 沒有 寫的很清楚 我引 ftp 來當 討論 用 open vs pipe 範例.
目前我這邊的狀況是 . 有3th party 寫的程式 
使用 console mode ( 就是 cmd.exe 下面執行的 , 用 printf 會印出字串)
在測試過程中. 會需要keyin 一些值 . ( ex: scanf ) 然後接著 測. 再接著 keyin不同的 值.
經過幾道不同的 keyin 與 畫面的檢查 ( regexp .. ) 才能把整道 程序 完程 .
這個相關的問題 在大大 開版不久時就有跟大大 請教過了 . 再次感謝.
今天看到 . open + cat.exe , 想說 有沒有可能 籍由 pipe ==> "|&" , 來更 瞭解 ..
open 的使用 ... 因為使用了 很多種方法 ( 包含 twapi ). 都還是有些Bug .
若今能習得 pipe 的精髓. 我想用單純的 open 就應該可以解決了. 且更好 maintain.
Best regards,
/Midas

Midas | 2010年4月19日 下午5:17

謝謝大大的 建議 . 我目前是用 curl . 但 你建議 的這個 更好用.
這個 FTP 用法 先收下了 .
我之前 沒有 寫的很清楚 我引 ftp 來當 討論 用 open vs pipe 範例.
目前我這邊的狀況是 . 有3th party 寫的程式 
使用 console mode ( 就是 cmd.exe 下面執行的 , 用 printf 會印出字串)
在測試過程中. 會需要keyin 一些值 . ( ex: scanf ) 然後接著 測. 再接著 keyin不同的 值.
經過幾道不同的 keyin 與 畫面的檢查 ( regexp .. ) 才能把整道 程序 完程 .
這個相關的問題 在大大 開版不久時就有跟大大 請教過了 . 再次感謝.
今天看到 . open + cat.exe , 想說 有沒有可能 籍由 pipe ==> "|&" , 來更 瞭解 ..
open 的使用 ... 因為使用了 很多種方法 ( 包含 twapi ). 都還是有些Bug .
若今能習得 pipe 的精髓. 我想用單純的 open 就應該可以解決了. 且更好 maintain.
Best regards,
/Midas

dai | 2010年4月19日 下午11:55

嗯 ~ 如果我遇到你的這個狀況,應該會採用expect,也許這個也會對你有幫助。

匿名 | 2010年4月20日 上午8:58

expect 應該是可用
但是當expect 要去開啟會load driver 的執行檔
或是 執行檔 內 會一直clear 畫面
就會導致 broken pipe
無法輸入任何command 到執行檔內

ivory | 2010年4月22日 下午4:43

Dai 您好:
想請問一下
透過tcl telnet到遠端機器
結果存回到$expect_out(buffer)
可是
$expect_out(buffer)的值
會有非預期的斷行
例如
正確應為
lan_ip_dhcp_end 1.2.3.4
實際結果為
lan_ip
_dhcp_end 1.2.3.4
請問您是否有遇過類似的問題?

謝謝

dai | 2010年4月22日 下午9:39

hello ~ 這個問題我沒有遇過哦!! 因為我expect用得很少...

路人 | 2010年4月28日 下午5:41

我轉貼你的 WGet 網路相簿下載器
在我的無名
如果不可以的話
麻煩告知

我會馬上移除
謝謝
PS:
因為我不知道該如何讓你知道
我轉貼了你的文章
所以才會在此留言
不好意思...

dai | 2010年4月28日 下午11:01

嗯 ~ 不要緊的,你轉貼吧!!

eda | 2010年5月26日 上午6:54

Hi Dai,

有一個問題想向您請教。在TCL中""和{}有不同的意義。我還是有些弄不清楚。如下例。

set x 0
while "$x < 5" {
set x [expr {$x + 1}]
if "$x > 3" continue
puts "x is $x"
}

由於用了""在while,會無限循環。

而以下例子
set x 0
while {$x < 5} {
set x [expr {$x + 1}]
if "$x > 3" continue
puts "x is $x"
}

則不會,因為用了{}。

這是我看到的一個例子。請問為什麼會這樣?

多謝。

dai | 2010年5月26日 下午1:26

hi eda,

放在雙引號裡的變數會被執行變數代換,而大括號裡的不會

詳細的說明,請參考說明文件的第4章及第7章

裡面有說明為什麼像這樣的例子while "$x < 5"

會產生無限迴圈

匿名 | 2010年5月26日 下午4:50

Hi Dai,

小弟路過...
恰巧正在學習TCL Thread.
這真是個學習TCL/TK的好地方。
感謝Dai大大的熱心..
希望未來的日子能請您多指教.

Thanks,
Chris Wang

dai | 2010年5月26日 下午8:34

您客氣了~有空常來交流哦!!

TerryWang | 2010年5月31日 下午1:46

Dear Dai大 :

又來跟您請教問題了...目前想寫TFTP Server, 不知道TCL是否有套件支援呢?

在google上找尋資料好久..資料少的可憐, 所以只好來找Dai您尋求幫助了!!!

dai | 2010年5月31日 下午5:23

這邊有位仁兄寫了一個tftp server,請參考

http://wiki.tcl.tk/12711

TerryWang | 2010年5月31日 下午6:58

Dai..那個我看過了!!他程式碼裡頭有package require tftpd

我怎樣都沒辦法有這個lib...用之前Dai您交的方式去download也失敗

XD...沒這個套件...也就沒法試試看這段程式碼了

dai | 2010年5月31日 下午10:13

tftpd就是他實作的程式碼 網頁上有這一部份的程式

也許你是要先裝tcludp套件吧!!

翊翾 | 2010年6月4日 下午6:34

哈囉Dai^^~
妳提供的網頁上面的程式碼已經成功的RUN出來了
感謝呢~

關於很久很久以前我問的一個問題,存檔路徑在WIN7下會出錯
後來解決方法就是把/代換成\\就ok囉~ 方法很爛啦XD

dai | 2010年6月5日 上午12:41

hi 翊翾

先恭喜你成功的RUN出你的程式~

其實~只要跑得出正確的功能就是好程式 ^^

翊翾 | 2010年6月8日 下午2:55

Dai你好^^~
最近又有個小問題要來煩你一下
我想在TCL裡面加入一個GIF的圖檔
但我的GIF是一個會動的圖檔
放到TCL版面上就靜止不動了

不知道是TCL沒支援還是我少了什麼步驟呢?

dai | 2010年6月8日 下午5:13

預設的tk不支援會動的gif檔,所以你需要額外的套件,參考下面的連結:

http://wiki.tcl.tk/4882

匿名 | 2010年6月10日 下午9:47

Dai,

請問如果處理參數問題?比如我寫了一個process,我希望運行的時候的命令行是用-來指定不同的參數,是否有簡單的辦法?如:

command -option1 -option2 ....

Thank you.

翊翾 | 2010年6月11日 上午9:23

Dai你好^^
想請教一個問題
當我用tablelist寫入資料後
想用點及滑鼠左鍵把直給取出
但每次點出顯示的值都是上一次點擊的值

在我在cmd底下驗證 .pathname.table curselection
是正確的值,是我的bind出問題了嗎?

dai | 2010年6月11日 下午2:27

在tcl裡你可以用argv這個變數取得程式執行時帶入的參數,一個簡單的例子像這樣:

foreach item $::argv {puts $item}

這個例子會把所有程式帶入的參數都印出來

dai | 2010年6月11日 下午2:35

hi 翊翾,

請試試下面的程式:

bind [.t bodypath] <ButtonRelease-1> {puts [.t curselection]}

dai | 2010年6月11日 下午2:36

ps...上面的.t是tablelist的widget

eda | 2010年6月26日 上午4:00

Hi Dai,

如何使一個Widget always on top?我使用了以下的方法。

wm attributes .top -topmost 1

這個方法可行,但是在top widget中有一個dropdown list,這個的內容被top widget擋住了。請問有什麼解決辦法麼?

可行這裡不能上圖,不然我可以上個圖。貼上我的部分code。


proc main {} {
toplevel .top
wm title .top
wm geometry .top 490x350
wm resizable .top 0 0
wm attributes .top -topmost 1

ttk::combobox .top.f2.c1 -textvariable layer -width 12

這個combobox的下拉內容的部分被top擋住了。

多謝。

dai | 2010年6月27日 下午10:07

hi eda,

你的片斷程式還缺了一點,我改成這樣:

toplevel .top
wm title .top
wm geometry .top 490x350
wm resizable .top 0 0
wm attributes .top -topmost 1
ttk::combobox .top.f2 -textvariable layer -width 12
pack .top.f2

上面的程式 沒有出現你說的問題

sam | 2010年6月29日 下午3:39

Hi Dai:

請問一個問題喔,
Tcl有辦法去取得某執行檔(非TCL的執行檔)中的欄位值嗎,
例如,有辦法取得"附屬應用程式/小算盤"中的欄位值嗎,
之前有用DDE去取得EXCEL或VB中的欄位值,
但這些都是知道欄位的名稱與該應用程式有支援DDE的情況下,
若沒有上述的資訊,Tcl是否有辦法取得某執行檔中的欄位值?
或者是說,
如果想要取得某執行檔的欄位值,前提必須是要知道哪些基本的資訊。
找了很久,目前還是沒有頭緒,請大大開示...

3Q你...

dai | 2010年6月29日 下午8:18

sam

嗯~~除了DDE也可以使用COM

請參考

http://wiki.tcl.tk/11900

http://wiki.tcl.tk/1821

上面的兩個例子使用COM去操控EXCEL 

eda | 2010年7月6日 上午6:29

Hi Dai,

有沒有興趣寫一個TK GUI builder?有些老的如Viusal TCL太老了,不支持新的TK。而PureTkGui不再開源了。

如果您能寫一個支持最新版TK的GUI builder那就太好了。

dai | 2010年7月6日 上午11:40

Hi eda,

我對你的提議非常的有興趣,而且事實上我自己也想寫很久了

但是,礙於目前的時間,還有經濟上的壓力

所以,我需要一起打拚的伙伴,才有可能投入寫這個程式

或是,過一段時間看看,如果狀況允許的話,我會很想把它寫出來

Theme Design by devolux.org. Converted by Wordpress To Blogger for WP Blogger Themes. Sponsored by iBlogtoBlog
This template is brought to you by : allblogtools.com | Blogger Templates