tcl返回用户选择的文件名

时间:2018-01-26 14:11:02

标签: tcl tk

现在已经开始反对这一天了,让我想起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中完成。但是,如果有更多的用户选择要收集 大概我们可以在procUpdperUserFile中对它们进行排序并继续。

proc fileDialog应该返回一个本地$ userFile,它是关于记住$$$

的全部内容

2 个答案:

答案 0 :(得分:0)

最简单的方法是使用全局变量。

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全局变量上设置写跟踪来处理它,并在更改时更新UI。当然,您可以使用-textvariable的{​​{1}}选项来执行最简单的版本:在幕后为您设置跟踪,以便始终显示变量的当前内容: / p>

label

您只需要直接设置跟踪(使用pack [label .showTheUserFile -textvariable userFile] )以进行更复杂的交互:

trace

答案 1 :(得分:0)

我遇到的问题(现在仍然是)忘记使用$来引用变量。当尝试传递参数时,这会导致奇怪的错误,并且可能导致缺乏经验的人开始做奇怪而美妙的事情,就像在原始问题中那样。谢谢你的帮助,我想我已经完全放弃了!

正确的版本如下:

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
}