Version 1 of Mixing Tcl/Tk and Xt Event Loops

Updated 2001-10-11 13:26:04

See also: Adding Tk to an Existing Xt Program


George Peter Staplin: The code that follows creates an Xt button and a Tk button, in the same application.


  #include <stdio.h>
  #include <stdlib.h>
  #include <X11/Intrinsic.h> 
  #include <X11/StringDefs.h> 
  #include <X11/Xaw/Command.h>  
  #include <tcl.h>
  #include <tk.h>

  Tcl_Interp *interp;

  void Action (Widget w, XtPointer client_data, XtPointer call_data) { 
  fprintf (stderr, "You pressed me.\n");
  exit (0); 
  }


  int main (int argc, char *argv[]) {
  XtAppContext appContext;
  Widget win, button;
  XEvent event;
  int i = 1;

        char sAppInit[] = "pack [button .b -text \"Hello\"]";

        win = XtVaAppInitialize(
                &appContext,          
                "TclTkXt",           
                NULL, 
                0,                
                &argc, 
                argv,            
                NULL,                   
                NULL);                  

        button = XtVaCreateManagedWidget (
                "XtButton",              
                commandWidgetClass,     
                win,               
                NULL);                  

  interp = Tcl_CreateInterp ();

  Tcl_FindExecutable (argv[0]); /* Does Tcl_FindExecutable behave better *before* Tcl_CreateInterp()? */

        if (Tcl_Init (interp) != TCL_OK) {
        fprintf (stderr, "Tcl_Init error"); 
        exit (1);
        }

        if (Tk_Init (interp) != TCL_OK) {
        fprintf (stderr, "Tk_Init error");
        exit (1);
        }



  XtAddCallback (button, XtNcallback, Action, 0);
  XtRealizeWidget (win);

        if (Tcl_Eval (interp, sAppInit) != TCL_OK) {
        fprintf (stderr, "Tcl_Eval error %s", Tcl_GetStringResult (interp));
        }

        for (;;) {

                if (XtAppPending (appContext) > 0) {
                XtAppNextEvent (appContext, &event);
                XtDispatchEvent (&event);        
                } else {
                Tcl_DoOneEvent (TCL_DONT_WAIT);
                usleep (200);
                }

        }

  return (0);
  }

Here's a package that contains a Makefile and the code above: http://www.xmission.com/~georgeps/TclTkXt.tgz You may need to change the Makefile string -ltcl83 to -ltcl8.3 and Linux users need to add -ldl.

Have fun!


"Event-oriented programming" has background information.