Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Changing state for gridded Entry?

by cniggeler (Sexton)
on Jun 10, 2023 at 16:15 UTC ( [id://11152731] : perlquestion . print w/replies, xml ) Need Help??

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

Hi, I am working on existing Perl/Tk package, quite large, and have a need for a text box that can be grayed out (e.g., until a checkbox is checked elsewhere). The existing code has a combo Label+Entry element which lines up everything nicely BUT I'm having trouble getting to the state of the Entry widget. Here is a boiled down test case:
use Tk; my $test1; my $var = "55"; $mw = MainWindow->new(); $FrameOpt = $mw -> Frame; my $exit_b = $mw->Button(-text => 'Exit', -command => sub { exit })->pack; $mw->Button(-text => "Toggle Textbox", -command => sub { my $state = $test1 -> Entry -> configure(-state); print "$state\n"; if ($state eq "disabled") { $test1 -> Entry -> configure(-state => 'normal') } else { $test1 -> Entry -> configure(-state => 'disabled') } })->pack; sub GuiTextEntryLabelOnLeftCreate { my ($frame, %x_args) = @_; my $label; my $text = $x_args{'-text'}; delete $x_args{'-text'}; $label = $frame -> Label ( -text => $text, -foreground => "black" ) -> grid ( $frame -> Entry (%x_args) , -sticky => 'w' , -pady => 2 ); $label; } $test1 = &GuiTextEntryLabelOnLeftCreate ( $FrameOpt , -text => "Test value" , -textvariable => \$var , -width => 6, -state => "disabled", -foreground => "gray" ); $FrameOpt->pack; MainLoop();
Output:
ARRAY(0x67e4b98)
As you can see, I'm having trouble isolating the state of the Entry widget inside the combo: $state is actually an array, and if I print the array I can see "normal" as one of the array elements, which is incorrect, so for sure it's not the correct state. Is there a way for me to get access to Entry -> state, or do I have to create some other combo widget with easier access? Thanks!

Replies are listed 'Best First'.
Re: Changing state for gridded Entry?
by NetWallah (Canon) on Jun 10, 2023 at 17:48 UTC
    According to the documentation, you should be using
    my $state = $test1 -> Entry -> cget('-state');
    to get the scalar current VALUE.

    The configure('-state') returns a 5-element array, with the last element containing the value.

                    "These opinions are my own, though for a small fee they be yours too."

      Thank you for the information! But, if I make the correction and run the code, I get a result of "normal", yet as you can see near the bottom in the call to create the widget, the state is set to "disabled"! And the fact I can't click in the textbox to change the 55 means to me it is indeed in the disabled state...

      Further, the toggle button does not toggle between normal and disabled, so apparently $test1 -> Entry is not the "right" Entry... ?

        Fixed your code:
        use strict; use warnings; use Tk; my $test1; my $var = "55"; my $mw = MainWindow->new(); my $FrameOpt = $mw -> Frame; my $exit_b = $mw->Button(-text => 'Exit', -command => sub { exit })->pack; $mw->Button(-text => "Toggle Textbox", -command => sub { my ($entry) = grep { $_->class eq "Entry" } $FrameOpt->ch +ildren; $entry-> configure(-state => $entry->cget('-state') eq "d +isabled" ? 'normal' : 'disabled'); })->pack; sub GuiTextEntryLabelOnLeftCreate { my ($frame, %x_args) = @_; my $label; my $text = $x_args{'-text'}; delete $x_args{'-text'}; $label = $frame -> Label ( -text => $text, -foreground => "black" ) -> grid ( $frame -> Entry (%x_args) , -sticky => 'w' , -pady => 2 ); $label; } $test1 = GuiTextEntryLabelOnLeftCreate ( $FrameOpt , -text => "Test value" , -textvariable => \$var , -width => 6, -state => "disabled", -foreground => "gray", ); $FrameOpt->pack; MainLoop();
        Your problem was that $test1 did not have any "Entry" .. the entry is a child of $FrameOpt.

                        "These opinions are my own, though for a small fee they be yours too."

Re: Changing state for gridded Entry?
by kcott (Archbishop) on Jun 10, 2023 at 18:05 UTC

    G'day cniggeler,

    "... state of the Entry ... is actually an array ..."

    Your underlying problem is that you're calling configure() where you should be calling cget(). Take a look at Tk::options; from the SYNOPSIS:

    $value = $widget->cget('-option'); ... @list = $widget->configure('-option');

    That's why you're getting an array.

    There's a lot of other problems with the code you presented. I'd start by putting the following before the code you have there and fixing all of the issues it tells you about. See "perlintro: Perl introduction for beginners" if this code is unfamiliar to you.

    use strict; use warnings;

    You should also remove leading '&'s from subroutine calls unless you know exactly what you're doing and can explain fully why you're doing it. See "perlsub: Perl subroutines".

    "... a checkbox is checked elsewhere ..."

    Your code doesn't contain any references to Tk::Checkbutton. There could be some other problem(s) there but, without seeing the code, it's impossible to tell.

    — Ken

      Hi, thanks for your reply.

      Context is everything:

      - I stated this was boiled down to a test case

      - The actual text was, "e.g., a checkbox is checked elsewhere"

      In a separate comment to the other responder, my main concern is that $test1 -> Entry is not actually pointing to the correct Entry! Do you have a suggestion for that?
        "Do you have a suggestion for that?"

        I see no evidence that you've taken any notice of the suggestions I've already made. Making more suggestions would seem to have little merit.

        — Ken