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

Hi Monks,

I try to make a simple statusbar, to show current cursor position in text widget.

Problem_1: it only works with the mousebutton. - I want to use the cursor buttons also in keyboard. So maybe it is not good to bind with mouse, it would be better to get the insertion cursor position. How?

Problem_2:I would like to use LineNumberText instead of Text, but current position doesn't work, it gives back '8'. I don't understand why.

Here is my little testscript:
use Tk; use Tk::LineNumberText; $mw = MainWindow->new; $t = $mw->Text()->pack(); #$t = $mw->LineNumberText('Text')->pack(); $t->insert('end', "This is some\n"); $t->insert('end', "normal text\n"); $t->bind('<Button-1>' => [\&updateStatus]); MainLoop(); sub updateStatus { $status = $t->index('current'); print "$status\n"; }
I appreciate any help!

Replies are listed 'Best First'.
Re: cursor position in text widget and linenumbertext
by liverpole (Monsignor) on Sep 15, 2009 at 14:22 UTC
    Hi balee,

    I don't see in the documentation for Tk::LineNumberText anything about the method index() being available the way it is for Tk::Text.

    Having said that, though, it appears (to address your second question first) that you could access the subwidget like this:

    use strict; use warnings; use Tk; use Tk::LineNumberText; my $mw = MainWindow->new; my $t = $mw->LineNumberText('Text')->pack(); $t->insert('end', "This is some\n"); $t->insert('end', "normal text\n"); $t->bind('<Button-1>' => [\&updateStatus]); $mw->bind('<question>' => [\&updateStatus]); # Debug section -- shows objects' keys use Data::Dumper; my @tkeys = keys %$t; my $sw = $t->{'SubWidget'}; my @swkeys = keys %$sw; printf "LineNumberText keys .... %s\n", Dumper([@tkeys]); printf "Subwidget keys ......... %s\n", Dumper([@swkeys]); MainLoop(); sub updateStatus { my $text = $sw->{'text'}; # Get Text obj (Not really a good p +ractice!) my $status = $text->index('current'); print "$status\n"; }

    Note, however, that the line my $text = $sw->{'text'}; breaks the OO encapsulation; you're not really supposed to be accessing the data from the Tk::LineNumberText object directly (and the interface could change in the future, leaving you out of luck!)

    Maybe you could suggest to the author of Tk::LineNumberText to put in a method to access the underlying Text object.

    For your first question, I'm not exactly sure what you're asking.  The line $mw->bind('<question>' => [\&updateStatus]); shows how you could bind the question mark "?" to the subroutine, but it sounds like you're asking more about the cursor keys in particular.  Can you be a bit more specific about what you're trying to do?


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

      Thanks for your help!

      Now I can see what was the problem with Linenumbertext.

      My first problem was that statusupdate happened only in case of clicking in the text with the mousebutton. I also wanted to update status every keystroke... Meanwhile - with a little help - I figured out: $mw->bind('<KeyPress>' => [\&updateStatus]); In case of linenumbertext, it works, but with simple Text, - I don't understand why - it doesn't.
      use Tk; use Tk::LineNumberText; $mw = MainWindow->new; $t = $mw->Text()->pack(); #$t = $mw->LineNumberText('Text')->pack(); $t->insert('end', "This is some\n"); $t->insert('end', "normal texaaaat\n"); $t->insert('end', "normal textasdfasdf\n"); $t->insert('end', "normal textasdasd\n"); $t->bind('<Button-1>' => [\&updateStatus]); $t->bind('<KeyPress>' => [\&updateStatus]); MainLoop(); sub updateStatus { #my ($line,$col) = split(/\./,$t->{'rtext'}->index('insert')); #$status = "line: $line, col: $col"; $status = $t->index('current'); print "$status\n"; }
        Hi,

        seems to work with 'insert' :

         perl -MTk -e'$t = tkinit->Text->pack;$t->bind("<KeyPress>", sub{print $t->index("insert"),"\n"});MainLoop'
        Cheers, Christoph