如何让"Back"和"Next"按钮正常工作?



我正在开发一个帮助学生的软件。我们的目标是要有一个交互式的软件。目前,我有几个按钮必须显示教程的第一个界面。我能够显示第一个教程,但如果我想使用"后退"或"下一步"按钮,它就不起作用了。我不明白为什么。当我按下一个按钮时,调用一个过程,代码如下:

proc loadBackground {} {
    #variables
    set ::i 0
    set close 0
    set bgColour "White"
    set fd [open [pwd]/content/background r]
    set ::data [split [read $fd] n]
    close $fd
#window definition
toplevel .fr
wm title .fr "Background" 
wm geometry .fr 660x550+0+105
.fr configure -bg $bgColour
# define the main text zone
text .fr.txt -wrap word -yscroll {.fr.vscroll set} -highlightthickness 0
scrollbar .fr.vscroll -orient vertical -command {.fr.txt yview}
grid .fr.txt -column 0 -row 1 -sticky snwe
grid .fr.vscroll -column 1 -row 1 -sticky snwe
# define the canvas for interactive diagrams
canvas .fr.canv -bg #f8f8f8 -yscrollcommand {.fr.vscroll set} -scrollregion "0 0 750 750"
.fr.txt tag configure center -justify center
.fr.txt configure -font "times 12" -state disabled
.fr.vscroll configure -orient vertical -command {.fr.txt yview}
grid .fr.txt -column 0 -row 1 -sticky snwe
.fr.txt configure -state normal
.fr.txt delete 1.0 end
# title of section
label .fr.titl
.fr.titl configure -font "arial 20" -pady 10
grid .fr.titl -column 0 -row 0 -sticky swe
.fr.titl configure -background "White"
#text styles
.fr.txt tag configure Normal -font "times 12"
.fr.txt tag configure subTitle -font "times 14"
.fr.txt tag configure Titlec -font "times 16" -justify "center"
.fr.txt tag configure subTitlec -font "times 14" -justify "center"
.fr.txt tag configure subTitlecu -font "times 14"  -justify "center" -underline on
.fr.txt tag configure Titlecu -font "times 16" -justify "center" -underline on
.fr.txt tag configure Title -font "times 16"
.fr.txt tag configure link -foreground blue -font "times 12"
.fr.txt tag configure right -foreground "forest green"
.fr.txt tag configure wrong -foreground red
.fr.txt tag configure enhance -background "light goldenrod"
.fr.txt tag configure rightenhance -background "light goldenrod" -foreground "forest green"
.fr.txt tag bind link <Enter> ".fr.txt configure -cursor hand1"
.fr.txt tag bind link <Leave> ".fr.txt configure -cursor arrow"
dispFile [lindex $::data $::i]
#buttons definition 
frame .fr.bar
grid .fr.bar -row 2
button .fr.bar.bk -text "<< Back" -pady 5 -borderwidth 0 -command { dispFile [lindex $::data [expr $::i - 1]]}
pack .fr.bar.bk -padx 5 -pady 5 -side left -fill none
button .fr.bar.cl -text "Close" -pady 5 -borderwidth 0 -command { set close 1}
pack .fr.bar.cl -padx 5 -pady 5 -side left -fill none
button .fr.bar.nx -text "Next >>" -pady 5 -borderwidth 0 -command { dispFile [lindex $::data [expr $::i + 1]]}
pack .fr.bar.nx -padx 5 -pady 5 -side right -fill none
vwait close
destroy .fr
}

显示教程(以文件形式编写)的过程如下:

proc dispFile {name} {
    set flname "[pwd]/Files/$name" 
    set infile [open $flname "r"]
    set inEOF -1
    set txln ""
    set lkcount 0
    set counter 0
    while {[gets $infile inln] != $inEOF} {
        switch $inln {
            "<Title>" {
                gets $infile inln
                .fr.titl configure -text $inln
            }
            "<subTitle>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" subTitle
            }
            "<subTitlec>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" subTitlec
            }
            "<subTitlecu>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" subTitlecu
            }
            "<Titlec>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" Titlec
            }
            "<Titlecu>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" Titlecu
            }
            "<Highlight>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" Titlecu
            }
            "<hyperlink>" {
                gets $infile inln
                .fr.txt insert end "$inln" "link lk$lkcount"
                .fr.txt insert end "n" Normal
                gets $infile inln
                .fr.txt tag bind lk$lkcount <1> "openPDF Files/$inln"
                incr lkcount
            }
            "<hypLink>" {
                gets $infile inln
                .fr.txt insert end "$inln" "link lk$lkcount"
                .fr.txt insert end "n" Normal
                .fr.txt tag bind lk$lkcount <1> [list eval exec [auto_execok start] "$inln"]
                incr lkcount
            }
            "<image>" {
                gets $infile inln
                .fr.txt insert end "n"
                set meh [image create photo -file [file join "Files/$inln"]]
                .fr.txt insert end " " center
                .fr.txt image create end -image $meh
                .fr.txt insert end "n"
            }
            "<test>" {
                gets $infile inln
                callTuto $inln
            }
            "<results>" {
                gets $infile inln
                DisplayResults
            }
            "<entry>" {
                gets $infile inln
                DispEntry
            }
            "<adv>" {
                gets $infile inln
                Advice
            }
            "<proc>" {
                gets $infile inln
                $inln
            }
            default {
                set txln "$inlnn"
                .fr.txt insert end $txln Normal
            }        
        }     
    }
    .fr.txt configure -state disabled
    close $infile
}

谁能帮我找到一个解决方案或错误?

代码中的关键问题在于这几行:

button .fr.bar.bk -text "<< Back" -pady 5 -borderwidth 0 -command { dispFile [lindex $::data [expr $::i - 1]]}
button .fr.bar.nx -text "Next >>" -pady 5 -borderwidth 0 -command { dispFile [lindex $::data [expr $::i + 1]]}

问题是您没有更改存储在::i变量中的值。一个简单的改变是在这里使用incr命令:

button .fr.bar.bk -text "<< Back" -pady 5 -borderwidth 0 -command { dispFile [lindex $::data [incr ::i -1]]}
button .fr.bar.nx -text "Next >>" -pady 5 -borderwidth 0 -command { dispFile [lindex $::data [incr ::i]]}

然而,我倾向于把它提出来一点,以便有一个目的明确的小帮助过程:

proc nextFile {} {
    global data i
    incr i
    dispFile [lindex $data $i]
    # Ought to check for what happens at the end; turn off Next button if no next file
}
proc backFile {} {
    global data i
    incr i -1
    dispFile [lindex $data $i]
    # Ought to check for what happens at the start; turn off Prev button if no previous file
}
button .fr.bar.bk -text "<< Back" -pady 5 -borderwidth 0 -command backFile
button .fr.bar.nx -text "Next >>" -pady 5 -borderwidth 0 -command nextFile

这样的分解使得复杂的行为更容易编写。

根据@Donal Fellows,我使用了他的"后退"one_answers"下一步"按钮的代码,并改进了它和我的"disfile"过程:

proc dispFile {name} {
    set flname "[pwd]/Files/$name" 
    set infile [open $flname "r"]
    set inEOF -1
    set txln ""
    set lkcount 0
    set counter 0
    grid forget .fr.canv
    .fr.vscroll configure -orient vertical -command {.fr.txt yview}
    grid .fr.txt -column 0 -row 1 -sticky snwe
    .fr.txt configure -state normal
    .fr.txt delete 1.0 end
    while {[gets $infile inln] != $inEOF} {
        switch $inln {
            "<Title>" {
                gets $infile inln
                .fr.titl configure -text $inln
            }
            "<subTitle>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" subTitle
            }
            "<subTitlec>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" subTitlec
            }
            "<subTitlecu>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" subTitlecu
            }
            "<Titlec>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" Titlec
            }
            "<Titlecu>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" Titlecu
            }
            "<Highlight>" {
                gets $infile inln
                .fr.txt insert end "$inlnn" Titlecu
            }
            "<hyperlink>" {
                gets $infile inln
                .fr.txt insert end "$inln" "link lk$lkcount"
                .fr.txt insert end "n" Normal
                gets $infile inln
                .fr.txt tag bind lk$lkcount <1> "openPDF Files/$inln"
                incr lkcount
            }
            "<hypLink>" {
                gets $infile inln
                .fr.txt insert end "$inln" "link lk$lkcount"
                .fr.txt insert end "n" Normal
                .fr.txt tag bind lk$lkcount <1> [list eval exec [auto_execok start] "$inln"]
                incr lkcount
            }
            "<image>" {
                gets $infile inln
                .fr.txt insert end "n"
                set meh [image create photo -file [file join "Files/$inln"]]
                .fr.txt insert end " " center
                .fr.txt image create end -image $meh
                .fr.txt insert end "n"
            }
            "<test>" {
                gets $infile inln
                callTuto $inln
            }
            "<results>" {
                gets $infile inln
                DisplayResults
            }
            "<entry>" {
                gets $infile inln
                DispEntry
            }
            "<adv>" {
                gets $infile inln
                Advice
            }
            "<proc>" {
                gets $infile inln
                $inln
            }
            default {
                set txln "$inlnn"
                .fr.txt insert end $txln Normal
            }        
        }     
    }
    .fr.txt configure -state disabled
    close $infile
}
proc nextFile {} {
    global data i
    incr i
    if {$i== [llength $data]} {
     set i 0
    }
    dispFile [lindex $data $i]
}
proc backFile {} {
    global data i
    incr i -1
    if {$i <= 0} {
     set i 0
    }
    dispFile [lindex $data $i]
}
proc loadBackground {} {
    #variables
    set ::i 0
    set close 0
    set bgColour "White"
    set fd [open [pwd]/content/background r]
    set ::data [split [read $fd] n]
    close $fd
    #window definition
    toplevel .fr
    wm title .fr "Background" 
    wm geometry .fr 660x550+0+105
    .fr configure -bg $bgColour
    # define the main text zone
    text .fr.txt -wrap word -yscroll {.fr.vscroll set} -highlightthickness 0
    scrollbar .fr.vscroll -orient vertical -command {.fr.txt yview}
    grid .fr.txt -column 0 -row 1 -sticky snwe
    grid .fr.vscroll -column 1 -row 1 -sticky snwe
    # define the canvas for interactive diagrams
    canvas .fr.canv -bg #f8f8f8 -yscrollcommand {.fr.vscroll set} -scrollregion "0 0 750 750"
    .fr.txt tag configure center -justify center
    .fr.txt configure -font "times 12" -state disabled
    .fr.vscroll configure -orient vertical -command {.fr.txt yview}
    grid .fr.txt -column 0 -row 1 -sticky snwe
    .fr.txt configure -state normal
    .fr.txt delete 1.0 end
    # title of section
    label .fr.titl
    .fr.titl configure -font "arial 20" -pady 10
    grid .fr.titl -column 0 -row 0 -sticky swe
    .fr.titl configure -background "White"
    #text styles
    .fr.txt tag configure Normal -font "times 12"
    .fr.txt tag configure subTitle -font "times 14"
    .fr.txt tag configure Titlec -font "times 16" -justify "center"
    .fr.txt tag configure subTitlec -font "times 14" -justify "center"
    .fr.txt tag configure subTitlecu -font "times 14"  -justify "center" -underline on
    .fr.txt tag configure Titlecu -font "times 16" -justify "center" -underline on
    .fr.txt tag configure Title -font "times 16"
    .fr.txt tag configure link -foreground blue -font "times 12"
    .fr.txt tag configure right -foreground "forest green"
    .fr.txt tag configure wrong -foreground red
    .fr.txt tag configure enhance -background "light goldenrod"
    .fr.txt tag configure rightenhance -background "light goldenrod" -foreground "forest green"
    .fr.txt tag bind link <Enter> ".fr.txt configure -cursor hand1"
    .fr.txt tag bind link <Leave> ".fr.txt configure -cursor arrow"
    dispFile [lindex $::data $::i]
    #buttons definition 
    frame .fr.bar
    grid .fr.bar -row 2
    button .fr.bar.bk -text "<< Back" -pady 5 -borderwidth 0 -command backFile
    pack .fr.bar.bk -padx 5 -pady 5 -side left -fill none
    button .fr.bar.cl -text "Close" -pady 5 -borderwidth 0 -command { set close 1}
    pack .fr.bar.cl -padx 5 -pady 5 -side left -fill none
    button .fr.bar.nx -text "Next >>" -pady 5 -borderwidth 0 -command nextFile
    pack .fr.bar.nx -padx 5 -pady 5 -side right -fill none
    vwait close
    destroy .fr
}

最新更新