[Rd] possible tcltk event loop problem

Peter Dalgaard p.dalgaard at biostat.ku.dk
Mon Nov 3 22:58:01 CET 2008


John Fox wrote:
> Dear list members,
> 
> Rich Heiberger reported to me last week that the Messages window in the
> Rcmdr GUI was freezing -- that is, messages posted to this window didn't
> appear -- under Windows and R 2.8.0. I was able to confirm this problem on
> three Windows systems, one using Vista and the other two XP. In each case, I
> used R 2.8.0 and Rcmdr 1.4-4 (the current version). The problem doesn't
> occur with R 2.7.2 and Rcmdr 1.4-4. Nor does it occur on my Mac OS/X and
> Ubtuntu Linux systems. In my case, the problem occurred only using Rgui, not
> under Rterm. Rich experienced the problem with both Rgui and Rterm. On the
> other hand, Erich Neuwirth tells me that the Messages window works fine for
> him generally under Windows with R 2.8.0 and Rcmdr 1.4-4, so whatever the
> source of the problem, it doesn't always manifest itself. Some detail, and a
> kludgy solution appear below.
> 
> What's odd is that the Rcmdr has three similar windows -- Script, Output,
> and Messages, created by the following code:
> 
> For the messages window:
> 
>     messagesFrame <- tkframe(.commander)
>     putRcmdr("messagesWindow", tktext(messagesFrame, bg="lightgray",
>         font=getRcmdr("logFont"), height=3, width=log.width, wrap="none"))
>     .messages <- MessagesWindow()
>     messagesXscroll <- ttkscrollbar(messagesFrame, orient="horizontal",
>         command=function(...) tkxview(.messages, ...))
>     messagesYscroll <- ttkscrollbar(messagesFrame,
>         command=function(...) tkyview(.messages, ...))
>     tkconfigure(.messages, xscrollcommand=function(...)
> tkset(messagesXscroll, ...))
>     tkconfigure(.messages, yscrollcommand=function(...)
> tkset(messagesYscroll, ...))
> 
> For the script window (note that "log" is a hold-over from earlier
> terminology):
> 
>     logFrame <- tkframe(CommanderWindow())
>     putRcmdr("logWindow", tktext(logFrame, bg="white",
> foreground=getRcmdr("log.text.color"),
>         font=getRcmdr("logFont"), height=log.height, width=log.width,
> wrap="none", undo=TRUE))
>     .log <- LogWindow()
>     logXscroll <- ttkscrollbar(logFrame, orient="horizontal",
>         command=function(...) tkxview(.log, ...))
>     logYscroll <- ttkscrollbar(logFrame,
>         command=function(...) tkyview(.log, ...))
>     tkconfigure(.log, xscrollcommand=function(...) tkset(logXscroll, ...))
>     tkconfigure(.log, yscrollcommand=function(...) tkset(logYscroll, ...))
> 
> For the output window:
> 
>     outputFrame <- tkframe(.commander)
> 
>     putRcmdr("outputWindow", tktext(outputFrame, bg="white",
> foreground=getRcmdr("output.text.color"),
>         font=getRcmdr("logFont"), height=output.height, width=log.width,
> wrap="none", undo=TRUE))
>     .output <- OutputWindow()
>     outputXscroll <- ttkscrollbar(outputFrame, orient="horizontal",
>         command=function(...) tkxview(.output, ...))
>     outputYscroll <- ttkscrollbar(outputFrame,
>         command=function(...) tkyview(.output, ...))
>     tkconfigure(.output, xscrollcommand=function(...) tkset(outputXscroll,
> ...))
>     tkconfigure(.output, yscrollcommand=function(...) tkset(outputYscroll,
> ...))
> 
> Note that the functions MessagesWindow(), LogWindow(), and OutputWindow()
> simply return their respective tk windows.
> 
> These windows are also similarly placed in the master Rcmdr window (slightly
> edited):
> 
>     tkgrid(.log, logYscroll, sticky="news", columnspan=2)
>     tkgrid(logXscroll)
>     tkgrid(logFrame, sticky="news", padx=10, pady=0, columnspan=2)
> 
>     tkgrid(.output, outputYscroll, sticky="news", columnspan=2)
>     tkgrid(outputXscroll, columnspan=1 + (.log.commands &&
> !.console.output))
>     tkgrid(outputFrame, sticky="news", padx=10, pady=0, columnspan=2)
> 
>     tkgrid(.messages, messagesYscroll, sticky="news", columnspan=2)
>     tkgrid(messagesXscroll)
>     tkgrid(messagesFrame, sticky="news", padx=10, pady=0, columnspan=2)
> 
> I was able successfully to write directly to the script and output windows:
> 
>> tkinsert(LogWindow(), "end", "\n testing \n")
> <Tcl>  
> 
>> tkinsert(OutputWindow(), "end", "\n testing \n")
> <Tcl> 
> 
> But writing to the message window, though it produced no error, also had no
> visible effect:
> 
>> tkinsert(MessagesWindow(), "end", "\n testing \n")
> <Tcl>
> 
> Checking the contents of the Messages window via tkget(MessagesWindow(),
> "1.0", "end") revealed, however, that the text should have been there.
> 
> Suspecting a timing/event-loop-synchronization issue, I inserted a delay
> into the function that sends text to the Messages window; here's a
> simplified version of that function:
> 
> Message <- function(message, type=c("note", "error", "warning")){
> 	Sys.sleep(0.01)
> 	.message <- MessagesWindow() 
> 	if (!missing(message)) {
> 		tkinsert(.message, "end", paste("\n", message, "\n")) 
> 		tkyview.moveto(.message, 1.0) 
> 	} 
> }
> 
> The 0.01 second delay is apparently sufficient to fix the problem.
> 
> I'm reporting the problem because I suspect that there's some issue with
> tcltk in the Windows version of R 2.8.0 (though I didn't see anything in the
> CHANGES or NEWS file to suggest this).
...

Hmm, does it help with a suitably placed tcl("update") or 
tcl("update","idletasks")?

-- 
    O__  ---- Peter Dalgaard             Øster Farimagsgade 5, Entr.B
   c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K
  (*) \(*) -- University of Copenhagen   Denmark      Ph:  (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)              FAX: (+45) 35327907



More information about the R-devel mailing list