An Introduction To Embedded Tk (page 14 of 32)

[Previous Page][Next Page][Table of Contents]

7.2 Moving Information From C To Tcl/Tk

We've seen how ET_STR(), ET_INT() and ET_DBL() can be used to pass values from Tcl/Tk back to C. But how do you go the other way and transfer C variable values into Tcl/Tk? ET has a mechanism to accomplish this too, of course.

Within the argument to any ET() function (or ET_STR() or ET_INT() or ET_DBL()), the string ``%d(x)'' is special. When ET sees such a string, it evalutes the integer C expression ``x'', converts the resulting integer into decimal, and substitutes the integer's decimal value for the original string. For example, suppose you want to initialize the Tcl/Tk variable named nPayment to be twelve times the value of a C variable called nYear. You might write the following code:

    ET( set nPayment %d(12*nYear) );
As another example, suppose you want to draw a circle on the canvas .cnvs centered at (x,y) with radius r. You could say:
    id = ET_INT( .cnvs create oval %d(x-r) %d(y-r) %d(x+r) %d(y+r) );
Notice here how the ET_INT() function was used to record the integer object ID returned by the Tcl/Tk canvas create command. This allows us to later delete or modify the circle by referring to its ID. For example, to change the fill color of the circle, we could execute the following:
    ET( .cnvs itemconfig %d(id) -fill skyblue );

If you want to substitute a string or floating-point value into an ET() argument, you can use %s(x) and %f(x) in place of %d(x). The names of these substitutions phrases were inspired by the equivalent substitution tokens in the standard C library function printf(). Note, however, that you cannot specify a field-width, precision, or option flag in ET() like you can in printf(). In other words, you can use conversions like %-10.3f in prinf() but not in ET(). The ET() function will accepts only specification, such as %f.

But the ET() function does support a conversion specifier that standard printf() does not: the %q(x) substitution. The %q works like %s in that it expects its argument to be a null-terminated string, but unlike %s the %q converter inserts extra backslash characters into the string in order to escape characters that have special meaning to Tcl/Tk. Consider an example.

  char *s = "The price is $1.45";
  ET( puts "%q(s)" );
Because %q(s) was used instead of %s(s), an extra backslash is inserted immediately before the ``$''. The command string passed to the Tcl/Tk interpreter is therefore:
  puts "The price is \$1.45"
This gives the expected result. Without the extra backslash, Tcl/Tk would have tried to expand ``$1'' as a variable, resulting in an error message like this:
  can't read "1": no such variable
In general, it is always a good idea to use %q(...) instead of %s(...) around strings that originate from outside the program--you never know when such strings may contain a character that needs to be escaped.

[Next Page][Table of Contents]