How to access and modify a sibling of a Tcl/Tk object in R

我的梦境 提交于 2021-01-29 08:26:59

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!