Perl Update UI on Long Thread

北慕城南 提交于 2019-12-01 21:18:06

One problem is that the listbox variable needs to be shared between the threads. Tk doesn't seem happy with the listbox variable shared directly, so I made two copies, and set up a periodic status update to copy the shared version to the non-shared version.

However, using threads with Tkx may be dicey. I was getting segfaults when I tried to join the thread rather than detach it, and I get a segfault with the code below if I move my $t inside startWork(). This discussion suggests that you may need to start the thread before creating any Tk widgets for it to work reliably.

Here is the code I ended up with:

my $outputTextShared :shared = " {a} {b}";
my $outputText = " {a} {b}";

my $t;
sub startWork()
{
    print "Starting thread \n";
    $t = threads->create(\&doWork, 1);
}

sub updateStatus()
{
    $outputText = $outputTextShared;
}

sub doWork()
{
    threads->detach();
    for (my $a = 0; $a<10; $a++)
    {
        $outputTextShared .= " {$a}";
        print "Counting $a\n";
        sleep(1);
    }
    print "End thread\n";
}

my $update;
$update = sub {
    Tkx::after (1000, $update);
    updateStatus();
};
Tkx::after (1000, $update);

Tkx::MainLoop();

Threading is nice because the UI doesn't block and you can do things like kill the child process if it's taking too long. That power comes with complexity, though. If all you care about is updating the task status in the UI you can do that without using threads; you just have to do it manually.

$outputText = 'some message';
Tkx::update('idletasks');
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!