perl tk gui to show script stdout and stderr in text widget - perl

I have a GUI that runs a script from a command button, but how can I get it to display output in the text widget?
If I wanted to display the output via a logfile insert, could I have the command on the same button/sub as the run button?
use warnings;
use strict;
use Tk;
use Tk::Text ;
use POSIX 'strftime';
my $DATE = strftime("Report.pl for %dth %b %Y" , localtime());
my $mw = MainWindow->new;
my $filename = "c:\\Temp\\perl.txt";
$mw->geometry("720x500");
$mw->title(" backupadmin ");
my $main_frame = $mw->Frame()->pack(-side => 'top', -fill => 'x');
my $left_frame = $main_frame->Frame(-background => "snow2")->pack(-side => 'left', -fill => 'y');
my $right_frame = $main_frame->Scrolled("Text", -scrollbars => 'se',-background => "black",-foreground => "yellow",-height => '44')->pack(-expand => 1, -fill => 'both');
my $failures_button = $left_frame->Button(-text => " $DATE ",
-command => [\&runscript])->pack;
my $Close_button = $left_frame->Button(-text => ' Close ',
-command => [$mw => 'destroy'])->pack;
my $Help_button = $left_frame->Button(-text => " Help Guide ",
-command => [\&load_file])->pack(-side => "bottom");
my $Close_help = $left_frame->Button(-text => ' Close Help ',
-command => [$right_frame => \&clear_file])->pack(-side => "bottom");
MainLoop;
sub runscript {
system("report.pl");
}
sub load_file {
open (FH, "$filename");
while (<FH>) { $right_frame->insert("end", $_); }
close (FH);
}
sub clear_file {
$right_frame->('quit');
}

If your report.pl script outputs to STDOUT, then you could try something like this in your runscript callback:
sub runscript {
right_frame->delete('1.0','end');
my $text = `report.pl`;
$right_frame->insert('end', $text);
}
Alternatively, if report.pl outputs to c:\temp\perl.txt then you could try the following:
sub runscript {
right_frame->delete('1.0','end');
system("report.pl");
load_file();
}

Related

Passing variable from subroutine in tk perl interface

I am using the perl Tk interface where I want to have a button test_1 and upon clicking on this button I would like a variable $varchoice to be defined as test_1. If I press on the button test_2, the variable $varchoice should be defined as test_2.
Before is the snippet of code in which I attempted to accomplish this:
$budget_frame->Button(-text => 'test_1',-command => sub{$varchoice=budget_plot_1()})->pack(-side => "left");
$budget_frame->Button(-text => 'test_2',-command => sub{$varchoice=budget_plot_2()})->pack(-side => "left");
sub budget_plot_1()
{
print "plotting 1\n";
my $var=1;
return $var;
}
sub budget_plot_2()
{
print "plotting 2\n";
my $var=2;
return $var;
}
How do I tweak this code to get the desired results?
Your program seems to work fine. Here is an example of how I tested it:
use feature qw(say);
use strict;
use warnings;
use Tk;
my $budget_frame = MainWindow->new(-title=>"Button test");
my $varchoice;
$budget_frame->Button(
-text => 'test_1',
-command => sub{ $varchoice = budget_plot_1() }
)->pack(-side => "left");
$budget_frame->Button(
-text => 'test_2',
-command => sub{ $varchoice = budget_plot_2() }
)->pack(-side => "left");
MainLoop;
say "Value of \$varchoice = $varchoice";
sub budget_plot_1()
{
print "plotting 1\n";
return "test_1";
}
sub budget_plot_2()
{
print "plotting 2\n";
return "test_2";
}
Output:
Value of $varchoice = test_1

Perl Tk: help me fix highlighting in my text editor

So i'm writing a text editor in Perl Tk and I have a subroutine for highlighting, it inserts two highlighted spaces for you to type in.
I'm having 3 problems.
I want the cursor to move to the left 1 space when the highlight subroutine is triggered. So that when one inserts a highlighting or underline style the cursor is automatically in between the two spaces and the user can type in that style instantly rather than having to use the left arrowkey. I guess my question is how do I insert a style at the cursor instead of the end of the file.
The subroutine's formatting of the text isn't saving properly to the filetype. I'm using .rtf currently.
I want to implement a drop down font selection menu that draws from a system font list but i'm unsure how.
#!/usr/local/bin/perl
#!/C:/Perl/site/lib
use Tk;
use utf8;
use vars qw/$TOP/;
# Main Window
my $mw = new MainWindow;
#Making a text area
my $txt = $mw -> Scrolled('Text', -width => 50,-scrollbars=>'e') -> pack (), -setgrid => true;
#Declare that there is a menu
my $mbar = $mw -> Menu();
$mw -> configure(-menu => $mbar);
#The Main Buttons
my $file = $mbar -> cascade(-label=>"File", -underline=>0, -tearoff => 0);
my $others = $mbar -> cascade(-label =>"Others", -underline=>0, -tearoff => 0);
my $help = $mbar -> cascade(-label =>"Help", -underline=>0, -tearoff => 0);
## File Menu ##
$file -> command(-label => "New", -underline=>0,
-command=>sub { $txt -> delete('1.0','end');} );
$file -> checkbutton(-label =>"Open", -underline => 0,
-command => [\&openfunction, "Open"]);
$file -> command(-label =>"Save", -underline => 0,
-command => [\&savefunction, "Save"]);
$file -> separator();
$file -> command(-label =>"Exit", -underline => 1,
-command => sub { exit } );
## Others Menu ##
my $insert = $others -> cascade(-label =>"Insert", -underline => 0, -tearoff => 0);
$insert -> command(-label =>"Highlight",
-command => [\&highlight, "Highlight"]);
$insert -> command(-label =>"Underline",
-command => [\&underline, "Underline"]);
$insert -> command(-label =>"Title",
-command => [\&bold, "Title"]);
$insert -> command(-label =>"Stippling",
-command => [\&stippling, "Stippling"]);
$insert -> command(-label =>"Find & Replace",
-command => [\&find_replace, "Find & Replace"]);
$insert -> command(-label =>"Name",
-command => sub { $txt->insert('end',"Name : Thaddeus Roebuck Badgercock\n");});
$insert -> command(-label =>"Bullet Point", -command=>sub {
$txt->insert('end',"⚫\t");});
$insert -> command(-label =>"Email",
-command=> sub {$txt->insert('end',"E-Mail :\n");});
$others -> command(-label =>"Insert All", -underline => 7,
-command => sub { $txt->insert('end',"Name : Thaddeus Roebuck Badgercock
Website :
E-Mail :");
});
## Help ##
$help -> command(-label =>"About", -command => sub {
$txt->delete('1.0','end');
$txt->insert('end',
"About
----------
This is a simple text editor written in Perl Tk. This program is licensed under the GNU Public License and is Free Software.
"); });
## Tags ##
$txt->tag(qw/configure bgstipple -background black -borderwidth 0
-bgstipple gray12/);
$txt->tag(qw/configure bold -font C_bold/);
$txt->tag(qw/configure color1 -background/ => '#a0b7ce');
$txt->tag(qw/configure raised -background white -relief raised/);
$txt->tag(qw/configure sunken -background white -relief sunken/);
$txt->tag(qw/configure underline -underline on/);
MainLoop;
sub find_replace {
$txt->FindAndReplacePopUp;
}
sub stippling {
$txt->insert('end', ' ', 'bgstipple');
} # end style
sub bold {
$txt->insert('end', ' ', 'bold');
}
sub highlight {
$txt->insert('end', ' ', 'color1');
}
sub raised {
$txt->insert('end', ' ', 'raised');
}
sub underline {
$txt->insert('end', ' ', 'underline'); #how do
}
sub savefunction {
my $fileDataToSave=$txt->get("1.0","end");
# Trigger dialog
$filename = $mw->getSaveFile( -title => "Selecting file to Save",
-defaultextension => '.rtf', -initialdir => '.' );
# save the file
open(my $fh, '>', $filename) or die $!;
print $fh $fileDataToSave;
close $fh;
}
sub openfunction {
# function to get file dialog box
$filename = $mw->getOpenFile( -title => "Selecting file to Load",
-defaultextension => '.txt', -initialdir => '.' );
# function to load file into string e.g. if you have use File::Slurp
open($fh, '<', $filename) or die $!;
my $file_content = do { local $/; <$fh> };
close $fh;
$txt->Contents($file_content)
}
sub menuClicked {
my ($opt) = #_;
$mw->messageBox(-message=>"You have clicked $opt.
This function is not implemented yet.");
}
#todo:
#figure out how to package as monolithic executables for various platforms
You can insert the highlight formatting at the current cursor position using:
sub highlight {
$txt->insert('insert', ' ', 'color1');
$txt->SetCursor( 'insert - 1 chars' ); # <-- moves the cursor back into the
# hightlight region
}

BioPerl/BioGraphics only prints one value instead of all

I am trying to plot SNPs onto a gene (or below). The code I have is the following:
#!/usr/bin/perl
use strict;
use warnings;
use Bio::Graphics;
use Bio::SeqFeature::Generic;
my #SNPs = "408777 408900 409100 409480";
my $gene_name = "GSTd10";
my $scaffold = "KB668289";
my $gene_start = 408763;
my $gene_end = 409489;
my $length = $gene_end - $gene_start + 50;
open my $png, ">", "$gene_name.png" or die "Cannot open $gene_name.png: $!\n";
#Create a panel for the image#
my $panel=Bio::Graphics::Panel->new(-offset => $gene_start, -length => $length, -width => 1000, -pad_left => 100, -pad_right => 10, -pad_top => 10);
my $track_whole=$panel->add_track(-glyph => 'graded_segments', -label => 1, -bgcolor => 'black', -font2color => 'black',);
my $feature= Bio::SeqFeature::Generic->new(-display_name => $gene_name, -start => $gene_start, -end => $gene_end,);
$track_whole->add_feature($feature);
my $track=$panel->add_track(-glyph => 'graded_segments', -label => 1, -bgcolor =>'blue', -min_score => 0, -max_score => 30, -font2color => 'black');
foreach my $SNP (#SNPs)
{
my $feature= Bio::SeqFeature::Generic->new(-label => $SNP, -start => $SNP, -end => $SNP);
$track->add_feature($feature);
}
#This will print out the final panel i.e. you must have created an object called $panel above
print $png $panel -> png;
Whenever I run this script, I only get printed one line.
Where is the mistake in order to print all values in #SNPs? In addition, is there a way of printing ^ instead of a block?
In this line
my #SNPs = "408777 408900 409100 409480";
You're just creating an array with a single element of that whole string.
Try
my #SNPs = qw(408777 408900 409100 409480);

How to print selected value with checkbutton in Tkx

I'm using the Tkx module to create a window populated with text values from a #list. Then I select one or more then one with a checkbutton. I want to print the already selected ones after pressing the 'OK' button but don't know how to pass the variables to the 'OK' -command => sub {}. Thanks.
use autodie;
use strict;
use warnings;
use Tkx;
my $mw = Tkx::widget->new( "." );
$mw->g_wm_title( "Listbox" );
$mw->m_configure( -background => "#191919" );
my $width = '700';
my $height = '500';
Tkx::update('idletasks');
$width ||= Tkx::winfo('reqwidth', $mw);
$height ||= Tkx::winfo('reqheight', $mw);
my $x = int((Tkx::winfo('screenwidth', $mw) / 2) - ($width / 2));
my $y = int((Tkx::winfo('screenheight', $mw) / 2) - ($height / 2));
$mw->g_wm_geometry($width . "x" . $height . "+" . $x . "+" . $y);
my #list = ('TEXT1', 'TEXT2', 'TEXT3', 'TEXT4', 'TEXT5');
for my $list (#list) {
my $cb = $mw->new_ttk__checkbutton(
-text => $list,
-onvalue => 1,
-offvalue => 0,
);
$cb->g_pack(
-anchor=>'w',
-side=>'top',
-fill => 'x'
);
}
my $ok = $mw->new_button(
-text => "OK",
-command => sub {
print "Selected Values";
Tkx::after(500, sub { $mw->g_destroy });
},
);
$ok->g_pack(
-anchor=>'c',
-side=>'bottom',
);
Tkx::MainLoop();
If you just want to find what checkboxes are selected:
my $settings;
for my $list (#list) {
my $cb = $mw->new_ttk__checkbutton(
-text => $list,
-onvalue => 1,
-offvalue => 0,
-variable => \$settings->{checkbuttons}->{$list},
);
$cb->g_pack(
-anchor=>'w',
-side=>'top',
-fill => 'x'
);
}
my $ok = $mw->new_button(
-text => "OK",
-command => sub {
print "Selected Values: [";
print join( ", ", grep { $settings->{checkbuttons}->{$_} } #list ), "]\n";
Tkx::after(500, sub { $mw->g_destroy });
},
);

Create new perl/tk window that will automatically close after 1sec

I want to add a new widget to my script that will open a new window with text and will close automatically after 1sec.
how can I do it ?
I think what you want is Tk::after.
#!/usr/bin/perl
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new;
my $spawn = $mw->Button(
-text => 'spawn',
-command => sub {
my $subwindow = MainWindow->new;
my $label = $subwindow->Label(-text => "spawned");
$label->pack;
$subwindow->after(1_000, sub { $subwindow->destroy; });
}
);
$spawn->pack;
my $exit = $mw->Button(
-text => 'exit',
-command => sub { print "exiting...\n"; exit }
);
$exit->pack;
MainLoop;