问题
In short:
I use tcltk
package in R. But non-R users may suggest ideas too and provide examples in other language than R.
I have a list of Tcl/Tk objects in R <Tcl> .1.1.1.1 .1.1.1.2 .1.1.1.3
and want to access and modify each object separately. How can I do it?
Or If I have button A object, how can I access and modify button B object?
Details:
I have the following widget:
The code to create it:
library(tcltk)
top <- tktoplevel()
frame_1 <- tkframe(top)
tkgrid(frame_1)
frame_n <- tkframe(frame_1)
tkgrid(frame_n)
b1 <- ttkbutton(frame_n, text = "button A")
b2 <- ttkbutton(frame_n, text = "button B")
b3 <- ttkbutton(frame_n, text = "button c")
tkgrid(b1, b2, b3)
Let's say I can access only b1
:
class(b1)
# [1] "tkwin"
I want to access and modify the siblings of b1
as if I had objects b2
, etc. (for example):
tkcget(b2, "-text") # Get text
tkconfigure(b2, text = "New B") # Change text
By using tkwinfo
, I managed to access the parent of b1
and get a list of siblings (I'm not sure if technically it is a "list"), but I don't know, how to access/modify each of them one by one:
(parent_of_b1 <- tkwinfo("parent", b1))
# <Tcl> .1.1.1
(siblings_of_b1 <- tkwinfo("children", parent_of_b1))
# <Tcl> .1.1.1.1 .1.1.1.2 .1.1.1.3
class(siblings_of_b1)
# "tclObj"
My attempt results in error:
tkcget(siblings_of_b1, "-text")
# Error in structure(.External(.C_dotTclObjv, objv), class = "tclObj") :
# [tcl] invalid command name ".1.1.1.1 .1.1.1.2 .1.1.1.3".
Most probably I don't know the way to subset the object. How can I do it?
UPDATE: based on the comments of @Donal Fellows, I found the solution.
Function as.character()
does the job.
(my_tcl_object <- tkwinfo("children", parent_of_b1))
# <Tcl> .1.1.1.1 .1.1.1.2 .1.1.1.3
as.character(my_tcl_object)
## [1] ".1.1.1.1" ".1.1.1.2" ".1.1.1.3"
In this situation, tclvalue()
+ strsplit()
works as well:
strsplit(tclvalue(my_tcl_object), " ", fixed = TRUE)[[1]]
## [1] ".1.1.1.1" ".1.1.1.2" ".1.1.1.3"
But, in general (for other problems), as.character()
vs. tclvalue()
+ strsplit()
may give different results.
回答1:
The issue is that the winfo children
subcommand (using the underlying Tcl name) returns a Tcl list of widget identifiers. In general, this is a bit messy to deal with from other languages (because of potential issues with handling quoting rules) but because the generated widget identifiers just contain ASCII digits and .
characters and the separators are just single spaces, simply splitting by space will give you the right thing.
(siblings_of_b1 <- strsplit(tkwinfo("children", parent_of_b1), " ", fixed = TRUE))
You'll need to iterate over the resulting list, of course. Multiple siblings are multiple siblings. (Also, don't forget that this includes b1 itself; you've not asked for the actual siblings, but rather the children of the parent.)
来源:https://stackoverflow.com/questions/54042767/how-to-access-and-modify-a-sibling-of-a-tcl-tk-object-in-r