用户界面-如何在同一程序中同时使用C++/TCL和C++/TK

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

本文关键字:C++ TK TCL 程序 用户界面      更新时间:2023-10-16

因此,C++/TCL通过以下API为我们提供易于管理的TCL C++函数和类是非常棒的:

#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);
}

同时,用类似的api在C++/Tk中处理系统事件循环也很棒

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

正如您所看到的,一个非常适合API创建,另一个非常适用于GUI渲染。

我想找到一种方法来混合它们,例如这样的代码工作:

#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.5n"
        "package require Tk 8.5n"
        "ttk::button ".b" -text "Say Hello" -command hello n"
        "pack ".b" -padx 20 -pady 6n"
        ;
    Tk::details::Expr(script, true);
    Tk::runEventLoop();
}

如何使这样的事情成为可能?如何混合C++/TCL和C++/Tk?

Updete:

所以我们已经做到了。需要一些CPP/TCL和CPP/Tk源代码修复,请参阅我们的svn,以及我的使用示例答案。

您可以使用UI回调来做复杂的事情,包括运行其他Tcl代码:

#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.5n"
        "package require Tk 8.5n"
        "ttk::button ".b" -text "Run a script" -command runscriptn"
        "pack ".b" -padx 20 -pady 6n"
        ;
    Tk::details::Expr(script, true);
    Tk::runEventLoop();
    return 0;
  }
};
TclHost* TclHost::singleton;
int main(void)
{
  TclHost().main();
}

您还需要了解Tcl/Tk事件循环支持的其他回调,包括计时器和文件I/O。

所以我们已经完成了…(这是我们的svn,它具有更新的、可工作的C++/Tk和C++/TCL,经过修补以相互工作,并从官方sourceforge网站上的一些错误中更正。

这是受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.5n"
        "package require Tk 8.5n"
        "ttk::button ".b" -text "Say Hello" -command hello n"
        "ttk::button ".c" -text "Run a script" -command runscriptn"
        "pack ".b" -padx 20 -pady 6n"
        "pack ".c" -padx 20 -pady 6n"
        ;
    i.eval(script);
    Tk::runEventLoop();
}

祝你使用TCL和Tk好运!(

Tcl::interpreter i(Tk::getInterpreter());
int main(int argc, char *argv[])
{
    i.def("runscript", runScript);
    std::string script = 
        "package require Tcl 8.5n"
        "package require Tk 8.5n"
        "ttk::button ".b" -text "Say Hello" -command hello n"
        "ttk::button ".c" -text "Run a script" -command runscriptn"
        "pack ".b" -padx 20 -pady 6n"
        "pack ".c" -padx 20 -pady 6n"
        "after 10 vwait qwerasdfzxcvn"
        ;
    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.

}