2011-09-29 17 views
0

我有一个文本窗口小的Perl Tk的应用程序,我想在一个非缓冲的方式来更新就像我有我的日志文件,但我无法得到它的工作混乱由于我对Perl所做的一切都不太了解。Perl的传统知识:与更新文本窗口

该应用程序读取XML索引,然后解析它在加载XML中找到的URL来缓存页面的每个ID。这些数字可以从1700到19,000,具体取决于输入哪个$ pubId并需要几个小时。

我有一个提交按钮下面的代码和文本窗口:

my $submit_image = $pict->Photo(-file => $submit); 
    my $submit_button = $mw->Button(
    -image => $submit_image, 
    -text => "Submit", 
    -background => "#cccccc", 
    -command => sub { 

     if ($pubId eq '') { 
      $|; 
    Log_message ("\n$DATE - $TIME - WARNING: Please complete all fields\t"); 
    tk_message ("Please enter a valid Publication ID"); 
} 
else { 
    request_url(); #Open the xml url and read it in 
    } 
    $text->insert( 
       # put something to the _end_ of the text 
       # which is in the widget 
       'end', 
       sprintf(" $txtmesg\n") 
      ); 
      # Set window to the end of the text 
      # I want to see the newest events immediately 
      $text->see('end'); 
     }) ->place(-x => 60, -y =>195); 

如果按钮按下空或无效$的pubId(工作request_url做了进一步的检查,看是否HTML正文包含单词404和错误消息到窗口)。

但是,如果一切正常,并request_url()运行,那么整个Tk的窗口冻结,我不能用我的退出按钮,必须通过在命令提示符下将其关闭。

我知道我应该不同,但到目前为止,每一个网站我已经看过这样做对我来说太复杂,我只是得到百思不得其解。我正在寻找一些noddy指令来帮助我解决这个问题。

谢谢。

编辑:我现在已经尝试使用MainLoop();和DoOneEvent():在我的分区内,但我仍然看到相同的GUI冻结,没有窗口更新。

我会继续研究和实验。

-command => \&long_job) 

MainLoop(); 

    sub long_job { 
     if ($pubId eq '') { 
      $|; 
    Log_message ("\n$DATE - $TIME - WARNING: Please complete all fields\t"); 
    tk_message ("Please enter a valid Publication ID"); 
} 
else { 
    DoOneEvent(); 
    request_url(); #Open the xml url and read it in 
    } 
    } 
+0

看起来问题是'request_url'正在同步工作,阻塞了进一步的事件处理直到完成。 (Tk的严格单线程。)我的perl已经生锈了,我不知道如何修复它。 –

+0

谢谢Donal,我会看看是否有办法改变这个例程 –

+0

嗨,你有没有解决这个问题?我在循环中遇到类似system()调用的问题,并试图在每个循环迭代中更新Label,但是直到完成循环才冻结。即使在循环中添加DoOneEvent()也没有正确解决它。 – insaner

回答

0

不知道这是否会帮助其他有类似的问题,但万一它:

MainLoop(); 

是什么“开始”的传统知识的过程。最好的做法是设置所有的小部件,回调以及任何你想在屏幕上显示的东西,然后调用MainLoop()。处理MainLoop()被调用。在上述内容中,您可能需要致电

$myLabel->update; 

循环内部无论您使用什么来显示输出。在我的情况下,我使用Label在使用system()进行调用的循环中输出进度消息。使用->update完美解决了它(而DoOneEvent()没有)。

希望帮助别人那里。

相关问题