Skip to content

Porting Perl Tk programs to Tcl::pTk

Christopher Chavez edited this page Jul 18, 2019 · 1 revision

(This is currently a draft, and might be incorporated into the POD for Tcl::pTk.)

(Adapted from https://www.perlmonks.org/?node_id=1218860) There are a few ways to try running an existing Perl/Tk program with Tcl::pTk instead. From most to least effort:

  1. substituting all mentions of Tk with Tcl::pTk, i.e. use Tk; with use Tcl::pTk;, any Tk::package or Tk->thing with Tcl::pTk::package or Tcl::pTk->thing, etc.
  2. putting use Tcl::pTk::TkHijack; (BEFORE any existing use Tk;) at the top of the program's main script
  3. running the program's script using the -MTcl::pTk::TkHijack command-line parameter, i.e. perl -MTcl::pTk::TkHijack my_tk_program.pl

The command line parameter approach might be the easiest for testing an entire program without changing any code. That way, the program can still be run with Perl/Tk for comparison, or when something breaks under Tcl::pTk. The use Tcl::pTk::TkHijack; approach has the same effect, though that line will need to be commented out to go back to Perl/Tk. Then, for programs "ready" to be run only with Tcl::pTk (i.e. Tcl::pTk doesn't break for the program) and no longer to be used with Perl/Tk, then the first approach might work better.

In an ideal world, an unmodified Perl/Tk program would work with Tcl::pTk on the first try. Unfortunately, that is often not the reality, as some functionality in Perl/Tk either missing from or not correctly supported by Tcl::pTk. Some functionality in Perl/Tk might be difficult or impossible to implement in Tcl::pTk (or Tcl/Tk and its extensions). However, the hope is that many Perl/Tk programs can still work with Tcl::pTk after some slight tweaking, and that the effort needed will be far less than that of rewriting the program in Tkx syntax, Tcl syntax, or some other widget toolkit. Some of these tweaks can be done while retaining Perl/Tk compatibility, though there is functionality in Tcl::pTk not present in Perl/Tk.

(TODO: list examples of tweaks that may be necessary.)

Also see notes on using Tcl::pTk with macOS aqua.

See the open bug reports for known incompatibilities or missing features. Some features not available in Tcl::pTk:

  • fileevent: currently unavailable for macOS and any other BSD-derived OS: RT #125662. On Linux and Windows, fileevent reads are emulated by polling every 250ms by default.

  • C/XS extensions for Perl/Tk (e.g. [Tk::IDElayout]): since Tcl::pTk is pure Perl, and has no control over the C code of the Tcl/Tk installation it uses, these sorts of extensions are not usable. However, it may be possible to reimplement them using only Perl and relying on any corresponding Tcl/Tk extensions, as done for Tk::TableMatrix → Tcl::pTk::TableMatrix (which requires the TkTable extension for Tcl/Tk to be installed).

  • Tk::Adjuster, due to GeometryRequest unavailable. A better-supported alternative is Tk::Panedwindow.

  • exit: Perl/Tk redefines exit so that it can do some cleanup. Using exit from a Tcl/Tk wrapper like Tcl::pTk, while possibly causing the program to exit without any apparent issue, might trigger a segmentation fault, particularly when used inside a callback subroutine. It is not yet known whether Tcl::pTk can or should properly support exit: see RT #128654. The currently supported alternative is to destroy the main window, i.e. $mw->destroy; this is functionally different from exit, in that it will cause anything appearing after the MainLoop statement to be executed.

Although much of the Perl/Tk documentation was based on the corresponding Tcl/Tk documentation, it may be helpful to refer to more recent Tcl/Tk documentation.

(TODO: put the following in Tcl::pTk POD "BUGS" section)

It may help to reproduce an issue from the widgetTclpTk demo program. It is not uncommon for a bug observed under Tcl::pTk to actually be caused by Tcl/Tk, or an extension for it. To tell if a bug is in Tcl/Tk or just in Tcl::pTk, you may try reproducing the issue in Tcl/Tk (using its widget demo, for example).

Clone this wiki locally