5

I have a script along the lines of:

if (!require(tcltk2)) {install.packages('tcltk2', repos="http://cran.us.r-project.org"); require(tcltk2)}

base <- NULL
done <- tclVar(0)

quasitelgui <- function(inputfile = NULL)
{
    base <- tktoplevel()
    tkwm.title(base, "QuasiTel")

    # Files
    file.frm <- tkframe(base, borderwidth=2)
    datafile.lbl <- tklabel(file.frm, text="Data")
    datafile.entry <- tkentry(file.frm, state="readonly")
    datafile.btn <- tkbutton(file.frm, text="Browse...")
    tkgrid(datafile.lbl, datafile.entry, datafile.btn)
    tkgrid.configure(datafile.lbl, sticky="e")
    tkgrid.configure(datafile.entry, sticky="ew", padx=1)
    tkgrid.columnconfigure(file.frm, 1, weight=1)
    tkgrid(file.frm)
    tkgrid.configure(file.frm, sticky="ew")

    # Main
    main.frm <- tkframe(base, borderwidth=2)
    g1.lbl <- tklabel(main.frm, text="Group 1")
    g2.lbl <- tklabel(main.frm, text="Group 2")
    tkgrid(g1.lbl, g2.lbl)

    q.btn <- tkbutton(bott.frm, text="Quit", command=function() tclvalue(done) <- 1)
    tkbind(base,"<Destroy>", function() tclvalue(done) <- 2)
    tkgrid(filter.lbl, columnspan=2)
    tkgrid(filter.entry)
    tkgrid(ok.btn, q.btn)
    tkgrid.configure(ok.btn, q.btn, padx=1)
    tkgrid(bott.frm)
    tkgrid.columnconfigure(base, 0, weight=1)

    if (length(inputfile) > 0) { datafile.open(inputfile) }
}

cmd.args <- commandArgs(trailingOnly=TRUE)

if (length(cmd.args) > 0) {
    quasitelgui(gsub("\\\\", "/", cmd.args[1]))
} else {
    quasitelgui()
}

tkfocus(base)
tkwait.variable(done)
tkdestroy(base)

I'm running it via rscript from another GUI. I want the window to grab focus when it starts. Tkfocus doesn't do it.

Matt Chambers
  • 2,229
  • 1
  • 25
  • 43

3 Answers3

5

Not focus, but raise:

> library(tcltk)
Loading Tcl/Tk interface ... done
> w1 <- tktoplevel()
> w2 <- tktoplevel()
> tkraise(w1)
jverzani
  • 5,600
  • 2
  • 21
  • 17
  • This doesn't seem to do anything for me. If I change tkfocus to tkraise, nothing changes. My GUI launching rscript stays on top. – Matt Chambers Mar 08 '12 at 22:08
  • 3
    You might try this too: tcl("wm", "attributes", w1, topmost=TRUE) to "Specifies whether this is a topmost window (displays above all other windows)." Though the docs say this is window manager dependent. – jverzani Mar 09 '12 at 12:42
  • Great, that worked: `tcl("wm", "attributes", base, topmost=TRUE); tcl("wm", "attributes", base, topmost=FALSE)` – Matt Chambers Mar 09 '12 at 15:55
  • I think `tkraise` does not work since the GUI is started in separate process (see description in the question). If both windows are created in the same process (session) of R it should work. – R Yoda Jul 07 '16 at 09:24
0

In MS Windows you can follow this way:

info_sys <- Sys.info() # sniff the O.S.

if (info_sys['sysname'] == 'Windows') { # MS Windows trick
 shell("powershell -command [void] [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') ; [Microsoft.VisualBasic.Interaction]::AppActivate('The title of your window') ")
}
0

I think jverzani is correct is that many if not all (contemporary) GUI systems (I mean, OS/desktop level, not GUI toolkits) prevent focus stealing. A new process which wants to grab focus is a perfect case of a focus stealing attempt, so I'm inclined to think that if your script, Matt, runs in another process, you can't expect it to actually grab focus. There are system-dependent ways to draw user attention to a particular window but I doubt they are directly supported by Tk.

Community
  • 1
  • 1
kostix
  • 51,517
  • 14
  • 93
  • 176