Search code examples
perltk-toolkitperltk

Using multiple Option menus in Perl/Tk


I am completely new to Perl/Tk and trying to make an app that needs multiple drop down menus. I am using option menus for that. But when I change the value of one option menu while running, the value for all the drop downs change to this value. Please help in this. This is the code:

    #!/usr/bin/perl
use warnings;
use Tk;

my $mw = MainWindow->new;
$mw->geometry("700x700");
$mw->title("AIR (Auto Immune Research)");

#create own title font
$mw->fontCreate("sectionTitleFont", -family => "Helvetica", -size => 36, -weight => "bold");

my $symptomFrame = $mw->Frame(-background => 'white', -foreground => 'black')->pack(-side => "top", -fill => "x");
my $pathologyFrame = $mw->Frame(-background => 'white', -foreground => 'black')->pack(-side => "bottom", -fill => "x");

my $symptomLabel = $symptomFrame->Label(-background => 'white', -text => 'Patient Symptoms', -font => 'sectionTitleFont');
my $pathologyLabel = $pathologyFrame->Label(-background => 'white', -text => 'Pathological Findings', -font => 'sectionTitleFont');

my $severityText = $symptomFrame->Label(-background => 'white', -text => 'Severity on a scale of 1 to 10');

#cough
my $coughCheckBox = $symptomFrame->Checkbutton(-text => 'Cough', -background => 'white');
my $coughSeverity;
my $coughSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$coughSeverity,
-textvariable => \$severityText
);

#Fever
my $feverCheckBox = $symptomFrame->Checkbutton(-text => 'Fever', -background => 'white');
my $feverSeverity;
my $feverSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$feverSeverity,
-textvariable => \$severityText
);

#joint pain
my $jointPainCheckBox = $symptomFrame->Checkbutton(-text => 'Joint Pain', -background => 'white');
my $jointPainSeverity;
my $jointPainSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$jointPainSeverity,
-textvariable => \$severityText
);

#Moon face
my $moonFaceCheckBox = $symptomFrame->Checkbutton(-text => 'Moon Face', -background => 'white');
my $moonFaceSeverity;
my $moonFaceSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$moonFaceSeverity,
-textvariable => \$severityText
);

#fatigue
my $fatigueBox = $symptomFrame->Checkbutton(-text => 'Fatigue', -background => 'white');
my $fatigueSeverity;
my $fatigueSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$fatigueSeverity,
-textvariable => \$severityText
);

#Skin Redness
my $skinRednessBox = $symptomFrame->Checkbutton(-text => 'Skin Redness', -background => 'white');
my $skinRednessSeverity;
my $skinRednessSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$skinRednessSeverity,
-textvariable => \$severityText
);

#Drowsiness
my $drowsinessBox = $symptomFrame->Checkbutton(-text => 'Drowsiness', -background => 'white');
my $drowsinessSeverity;
my $drowsinessSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$drowsinessSeverity,
-textvariable => \$severityText
);

#Headache
my $headacheBox = $symptomFrame->Checkbutton(-text => 'Headache', -background => 'white');
my $headacheSeverity;
my $headacheSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$headacheSeverity,
-textvariable => \$severityText
);


#Inflamations
my $inflamationsBox = $symptomFrame->Checkbutton(-text => 'Inflamations', -background => 'white');
my $inflamationsSeverity;
my $inflamationsSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$inflamationsSeverity,
-textvariable => \$severityText
);

#Itchiness
my $itchinessBox = $symptomFrame->Checkbutton(-text => 'Itchiness', -background => 'white');
my $itchinessSeverity;
my $itchinessSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$itchinessSeverity,
-textvariable => \$severityText
);

#Blood in Urine
my $bloodBox = $symptomFrame->Checkbutton(-text => 'Blood in Urine', -background => 'white');
my $bloodSeverity;
my $bloodSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$bloodSeverity,
-textvariable => \$severityText
);

#Depression
my $depressionBox = $symptomFrame->Checkbutton(-text => 'Depression', -background => 'white');
my $depressionSeverity;
my $depressionSeverityDD = $symptomFrame->Optionmenu(
-options => [[1=>1], [2=>2], [3=>3], [4=>4], [5=>5], [6=>6], [7=>7], [8=>8], [9=>9], [10=>10]],
-variable => \$depressionSeverity,
-textvariable => \$severityText
);


#emty label to give empty space
my $emptyLabel = $symptomFrame->Label(-background => 'white', -width => '20');
$symptomLabel->grid(-columnspan => '5');
$pathologyLabel->grid(-columnspan => '5');
#$severityText->grid;
$coughCheckBox -> grid($coughSeverityDD, $emptyLabel, $feverCheckBox, $feverSeverityDD);
$jointPainCheckBox -> grid($moonFaceSeverityDD, $emptyLabel, $depressionBox, $depressionSeverityDD);
$moonFaceCheckBox -> grid($jointPainSeverityDD, $emptyLabel, $bloodBox, $bloodSeverityDD);


MainLoop;

Solution

  • When an option is selected in an Optionmenu widget, it updates the scalar referenced in the -textvariable widget option. Also, when that scalar is modified, the widget shows the modified text automatically.

    In the code, all the Optionmenu widgets have been passed a reference to the same scalar ($severityText) and as a result, all of them always end up showing the same text. To fix this, you may create a new variable for -textvariable of each widget, but you can get away with not using the option at all.

    my $coughSeverity;
    my $coughSeverityDD = $symptomFrame->Optionmenu(
        -options => [ 1..10 ],      # you can omit the labels if they are the same as the values
        -variable => \$coughSeverity,
    );
    

    Although not related to the question, you should consider creating a new composite widget that contains the widgets for a symptom. That'll make it easier to add new symptoms or change the appearance of the all the symptom widgets easily. See here for some documentation on that.