开发者

How to use C++/TCL and C++/TK at the same time, in the same program?

开发者 https://www.devze.com 2023-03-17 05:54 出处:网络
So it is great of C++/TCL to provide us with easy manageable in TCL C++ functions and classes via APIs like:

So it is great of C++/TCL to provide us with easy manageable in TCL C++ functions and classes via APIs like:

#include "cpptcl.h"
#include <iostream>
#include <string>
using namespace std;
using namespace Tcl;
void hello()
{
     cout << "Hello C++/Tcl!" << endl;
}
int main()
{
     interpreter i;
     i.def("hello", hello);
     string script = "for {set i 0} {$i != 4} {incr i} { hello }";
     i.eval(script);
}

At he same time its great to have an system event loop handled in C++/Tk with api's like

#include <string>
#include "cpptk.h"

int main(int argc, char *argv[])
{
    std::string script = 
        "package require Tcl 8.5\n"
        "package require Tk 8.5\n"
        "ttk::button \".b\" -text \"Say Hello\"\n"
        "pack \".b\" -padx 20 -pady 6\n"
        ;
    Tk::details::Expr(script, true);
    Tk::runEventLoop();
}

So as you can see one is great for API creation another for GUI rendering.

I want to find a way to mix them to have for example such code working:

#include "cpptcl.h"
#include "cpptk.h"
#include <iostream>
#include <string>
using namespace std;
using namespace Tcl;
void hello()
{
     cout << "Hello C++/Tcl!" << endl;
}
int main()
{
     interpreter i;
     i.def("hello", hello);
     string script = 
        "package require Tcl 8.5\n"
        "package require Tk 8.5\n"
        "ttk::button \".b\" -text \"Say Hello\" -command hello \n"
        "pack \".b\" -pa开发者_开发问答dx 20 -pady 6\n"
        ;
    Tk::details::Expr(script, true);
    Tk::runEventLoop();
}

How to do such thing possible? How to mix C++/TCL and C++/Tk?

Updete:

And so we have done it. Required some CPP/TCL and CPP/Tk sorurce code fixing, see our svn, and my answer for example of use.


You can use UI callbacks to do complicated things, including running other Tcl code:

#include "cpptcl.h"
#include "cpptk.h"
#include <iostream>
#include <string>
using namespace std;
using namespace Tcl;

class TclHost
{
  interpreter i;
  static TclHost* singleton;

  static void hello()
  {
     cout << "Hello C++/Tcl!" << endl;
  }

  static void runScript()
  {
     singleton->i.def("hello", &TclHost::hello);
     string script = "for {set i 0} {$i != 4} {incr i} { hello }";
     singleton->i.eval(script);
  }

public:
  int main()
  {
     singleton = this;
     i.def("runscript", &TclHost::runScript);
     string script = 
        "package require Tcl 8.5\n"
        "package require Tk 8.5\n"
        "ttk::button \".b\" -text \"Run a script\" -command runscript\n"
        "pack \".b\" -padx 20 -pady 6\n"
        ;
    Tk::details::Expr(script, true);
    Tk::runEventLoop();

    return 0;
  }
};

TclHost* TclHost::singleton;

int main(void)
{
  TclHost().main();
}

You'll also want to look at other callbacks, including timers and file I/O, that the Tcl/Tk event loop supports.


So we have done it...) here is our svn with updated, working C++/Tk and C++/TCL, patched for work with each other, corrected from some errors that were on official sourceforge site.

And here is code sample inspired by Ben:

#include "cpptcl/cpptcl.h"
#include "cpptk/cpptk.h"
#include <iostream>
#include <string>
Tcl::interpreter i(Tk::getInterpreter());
void hello()
{
    std::cout << "Hello C++/Tcl!" << std::endl;
}
void runScript()
{
    i.def("hello", hello);
    std::string script = "for {set i 0} {$i != 4} {incr i} { hello }";
    i.eval(script);
}
int main(int argc, char *argv[])
{

    i.def("runscript", runScript);
    std::string script = 
        "package require Tcl 8.5\n"
        "package require Tk 8.5\n"
        "ttk::button \".b\" -text \"Say Hello\" -command hello \n"
        "ttk::button \".c\" -text \"Run a script\" -command runscript\n"
        "pack \".b\" -padx 20 -pady 6\n"
        "pack \".c\" -padx 20 -pady 6\n"
        ;
    i.eval(script);
    Tk::runEventLoop();
}

Have a good luck in using TCL and Tk!)


Tcl::interpreter i(Tk::getInterpreter());

int main(int argc, char *argv[])
{

    i.def("runscript", runScript);
    std::string script = 
        "package require Tcl 8.5\n"
        "package require Tk 8.5\n"
        "ttk::button \".b\" -text \"Say Hello\" -command hello \n"
        "ttk::button \".c\" -text \"Run a script\" -command runscript\n"
        "pack \".b\" -padx 20 -pady 6\n"
        "pack \".c\" -padx 20 -pady 6\n"
        "after 10 vwait qwerasdfzxcv\n"
        ;
    i.eval(script);
    //Tk::runEventLoop(); //<== if you don't want stock here to make mainthread can keep running. you can add tcl script "after 10 vwait qwerasdfzxcv" as above showed.

}

0

精彩评论

暂无评论...
验证码 换一张
取 消