gbertrand has asked for the wisdom of the Perl Monks concerning the following question:

Dear perl monks, I have a perl program with a Tk Gui. The program runs fine when launched with perl my_prog.pl. However, I have packed it using pp and now I face the problem described below.

My program uses the getOpenFile method to ask the user to select a file to be opened. In the packed version of my program, the opened file selection window does not list any file (but it should!), whereas it listed all the files, as required, in the original program.

The specific error message that I get is the following:
~/svn/my_prog> FLT.bin XS_Tk__Callback_Call error:must specify one of -data, -file, -array or + -id at Tk/Image.pm line 21. Tk::Error: must specify one of -data, -file, -array or -id at Tk/Image +.pm line 21. Tk callback for image Tk::Image::new at Tk/Image.pm line 21 Tk::Image::__ANON__ at Tk/Image.pm line 63 Tk::FBox::Update at Tk/FBox.pm line 402 Tk::After::once at Tk/After.pm line 89 [once,[{},after#17,idle,once,[{},Update]]] ("after" script) XS_Tk__Callback_Call error:must specify one of -data, -file, -array or + -id at Tk/Image.pm line 21.
Except for this problem, the program works fine. I have not managed to solve this problem by myself, so, I would really appreciate any help. Thanks!

Best regards, GB

Replies are listed 'Best First'.
Re: perl, Tk GUI, problem with getOpenFile, in a packed program
by Anonymous Monk on Jul 17, 2009 at 10:20 UTC
      Thanks for your answer.

      I have tried to run the program without the initialdir option. The problem persists.
Re: perl, Tk GUI, problem with getOpenFile, in a packed program
by lamprecht (Friar) on Jul 17, 2009 at 22:06 UTC
    Hi,

    what do you get with a minimal testcase like this one:

     pp -o test.bin -e 'use Tk; use Tk::Bitmap; tkinit->getOpenFile'

    Cheers, Christoph

      Dear Christoph,

      your simple example (pp -o test.bin -e 'use Tk; use Tk::Bitmap; tkinit->getOpenFile') works fine.

      An important additional information: during the "compilation" process with pp, my program is run twice (I don't know why, I have not fully understood the compilation options yet). The first run corresponds to the .par file, I think. During this run, the file selection window lists all the files. However, during the second run (the .bin) the window does not list any file.

      Here is the compilation option I use to produce the .bin:
      pp -o FLT.bin   -a my_module.pm -C -x -vvv my_prog.pl
      
      Best regards,

      Gilles
        Hi,

        Given the program

        use warnings; use strict; use Tk; use Tk::Bitmap; my $mw = MainWindow->new(); $mw->getOpenFile(); MainLoop;

        packing with

        pp -o test.exe -C -x -vvv test.pl

        I can't reproduce this. I see the program running once during packing as documented when using the -x switch. Note however, that -x does not make so much sense in a Tk program, where lots of modules are loaded on demand. The static dependency checks of Module::ScanDeps work quite well given that you explicitly use/require the needed modules or instantiate them like so:$mw->MyWidget(). Also if you write require my_module; in my_program.pl you do not need to add my_module.pm using the -a switch. I would recommend, that you try to strip down your program to get to the point where the packing works. Maybe this will help to track down the problem.

        Cheers Christoph

Re: perl, Tk GUI, problem with getOpenFile, in a packed program
by Marshall (Canon) on Jul 18, 2009 at 06:39 UTC
    I don't know if this will help or not, BUT I find that when making an .exe with ActiveState some work is required. When I run from the command line, I can have a XXX.pl that just has "use Tk;". When something shows up that the autoloader needs, it gets loaded. To get that same program to compile to an standalone .exe I need lots of "use" statements to force modules into the "compiled version":
    use Tk; use Tk::LabFrame; use Tk::Listbox; use Tk::Scrollbar; use Tk::Button; use Tk::Menubutton; use Tk::Menu; use Tk::Widget; use Tk::Label; use Tk::Entry;
    It could very well be that you don't have enough "use" statements. These statements force compilation and inclusion of the code into the .exe file. The above are very standard widgets. Stick those "use statements" into your source. And see what happens. In std environment, "use Tk;" is enough, but that is not enough for a "compiled version".
      Dear Marshall,

      Following your advice, I have added all the listed inclusions. Unfortunately, they did not solve my problem in the .bin.

      Thanks,

      Gilles
        Well sorry to hear that. This can get to be a mess! The first time I did this, it took me a week to get a fully functional .exe file. You are getting run-time errors and I would try to find the fewest number of mouse clicks that creates the error reliably. Then from there, put print statements in the code and just slug through it to find what isn't getting loaded - something is missing from the .exe version that the "normal" version can run via the autoloader. You will have to figure out what that "something" is and force it into the .exe file. I'm sorry that the "simple" ideas didn't work.
      That isn't normally required with PAR/pp
        The problem is solved!

        I have added several "use" statements explicitly to be sure that they would be packed within the binary. I have also changed the pp options that I used, which were probably wrong. I am not quite sure of the origin of my problem, but anyway, it's solved.

        Many thanks for your help.