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

First my code:

$BAK_menu -> cascade(-label => "Enter Repos." ); my $menu = $menu_bar -> cget (-menu); my $cm = $BAK_menu -> Menu ( -tearoff => 0 ); ### WORKS DOWN TO ### THIS LINE $BAK_menu -> entryconfigure ( "Enter Repos." , -menu => $cm ); # $cm -> command ( -label => "first" ); # $cm -> command ( -label => "second" ); my $repos = ""; my $REPOS_entry = $cm -> Entry ( -width => 20, -foreground => 'white', -background => 'black', #-textvariable => \$repos ) -> pack(); $BAK_menu -> separator(); $BAK_menu -> command ( -label => "Close", -command => sub { ##$top -> destroy; } ); $menu_bar -> idletasks;

The examples came in very helpful. This is as far as I got. BUT I CAN'T
get the text typed into the Entry() widget. Ideas? Thanks in advance.

Replies are listed 'Best First'.
Re: GETTING the input from a cascading menu
by Fletch (Bishop) on Aug 06, 2021 at 19:14 UTC

    While it's good you've trimmed down things before posting, you've probably trimmed a bit too much. You've omitted any mention of what module(s) you're using so unless someone immediately recognizes what you're using you've limited your possibilities for help.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: GETTING the input from a cascading menu
by kcott (Archbishop) on Aug 09, 2021 at 07:49 UTC

    As you can see from earlier posts, you haven't provided sufficient information for us to help you. I won't say any more about that; however, please read "How do I post a question effectively?" and "Short, Self-Contained, Correct Example" before posting again.

    I suspect you're confusing Tk::Entry with the word "entry" used by Tk::Menu. From its doco (my emphasis):

    "A menu is a widget that displays a collection of one-line entries ... There exist several different types of entries, ... Entries of different types may be combined in a single menu. Menu entries are not the same as entry widgets. In fact, menu entries are not even distinct widgets; the entire menu is one widget. ..."

    You later wrote:

    "I need to get the dirname from Tk::Enter so I can build a command line and execute it."

    [Yes, you did write Tk::Enter. You need to be careful about that sort of thing.]

    I think the following might form the guts of what you're attempting. It's fully functional as is. You'll need to get $dir into your command line, instead of displaying it in a label. Once you have the basic functionality working, add cosmetics (colours, fonts, borders, etc.).

    #!/usr/bin/env perl use strict; use warnings; use Tk; my $mw = Tk::MainWindow::->new(); my $dir = ''; my $menu_F = $mw->Frame()->pack(-fill => 'x'); my $label_F = $mw->Frame()->pack(-fill => 'both', -expand => 1); $label_F->Label(-textvariable => \$dir)->pack; my $menutop = $menu_F->toplevel(); my $menubar = $menutop->Menu(-type => 'menubar'); $menutop->configure(-menu => $menubar); my $file_menu = $menubar->Cascade( -label => 'File', -tearoff => 0, -menuitems => [ [ Button => 'Get Dir', -command => sub { $dir = $mw->chooseDirectory; }], [ Button => 'Exit', -command => sub { exit } ], ], ); MainLoop;

    See also: Tk and Tk::chooseDirectory.

    — Ken

Re: GETTING the input from a cascading menu
by LanX (Saint) on Aug 06, 2021 at 19:33 UTC
Re: GETTING the input from a cascading menu
by Marshall (Canon) on Aug 08, 2021 at 19:18 UTC
    From the code that you've shown, I am not sure what you are trying to do. Let's try it this way: I will give you some runnable code and you tell me what else it should do or not do. When asking a question, it is important to show a short runnable example.

    It been more than a decade since I've worked with a GUI. But I hacked an old application to make the code below. Repo has a cascading menu underneath the Configure button. There is no real code behind any of the options other than a snarky "this doesn't work" message box. I did put a label with the current repo name as a label box to the far right of the menu frame. Maybe something like that is appropriate for your application?

    Provided that my simple framework is in the direction that you want, I guess the question is how to get Configure|Repo|Change Repo Name button to actually do something? You will need to supply a subroutine along the lines of my "not_implemented" sub.

    To do this, I would back up. Start with a main window. Make a frame for your new "Change Repo Name" functionality. I suppose that you will need multiple GUI objects within this frame. A entry window, some labels, probably some action buttons like "Submit", "Cancel" or whatever. You probably start with a copy of the current repo name variable, allow the user to edit that name, submit the change, then validate it, probably with some message boxes that show various error scenarios (like my "not_implemented" sub). Next to last step of "validate" would be to copy the validated new repo name to the displayed name in the main menu bar. Get all of that working as a prototype.

    Now instead of making all of this within the main window. You will need to create a new TopLevel window. Put the same code from your prototype in that window. Its fine for this "pop up" window to destroy itself as the last step in "submit". You presumably won't be doing this that often. For windows that you use a lot, you can withdraw them from the screen and then just display them again on the second use. I don't think you need that complication.

    There are many ways to code my example framework, I just show one way. There are many really fancy ways to do this. I would advise keeping things as simple as you can until you become more proficient at this. So here you go....play with code below.....

    use strict; use warnings; use Tk; my $repo_filepath = "some current repo path?"; my $STD_TITLE = 'the title of this application'; # --- generate the "main" window my $mw = MainWindow->new; $mw->configure(-title=> $STD_TITLE); $mw->geometry("400x100+0+0"); # appears in upper left corner of screen # --- make a menu frame within the main frame # A common mistake is not make enough frames when using pack(). # Basically, make a frame for everything that has more than # one Tk object in it. With pack(), more frames ==>> good! my $menu_f = $mw->Frame()->pack(-side=>'top',-fill=>'x'); # --- populate top level menu buttons in the menu frame my $menu_file = $menu_f->Menubutton (-text=>'File',-tearoff=>'false') ->pack(-side=>'left'); my $menu_configure = $menu_f->Menubutton (-text=>'Configure',-tearoff=>'false') ->pack(-side=>'left'); my $menu_help = $menu_f->Menubutton (-text=>'Help',-tearoff=>'false') ->pack(-side=>'left'); my $label_repo_path = $menu_f->Label # maybe display current repo pat +h? # in main window of the applicat +ion? (-textvariable => \$repo_filepath) ->pack(-side=>'right'); #---- "Configure" Button options only --- #---- The menu buttons for 'File' and 'Help' will do nothing at all! $menu_configure->command (-label=>'Option A', -command => \&not_implemented ); #--- the "Repo" option has a cascade of menu options my $repo_level2 = $menu_configure->cascade( -label => 'Repo', -tearoff=>'false'); $repo_level2->command(-label => "Valdidate Repo", -command => \&not_implemented ); $repo_level2->command(-label => "Change Repo PathName", -command => \&not_implemented ); $repo_level2->command(-label => "Back up Repo", -command => \&not_implemented ); # continuing with other 'Config' options ..... + $menu_configure->command (-label=>'Option C', -command => \&not_implemented ); #--- end of menu options MainLoop(); sub not_implemented { my $response = $mw->messageBox( -title => $STD_TITLE, -message => "You wish this feature worked!! Sorry!!!\n\n", -type => 'Ok'); }
    Update:
    I will engage in some "mind reading" because your requirement statement is so unclear.
    The standard paradigm for GUI's is that you "left click" on something to perform some action. I show a very common high level menu. To "configure", you left click on "Configure". That click shows a drop down menu of options. If you want A or C, you click on that. Option B is "special" and you see that by the displayed right arrow (a cascaded menu). If you just "hover" the mouse over option B, "Repo", that automatically displays the sub-options that you can click upon.

    If you somehow think that hovering over "Change Repo Name" should display a complex interactive dialog automatically, I think you are "barking up the wrong tree". I think that it is proper for you to have to actually click upon "Change Repo Name" for that dialog to appear. The menu should make it easy to navigate to the functionality that you want. "Implementing the actual functionality" should require a click.

    So I see your question as two parts:(a) Cascaded menus and (b) Implementing "pop up" window for a complex user interaction. For me, those are completely separate things. I guess that almost anything is possible with a GUI design. My advice again is: don't make it more complicated than it needs to be.

Re: GETTING the input from a cascading menu
by Anonymous Monk on Aug 06, 2021 at 22:09 UTC

    There are no modules, other than Tk. I need to get the dirname from Tk::Enter so I can build a command line and execute it.