tcl return 用户选择的文件名
tcl return file name chosen by user
我已经为此苦苦思索了一天,让我想起了 20 多年前学习 MFC 的情景:-(
我希望用户选择一个文件名。选择它后,我希望能够在程序的其他部分使用该文件名。我迄今为止的努力就这样结束了:
package require Tk
wm title . "get user specified file name (how hard can it be?)"
labelframe .lfInput -text "user specified file name goes here"
set userChoice "userChoice is bound to this field"
# note not $userChoice in next line
entry .lfInput.ent -width 40 -textvariable userChoice
button .lfInput.but -text "Kindly press this button and choose a file.\nNot only will I write the file name\nin the the field to the left, I'll make\nit available to anyone who cares\n to press the button below."\
-command "fileDialog .lfInput .lfInput.ent"
pack .lfInput.ent -side left -padx 10 -expand yes -fill x
pack .lfInput.but -side left -padx 10 -pady 3
pack .lfInput -fill x -padx 2c -pady 3
focus .lfInput.ent
button .b -text "Press this button to write\nuserChoice to the console\nthereby demonstrating\nthe ability to get a file\nname from the user."\
-command "writeTheArg {$userChoice}"
pack .b
proc fileDialog {w ent} {
set types { {"All files" *} }
set userFile [tk_getOpenFile -multiple false -filetypes $types -parent $w -typevariable "All files"]
if {[string compare $userFile ""]} {
$ent delete 0 end
$ent insert 0 $userFile
$ent xview end
}
puts "line 34: local userFile is $userFile"
}
proc writeTheArg {s} {
puts "line 38: puts $s"
}
puts "line 41: user choice is {$userChoice}"
puts "when pressing second button, the file chosen by the user should show up here\n\
by virtue of the textvariable option at line 9\n...\n"
就其规定的目的而言,这有点矫枉过正,我们在这里所做的任何事情都可以在 proc fileDialog 中完成。但是,如果有更多的用户选择可以收集
大概我们可以在 proc UpdatedUserFile 中将它们全部整理出来并继续。
proc fileDialog 应该 return 一个本地 $userFile,这就是记住 $$$
最简单的方法是使用全局变量。
proc fileDialog {w ent} {
global userFile
set types { {"All files" *} }
set file [tk_getOpenFile -filetypes $types -parent $w]
if {[string compare $file ""]} {
# Only update the global if the user didn't cancel
set userFile $file
$ent delete 0 end
$ent insert 0 $userFile
$ent xview end
}
puts "line 34: local userFile is $userFile"
}
然后您的其余代码可以读取该全局文件以获取文件。主要的棘手之处在于,当用户在对话框中接受文件时,全局将发生变化;您可以通过在 userFile
全局变量上设置 write trace 来处理该问题,并在该变量发生变化时更新 UI。当然,您可以通过使用 label
的 -textvariable
选项来完成此操作的最简单版本:在幕后为您设置跟踪,因此它始终向您显示变量的当前内容:
pack [label .showTheUserFile -textvariable userFile]
对于更复杂的交互,您只需要直接设置跟踪(使用trace
):
trace add variable userFile write UpdatedUserFile
proc UpdatedUserFile {args} {
# Note that we're ignoring the arguments to the callback here; we only ever apply
# this trace to one event on one variable so we know what's going on without
# being told explicitly
# Here's a very simple version; for more complicated versions, see your imagination!
global userFile
puts "The user has selected the file $userFile"
}
我曾经(现在仍然)遇到的问题是忘记使用 $ 来引用变量。这会在尝试传递参数时导致奇怪的错误,并可能导致没有经验的人开始做奇怪而奇妙的事情,就像原来的问题一样。感谢您的帮助,否则我想我会完全放弃!
正确版本如下:
package require Tk
wm title . "get user specified file name"
labelframe .fileSelectorGroup -text "press the button to choose your file"
set userFileChoice "userFileChoice is bound to this field"
# note not $userFileChoice in next line
entry .fileSelectorGroup.ent -width 40 -textvariable userFileChoice
button .fileSelectorGroup.but -text "Kindly press this button and choose a file.\nNot only will I write the file name\nin the the field to the left, I'll make\nit appear in the console."\
-command "getUserFileAndProceed .fileSelectorGroup .fileSelectorGroup.ent"
pack .fileSelectorGroup.ent -side left -padx 10 -expand yes -fill x
pack .fileSelectorGroup.but -side left -padx 10 -pady 3
pack .fileSelectorGroup -fill x -padx 2c -pady 3
focus .fileSelectorGroup.ent
proc getUserFileAndProceed {w ent} {
set userChoice [fileDialog $w $ent]
puts "line 21: userChoice is $userChoice"
puts "have a nice day"
}
proc fileDialog {w ent} {
set types { {"All files" *} }
set userFile [tk_getOpenFile -multiple false -filetypes $types -parent $w -typevariable "All files"]
if {[string compare $userFile ""]} {
$ent delete 0 end
$ent insert 0 $userFile
$ent xview end
}
return $userFile
}
我已经为此苦苦思索了一天,让我想起了 20 多年前学习 MFC 的情景:-(
我希望用户选择一个文件名。选择它后,我希望能够在程序的其他部分使用该文件名。我迄今为止的努力就这样结束了:
package require Tk
wm title . "get user specified file name (how hard can it be?)"
labelframe .lfInput -text "user specified file name goes here"
set userChoice "userChoice is bound to this field"
# note not $userChoice in next line
entry .lfInput.ent -width 40 -textvariable userChoice
button .lfInput.but -text "Kindly press this button and choose a file.\nNot only will I write the file name\nin the the field to the left, I'll make\nit available to anyone who cares\n to press the button below."\
-command "fileDialog .lfInput .lfInput.ent"
pack .lfInput.ent -side left -padx 10 -expand yes -fill x
pack .lfInput.but -side left -padx 10 -pady 3
pack .lfInput -fill x -padx 2c -pady 3
focus .lfInput.ent
button .b -text "Press this button to write\nuserChoice to the console\nthereby demonstrating\nthe ability to get a file\nname from the user."\
-command "writeTheArg {$userChoice}"
pack .b
proc fileDialog {w ent} {
set types { {"All files" *} }
set userFile [tk_getOpenFile -multiple false -filetypes $types -parent $w -typevariable "All files"]
if {[string compare $userFile ""]} {
$ent delete 0 end
$ent insert 0 $userFile
$ent xview end
}
puts "line 34: local userFile is $userFile"
}
proc writeTheArg {s} {
puts "line 38: puts $s"
}
puts "line 41: user choice is {$userChoice}"
puts "when pressing second button, the file chosen by the user should show up here\n\
by virtue of the textvariable option at line 9\n...\n"
就其规定的目的而言,这有点矫枉过正,我们在这里所做的任何事情都可以在 proc fileDialog 中完成。但是,如果有更多的用户选择可以收集 大概我们可以在 proc UpdatedUserFile 中将它们全部整理出来并继续。
proc fileDialog 应该 return 一个本地 $userFile,这就是记住 $$$
最简单的方法是使用全局变量。
proc fileDialog {w ent} {
global userFile
set types { {"All files" *} }
set file [tk_getOpenFile -filetypes $types -parent $w]
if {[string compare $file ""]} {
# Only update the global if the user didn't cancel
set userFile $file
$ent delete 0 end
$ent insert 0 $userFile
$ent xview end
}
puts "line 34: local userFile is $userFile"
}
然后您的其余代码可以读取该全局文件以获取文件。主要的棘手之处在于,当用户在对话框中接受文件时,全局将发生变化;您可以通过在 userFile
全局变量上设置 write trace 来处理该问题,并在该变量发生变化时更新 UI。当然,您可以通过使用 label
的 -textvariable
选项来完成此操作的最简单版本:在幕后为您设置跟踪,因此它始终向您显示变量的当前内容:
pack [label .showTheUserFile -textvariable userFile]
对于更复杂的交互,您只需要直接设置跟踪(使用trace
):
trace add variable userFile write UpdatedUserFile
proc UpdatedUserFile {args} {
# Note that we're ignoring the arguments to the callback here; we only ever apply
# this trace to one event on one variable so we know what's going on without
# being told explicitly
# Here's a very simple version; for more complicated versions, see your imagination!
global userFile
puts "The user has selected the file $userFile"
}
我曾经(现在仍然)遇到的问题是忘记使用 $ 来引用变量。这会在尝试传递参数时导致奇怪的错误,并可能导致没有经验的人开始做奇怪而奇妙的事情,就像原来的问题一样。感谢您的帮助,否则我想我会完全放弃!
正确版本如下:
package require Tk
wm title . "get user specified file name"
labelframe .fileSelectorGroup -text "press the button to choose your file"
set userFileChoice "userFileChoice is bound to this field"
# note not $userFileChoice in next line
entry .fileSelectorGroup.ent -width 40 -textvariable userFileChoice
button .fileSelectorGroup.but -text "Kindly press this button and choose a file.\nNot only will I write the file name\nin the the field to the left, I'll make\nit appear in the console."\
-command "getUserFileAndProceed .fileSelectorGroup .fileSelectorGroup.ent"
pack .fileSelectorGroup.ent -side left -padx 10 -expand yes -fill x
pack .fileSelectorGroup.but -side left -padx 10 -pady 3
pack .fileSelectorGroup -fill x -padx 2c -pady 3
focus .fileSelectorGroup.ent
proc getUserFileAndProceed {w ent} {
set userChoice [fileDialog $w $ent]
puts "line 21: userChoice is $userChoice"
puts "have a nice day"
}
proc fileDialog {w ent} {
set types { {"All files" *} }
set userFile [tk_getOpenFile -multiple false -filetypes $types -parent $w -typevariable "All files"]
if {[string compare $userFile ""]} {
$ent delete 0 end
$ent insert 0 $userFile
$ent xview end
}
return $userFile
}