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.
}
精彩评论