perldialogtk-toolkitperltk

How do I create a Tk::Dialog for Yes/No user input?


I am trying to use a simple Tk Yes/No Dialog in Perl. I have the following script based upon the example from metacpan:

#!/usr/bin/perl

use strict;
use warnings;
use Tk::Dialog;

my $mw->Dialog->new();
my $dialog = $mw->Dialog(-text => 'Save file?',
                      -bitmap => 'question',
                      -title => 'Save File Dialog',
                      -default_button => 'Yes',
                      -buttons => [qw/Yes No Cancel/]);
print "$dialog\n";

When I run it, it throws the following error:

Can't call method "Dialog" on an undefined value at script.pl line N.

What am I doing wrong?


Solution

  • Since I'm on a macOS, I had to jump a few hoops to get this thing running but basically the error you are encountering is because of the way you are trying to instantiate the Dialog object.

    The $mw->Dialog->new() syntax you used is not correct.

    You need to first create the main window using MainWindow->new and then use it to create the Dialog object.

    This should work:

    #!/urs/bin/perl
    
    use strict;
    use warnings;
    use Tk;
    use Tk::Dialog;
    
    my $mw = MainWindow->new();   # Create main window first
    
    # Create the Dialog
    my $dialog = $mw->Dialog(-text => 'Save file?',
                          -bitmap => 'question',
                          -title => 'Save File Dialog',
                          -default_button => 'Yes',
                          -buttons => [qw/Yes No Cancel/]);
    
    my $answer = $dialog->Show();
    
    print "$answer\n";
    
    MainLoop();
    

    Make sure your x11 server is running.

    I got to see this:

    enter image description here

    EDIT: How to run the script on macOS?

    1. Install https://www.xquartz.org/
    2. Start XQuartz from the Applications folder. Once it's running, you should see an xterm window. This indicates that the X11 server is active.
    3. Run the script from the macOS terminal, but make sure your display is set by checking echo $DISPLAY. It should be set to something like :0.