[R-gui] Idle/timer callbacks in tk widgets
Stephen Eglen
S.J.Eglen at damtp.cam.ac.uk
Tue Jan 9 14:08:15 CET 2007
>
> For the archives (and for others if interested) I'll send my test
> script tomorrow to the list.
Here it is.
Stephen
## Simple example of playing a movie in tcltk.
## Tue 09 Jan 2007
## Use the 'after' command to repeatedly call the plot function after
## some delay. (I tried an alternative method for running the movie,
## go.callback2, for those interested, but go.callback seems
## preferable.)
library(tcltk)
## Some dummy data.
npts <- 1000
step.size <- 40 #how many data points to show.
data <- sin(4*pi * 1:npts/npts)
pause.time <- 100 #delay in msec
movie.time <- tclVar(1) # current start time of frame.
movie.show <- tclVar(1) # "1" for on, "0" for off.
show.plot <- function(..., update.win=TRUE) {
## Update the plot window.
## TODO: check that beg/end times are suitable.
start.time <- as.numeric(tclvalue(movie.time))
x <- floor(start.time) + (1:step.size)
plot(x, data[x], ylim=c(-1, 1), bty='n', lwd=3, col='red',
main='dummy data', type='l', yaxt='n')
if ( update.win && (tclvalue(movie.show)=="1")) {
next.time <- start.time + step.size
if (next.time < length(data)) {
## Still have more to show...
tclvalue(movie.time) <- as.character(next.time)
tcl("after", pause.time, show.plot)
} else {
tclvalue(movie.show) == "0" #for consistency.
}
}
}
stop.callback <- function() {
## Callback for the stop button.
tclvalue(movie.show) <- "0"
}
go.callback <- function() {
## Callback for the go button.
tclvalue(movie.show) <- "1"
show.plot()
}
go.callback2 <- function() {
## Alternative callback for the go button. This uses a for loop to
## control the movie; however, while the movie is running, the R
## prompt is blocked (although the tk GUI is still responsive).
print("Alternate go callback")
tclvalue(movie.show) <- "1"
looping <- TRUE
while(looping) {
show.plot(update.win=FALSE)
cur.time <- as.numeric(tclvalue(movie.time))
if ( (tclvalue(movie.show) == "0") || cur.time >= length(data)) {
looping <- FALSE
tclvalue(movie.show) <- "0" #needed iff at end of data.
} else {
Sys.sleep(pause.time/1000) #1000 needed to give time in sec.
tclvalue(movie.time) <-
as.character( cur.time + step.size)
}
}
}
show.plot.scale <- function(...) {
## Callback for the scale widget.
show.plot(update.win=FALSE)
}
movie.window <- function() {
## Create a control window and show it.
## Init the vars?
tclvalue(movie.time) <- "1"
## Create base frame.
base <- tktoplevel()
spec.frame <- tkframe(base, borderwidth=2)
tkwm.title(base, "Movie player")
beg.time <- 1
end.time <- length(data)
scale <- tkscale(spec.frame, command=show.plot.scale,
from = beg.time,
to = end.time,
showvalue=TRUE,
variable=movie.time,
resolution=5,
orient="horiz")
go.but <- tkbutton(spec.frame, text="Go", command=go.callback2)
prev.but <- tkbutton(spec.frame, text="Stop", command=stop.callback)
## Add buttons, one row at a time, using the grid manager.
tkgrid(scale, columnspan=2)
tkgrid(go.but, prev.but)
tkpack(spec.frame)
}
movie.window()
More information about the R-SIG-GUI
mailing list