Hi Wiggins,

Tk is not thread safe, so you should not expect to be able to manage a gui from two threads in the same process.

However, that shouldn't stop you from doing ALL gui management from within one thread (preferrably the parent), and setting up a worker thread to handle otherwise potentially-blocking actions (such as LWP fetches).  For that, you may want to look at using threads::shared.

To do this, construct the thread before setting up the gui.  I've created an example program for you which illustrates this:

#!/usr/bin/perl -w # Always use 'strict' and 'warnings' use strict; use warnings; # Libraries use threads; use threads::shared; use Thread::Queue; use Tk; use Tk::ROText; # Globals my $rotext = 0; # The Read-only text widget my $n_lines_waiting: shared = 0; # Message passing between thre +ads my $p_queue = Thread::Queue->new(); # Construct message 'Queue' #################### ### Main program ### #################### # Startup worker thread my $gui_thr = threads->create(\&worker_thread); # Only *now* is it safe to construct the GUI, from the parent thread gui(); + ################### ### Subroutines ### ################### # This subroutine is ONLY called from the parent thread sub gui { my $mw = MainWindow->new(); my $top = $mw->Frame()->pack(-expand => 1, -fill => 'both'); my $bt = $top->Button(-bg => 'skyblue', -text => "Exit"); $bt->configure(-command => sub { $mw->destroy() }); $rotext = $top->ROText(-bg => 'white'); $rotext->pack(); $bt->pack(); $mw->repeat(1000 => \&main_loop); MainLoop; } sub main_loop { if ($n_lines_waiting) { fetch_worker_data(); } } sub fetch_worker_data { for (my $i = 0; $i < $n_lines_waiting; $i++) { my $line = $p_queue->dequeue(); $rotext->insert("end", "$line\n"); } $rotext->insert("end", "--- End of $n_lines_waiting line(s) ---\n" +); $rotext->see("end"); my $mw = $rotext->toplevel(); $mw->update(); $n_lines_waiting = 0; } # This subroutine is ONLY called in the worker thread sub worker_thread { while (1) { sleep 3; worker_simulate_data(); } } sub worker_simulate_data { my $nlines = int(rand(10)); ($nlines > 0) or return; my $timestamp = localtime(time); for (my $i = 0; $i < $nlines; $i++) { my $idx = $i + 1; my $line = "[$timestamp] Random line of text #$idx"; $p_queue->enqueue($line); } $n_lines_waiting = $nlines; }

The subroutine worker_simulate_data is called by the worker_thread subroutine every 3 seconds, and creates from 0 to 9 lines of data, which are then queued using Thread::Queue.  Finally, the shared variable $n_lines_waiting is set to the number of lines waiting in the queue.

The parent thread gets the signal of how many lines are waiting via $n_lines_waiting, pulls this number of lines out of the shared queue, and writes them to the ROText window $rotext.

Note that the worker thread only writes new data if $n_lines_waiting is zero (otherwise there are lines waiting which haven't been read by the parent thread yet).

Of course, you are free to do other operations within the main_loop, as well as modify worker_thread so that it uses real-life data rather than a simulation.


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

In reply to Re: PerlTk on a thread... by liverpole
in thread PerlTk on a thread... by Wiggins

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.