Get Data Out of a Tcltk Function

Get data out of a tcltk function

Here is a modification of your function:

inputs <- function(){

xvar <- tclVar("")
yvar <- tclVar("")

tt <- tktoplevel()
tkwm.title(tt,"Input Numbers")
x.entry <- tkentry(tt, textvariable=xvar)
y.entry <- tkentry(tt, textvariable=yvar)

reset <- function()
{
tclvalue(xvar)<-""
tclvalue(yvar)<-""
}

reset.but <- tkbutton(tt, text="Reset", command=reset)

submit <- function() {
x <- as.numeric(tclvalue(xvar))
y <- as.numeric(tclvalue(yvar))
e <- parent.env(environment())
e$x <- x
e$y <- y
tkdestroy(tt)
}
submit.but <- tkbutton(tt, text="submit", command=submit)

tkgrid(tklabel(tt,text="Enter Two Inputs"),columnspan=2)
tkgrid(tklabel(tt,text="Input1"), x.entry, pady = 10, padx =10)
tkgrid(tklabel(tt,text="Input2"), y.entry, pady = 10, padx =10)
tkgrid(submit.but, reset.but)

tkwait.window(tt)
return(c(x,y))
}

Now run the function like:

myvals <- inputs()

Now enter your 2 values and click "Submit", then look at the myvals variable, it contains your 2 values.

tcltk R - how to access value returned by function

I found a solution, at first I thought its not really a "clean" way of doing it, but even in the offical documentation it is done this way.
Simply create a global variable using <<- :

myFun1 <- function() { 
compVal <<- 2*3
}

getting values in R from tkentry() widgets

I have found an answer (courtesy of Greg Snow enter link description here

sorry for answering my own Q, but editing was impossible through misplaced error calls "you're text appears to contain code blablabla" whilst I correctly designated it (cntrl K).

here's the code

    define.test<-function(){                
# create a function to call upon
require(tcltk)
# make sure tcltk package is active
# define attributes of widget components
t3<- tktoplevel()
# create main (toplevel) widget
tktitle(t3)<-"Statistical power"
# widget looks better with title
fontHead <-tkfont.create(family="times",size=16,weight="bold")
# define font for heading, etc
fontSub <-tkfont.create(family="times",size=14,weight="bold")
fontQ <-tkfont.create(family="times",size=14)
fontQ.s <-tkfont.create(family="times",size=12)
filename <-tclVar("Your test")
# Default testname, to change in widget
groups <-tclVar("")
# empty variable for number of groups, to fill in in widget
test <-""
# empty var for test, to be found by <<- in button function
submit.prop <- function(){
# function for proportional button
test<<-"prop"
# reassign test in higer level
tkdestroy(t3)}
# destroy widget, or nothing happens
submit.scal <- function(){
# function voor scalar button (same as above)
test<<-"scale"
tkdestroy(t3)}
### build widget
tkgrid(tklabel(t3, text="This module will give you insight in the statistical power requirements of your test", font=fontHead), columnspan=6)
# header
tkgrid(tklabel(t3, text=" ")) # empty row
tkgrid(tklabel(t3, text="Please answer the following questions:", font=fontSub), columnspan=6, sticky="w") # sub header
tkgrid(tklabel(t3,text=" "))
tkgrid(tklabel(t3,text="What is the name of your test?", font=fontQ), row=5, column=0, rowspan=1, columnspan=2,sticky="w") #Q1
tkgrid(tkentry(t3, textvariable=filename), row=5, column=2, rowspan=1, columnspan=3, sticky="ew")
# entry for test name(= filename)

tkgrid(tklabel(t3,text=" "))
tkgrid(tklabel(t3,text="How many test-groups do you have?", font=fontQ), row=7, column=0, rowspan=1, columnspan=4, sticky="w")
#Q2
tkgrid(tkentry(t3,textvariable=groups),row=7,column=4,rowspan=1,columnspan=1,sticky="ew") # entry for number of groups to test

tkgrid(tklabel(t3,text=" "))
tkgrid(tklabel(t3,text="What type of differences do you want to test for?",font=fontQ), sticky="w") #Q3
tkgrid(tklabel(t3,text="Proportional differences (e.g. click through rate, bounce rate, gender rate, etc)", font=fontQ.s),row=10,column=0,rowspan=1,columnspan=4, sticky="w" )
tkgrid(tkbutton(t3,text="Proportional",command=submit.prop),row=10,column=4,rowspan=1,columnspan=2, sticky="ew") # define test as proportional
tkgrid(tklabel(t3,text="Scaled differences (e.g. converted value, age, numer of sessions before conversion, etc)", font=fontQ.s),row=11,column=0,rowspan=1,columnspan=4, sticky="w" )
tkgrid(tkbutton(t3,text="Scale",command=submit.scal),row=11,column=4,rowspan=1,columnspan=2, sticky="ew") # define test as scalar

tkfocus(t3) # focus on widget
tkwait.window(t3) # wait for user to give input
return(c(tclvalue(filename),tclvalue(groups),test)) # create character string with user input
}
input <-define.test()
filename <-input[1]
groups <-as.numeric(input[2])
test <-input[3]

Tcl/Tk: scope of variables for a function within a function

When bar1, bar2, ... are called from within foo, their upvar calls will try to link with any proc-local variables of the executed foo proc. This is because upvar without level defaults to upvar 1 which denotes the proc's caller (i.e., foo). Your targeted variables in bar.tcl, however, reside in the global namespace and not within foo. Hence, there are no variables linked by alpha, bravo.

Rewrite your upvar occurrences as upvar #0 ..., with #0 indicating the global, top-level namespace, e.g.:

upvar "#0" a alpha

This is equivalent to using global a modulo a variable alias (alpha).

how to use Tcl/Tk bind function on Tkinter's widgets in Python?

If you are asking how to create a binding that makes use of the "data" field (ie: %d substitution), you will have to call some tcl code to make that happen. This requires two steps: create a tcl command that calls a python function, and use tcl to bind an event to that function.

First, let's create a python program that can create an event and set the "data" field (this assumes the existence of a global variable named root, which we'll create later). When this function is called, it will generate a custom event with the data field populated by a string.

def create_custom_event():
root.event_generate("<<Custom>>", data="Hello, world")

Next, lets create a program to call that function on a button press

import tkinter as tk
root = tk.Tk()
button = tk.Button(root, text="click me", command=create_custom_event)
button.pack(side="top", padx=20, pady=20)
root.mainloop()

Next we need to create a function that is called when the event is generated. We plan to set the data field, so this function must accept one value which is the value of the %d substitution.

def callback(detail):
print("detail: %s" % detail)

Because you want to use the %d substitution we'll have to create the binding via Tcl. However, tcl doesn't automatically know about our python functions so we have to register the function with tcl. Then it's just a matter of calling bind via the tcl interface to set up the binding.

The first step, then, is to register the callback. We've already created the function, we just have to create a tcl function that calls this function. Fortunately, tkinter gives us a way to do that with the register command. You use it like this:

cmd = root.register(callback)

This takes a python function (callback in this case), and creates a tcl command which will call that function. register returns the name of that tcl command which we store in a variable named cmd (the name is irrelevant)

Next, we need to set up a binding via Tcl to call this command. If we were doing this in an actual tcl script, the command would look something like this (where "." represents the root window):

bind . <<Custom>> {callback %d}

The python equivalent is this:

root.tk.call("bind", root, "<<Custom>>", cmd + " %d")

Notice that there is a 1:1 correspondence between an argument to call and a tcl argument. Conveniently, the default string representation of a tkinter widget is the internal tcl name, so we can directly use the widget in the call (though, pedantically, perhaps we should use str(root)).

Putting it all together gives us this, which prints out "detail: Hello, world" when you click the button:

import tkinter as tk

def callback(detail):
print("detail: %s" % detail)

def create_custom_event():
root.event_generate("<<Custom>>", data="Hello, world")

root = tk.Tk()

button = tk.Button(root, text="click me", command=create_custom_event)
button.pack(side="top", padx=20, pady=20)

cmd = root.register(callback)
root.tk.call("bind", root, "<<Custom>>", cmd + " %d")

root.mainloop()

Displaying data in a pop up window (table widget) using tcltk in R - why is it dropping the last row of data?

This is a pretty simple fix. Your function looks good, but your widget setup is forgetting to account for the header row when allocating rows to the tk table. Just add a +1 and you should be good:

tt<-tktoplevel()
table1 <- tkwidget(tt,"table",variable=temptable,rows=dim(mtcars)[1]+1,
cols=dim(mtcars)[2],titlerows=1,selectmode="extended",colwidth=10)
tkgrid(table1, pady = 20, padx = 30)

Result:

Sample Image



Related Topics



Leave a reply



Submit