Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: GUI > Вывод имени открытого файла в Tk


Автор: korob2001 13.9.2004, 14:27
Привет!
Вобщем, для тренировки, решил написать небольшую программку на Perl/Tk.
Программа с помощью GUI получает имя каталога, искомое слово или шаблон, а так же должна отображать путь к файлу и его имя, который в данный момент открыт, при открытии следующего файла, этот путь должен изменяться.

При нажатии на кнопку Scan программа проходит по всем вложенным каталогам в указанном каталоге в поисеках текстовых файлов. Затем если файл является текстовым, програ открывает его и ищет в нём искомое слово.

Проблема в том, что при поиске программа не изменяет путь к фалу, а как бы подвисает, а только когда поиск окончен выводит имя последнего открытотого файла. sad.gif

Как сделать что бы программа выводила имена файлов на стадии выполнения, как это происходит практически при инсталяции любой программы.
Например:
Копируется файл: C:\Perl\usr\lib\Tk.pm.

затем ета строка изменяется на такую:
Копируется файл: С:\Perl\usr\lib\CGI.pm

и т.д.

Эту строку я создал так:

Код

$main = new MainWindow;
$label = $main->Label( -textvariable = \$string )->pack


Затем при открытии файла значение переменной $string изменяется на имя файла. Но комп почему-то виснет, до полного завершения программы, а затем переменная выводит имя последного фала.

Может нужно создать отдельный процесс, для выполнения подпрограммы, производящей рекурсивный обход вложенных каталогов?
Может кто сталкивался с такой проблемой? Поясните пожалуйста хотябы принцип или где рыть.

Заранее спасибо,
Денис

Автор: ElectricalStorm 13.9.2004, 16:31
я к сожалению не работал с Тк но я Вам дам одну чудную прогу на Tk может что-нибудь из нее Вам пригодиться
Код

#!/usr/local/bin/perl -w
#
# Towers of Hanoi, Perl/Tk style.  2000/06/14, [email protected]

# Global package, subroutine and data declarations.

use Tk;
use Tk::Dialog;
use subs qw/do_hanoi fini hanoi init move_ring/;
use strict;

my $canvas;   # the Hanoi playing field
my @colors;   # 24 graduated ring colors
my $fly_y;   # canvas Y-coord along which rings fly
my $max_rings;   # be nice and keep @colors count-consistent
my $num_moves;   # total ring moves
my %pole;   # tracks pole X-coord and ring count
my %ring;   # tracks ring canvas ID, width and pole
my $ring_base;   # canvas Y-coord of base of ring pile
my $ring_spacing;  # pixels between adjacent rings
my $stopped;   # 1 IFF simulation is stopped
my $velocity;   # pixel delta the rings move while flying
my $version = '1.0, 2000/06/14';

# Main.

my $mw = MainWindow->new;
init;
MainLoop;

sub do_hanoi {

   # Initialize for a new simulation.

   my($n) = @_;  # number of rings
   
   return unless $stopped;

   $stopped = 0;  # start ...
   $num_moves = 0;  # ... new simulation

   my $ring_height = 26;
   $ring_spacing = 0.67 * $ring_height;

   my $ring_width = 96 + $n * 12;

   my $canvas_width = 3 * $ring_width + 4 * 12;
   my $canvas_height = $ring_spacing * $n + $fly_y + 2 * $ring_height;

   $ring_base = $canvas_height - 32;

   # Remove all rings from the previous run and resize the canvas.

   for (my $i = 0; $i < $max_rings; $i++) {
$canvas->delete($ring{$i, 'id'}) if defined $ring{$i, 'id'};
   }
   $canvas->configure(-width => $canvas_width, -height => $canvas_height);

   # Initialize the poles: no rings, updated X coordinate.

   for (my $i = 0; $i < 3; $i++) {
$pole{$i, 'x'} = ($i * $canvas_width / 3) + ($ring_width / 2) + 8;
$pole{$i, 'ring_count'} = 0;
   }

   # Initialize the rings: canvas ID, pole number, and width.

   for (my $i = 0; $i < $n; $i++) {
my $color = '#' . $colors[$i % 24];
my $w = $ring_width - ($i * 12);
my $y = $ring_base - $i * $ring_spacing;
my $x = $pole{0, 'x'} - $w / 2;
my $r = $n - $i;
$ring{$r, 'id'} = $canvas->createOval(
           $x, $y, $x + $w, $y + $ring_height,
           -fill => $color, -outline => 'black', -width => 1,
       );
$ring{$r, 'width'} = $w;
$ring{$r, 'pole'} = 0;
$pole{0, 'ring_count'}++;
   }

   # Start the simulation.

   $mw->update;
   hanoi $n, 0, 2, 1;
   $stopped = 1;

} # end do_hanoi

sub hanoi {

   # Recursively move rings until complete or stopped by the user.

   my($n, $from, $to, $work) = @_;

   return if $n <=0 or $stopped;

   hanoi $n - 1, $from, $work, $to;
   move_ring $n, $to unless $stopped;
   hanoi $n - 1, $work, $to, $from;
}

sub init {

   $fly_y = 32;  # Y-coord rings use to fly between poles
   $stopped = 1;
   my $stop = sub {$stopped = 1};
   my $about = $mw->Dialog(
       -title          => 'About tkhanoi',
       -bitmap         => 'info',
       -default_button => 'OK',
       -buttons        => ['OK'],
       -text           => "tkhanoi version $version\n\n" .
                          "r - run  simulation\n"        .
                          "s - stop simulation\n"        .
                          "q - quit program\n",
       -wraplength     => '6i',
   );
   
   # Menubar and menubuttons.

   $mw->title("Towers of Hanoi");
   $mw->configure(-menu => my $menubar = $mw->Menu);

   my $file = $menubar->cascade(-label => 'File');
   $file->command(-label => '~Quit', -command => \&fini,-accelerator => 'q');

   my $game = $menubar->cascade(-label => 'Game');
   $game->command(-label => '~Run',  -command => sub {}, -accelerator => 'r');
   $game->command(-label => '~Stop', -command => $stop,  -accelerator => 's');

   my $help = $menubar->cascade(-label => 'Help');
   $help->command(-label => 'About', -command => sub {$about->Show});

   my $info = $mw->Frame->pack;

   # Number of rings scale.

   my $rframe = $info->Frame(qw/-borderwidth 2 -relief raised/);
   my $rlabel = $rframe->Label(-text => 'Number of Rings');
   my $rscale = $rframe->Scale(
       qw/-orient horizontal -from 1 -to 24 -length 200/,
   );
   $rscale->set(4);
   $game->cget(-menu)->entryconfigure('Run',
       -command => sub {do_hanoi $rscale->get},
   );

   $rframe->pack(qw/-side left/);
   $rscale->pack(qw/-side right -expand 1 -fill x/);
   $rlabel->pack(qw/-side left/);

   # Ring velocity scale.

   my $vframe = $info->Frame(qw/-borderwidth 2 -relief raised/);
   my $vlabel = $vframe->Label(-text => 'Ring Velocity %');
   my $vscale = $vframe->Scale(
       qw/-orient horizontal -from 0 -to 100 -length 200/,
       -command => sub {$velocity = shift},
   );
   $vscale->set(2);

   $vframe->pack(qw/-side left/);
   $vscale->pack(qw/-side right -expand 1 -fill x/);
   $vlabel->pack(qw/-side left/);

   # The simulation is played out on a canvas.

   $canvas = $mw->Canvas(qw/-relief sunken/);
   $canvas->pack(qw/-expand 1 -fill both/);
   $canvas->createWindow(40, 10, -window =>
       $canvas->Label(-textvariable => \$num_moves, -foreground => 'blue'),
   );

   # Each ring has a unique color, hopefully.

   @colors = (qw/
       ffff0000b000 ffff00006000 ffff40000000 ffff60000000
       ffff80000000 ffffa0000000 ffffc0000000 ffffe0000000
       ffffffff0000 d000ffff0000 b000ffff0000 9000ffff0000
       6000ffff3000 0000ffff6000 0000ffff9000 0000ffffc000
       0000ffffffff 0000e000ffff 0000c000ffff 0000a000ffff
       00008000ffff 00006000ffff 00004000ffff 00000000ffff
   /);

   $max_rings = 24;
   warn "Too few colors for $max_rings rings!" if $max_rings > $#colors + 1;

   # Global key bindings that emulate menu commands.

   $mw->bind('<KeyPress-r>' => sub {do_hanoi $rscale->get});
   $mw->bind('<KeyPress-q>' => \&fini);
   $mw->bind('<KeyPress-s>' => $stop);

} # end init

sub fini {
   $mw->destroy;
}

sub move_ring {

   # Move ring $n - its bounding box coordinates - to pole $to.

   my($n, $to) = @_;

   $num_moves++;
   my $r = $ring{$n, 'id'};
   my($x0, $y0, $x1, $y1) = map {int($_ + 0.5)} $canvas->coords($r);

   # Float the ring upwards to the flying Y-coordinate, and decrement
   # this pole's count.

   my $delta;
   while ($y0 > $fly_y) {
$delta = $y0 - $fly_y > $velocity ? $velocity : $y0 - $fly_y;
$canvas->coords($r, $x0, $y0 -= $delta, $x1, $y1 -= $delta);
$mw->update;
   }
   $pole{$ring{$n, 'pole'}, 'ring_count'}--;

   # Determine the target X coordinate based on destination pole, and
   # fly the ring over to the new pole. The first while moves rings
   # left-to-right, the second while moves rings right-to-left.

   my $x = $pole{$to, 'x'} - $ring{$n, 'width'} / 2;

   while ($x0 < $x) {
$delta = $x - $x0 > $velocity ? $velocity : $x - $x0;
$canvas->coords($r, $x0 += $delta, $y0, $x1 += $delta, $y1);
$mw->update;
   }

   while ($x0 > $x) {
$delta = $x0 - $x > $velocity ? $velocity : $x0 - $x;
$canvas->coords($r, $x0 -= $delta, $y0, $x1 -= $delta, $y1);
$mw->update;
   }

   # Determine ring's target Y coordinate, based on the destination
   # pole's ring count, and float the ring down.

   my $y = $ring_base - $pole{$to, 'ring_count'} * $ring_spacing;

   while ($y0 < $y) {
$delta = $y - $y0 > $velocity ? $velocity : $y - $y0;
$canvas->coords($r, $x0, $y0 += $delta, $x1, $y1 += $delta);
$mw->update;
   }
   
   $pole{$to, 'ring_count'}++;
   $ring{$n, 'pole'} = $to;

} # end move_ring




Автор: korob2001 13.9.2004, 23:42
Огромное спасибо. Здесь есть практически всё что мне нужно.
Правда кирилица отсутствует, но ничего это дело времени.
Ещё раз спасибо.

Автор: ElectricalStorm 14.9.2004, 13:18
Да.... с кирилецей не понятно что делать ..... sad.gif


Автор: Samot 16.11.2004, 19:25
use encoding "ru_RU.CP1251";

Автор: korob2001 16.11.2004, 23:38
Большое спасибо. Работает. ;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)