我有一个带有文本窗口的小型Perl Tk应用程序,我希望以非缓冲的方式更新,就像我的日志文件一样,但由于我对所做的一切都知之甚少,我无法让它工作与Perl。
应用程序读取xml索引,解析它然后将xml中找到的每个id作为URL缓存以缓存页面。这些数字可以从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窗口冻结,我无法使用退出按钮,必须通过命令提示符关闭它。
我知道我应该以不同的方式做到这一点,但到目前为止,我所看到的每个网站对我来说都太复杂了,我只是感到困惑。我正在寻找一些令人失望的说明,以便我能够解决这个问题。
感谢。
编辑:我现在尝试使用MainLoop();和DoOneEvent():在我的sub中,但我仍然看到相同的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 :(得分:0)
不确定这是否会帮助其他人遇到类似问题,但以防万一:
MainLoop();
是"开始" tk过程。好的做法是先设置所有小部件,回调和任何想要在屏幕上显示的内容,然后调用MainLoop()
。在调用MainLoop()
之后,应该进行处理。在上文中,您可能需要调用
$myLabel->update;
在循环内部,无论你用什么来显示你的输出。就我而言,我使用Label
在循环中输出进度消息,该循环使用system()
进行调用。使用->update
完美地解决了它(而DoOneEvent()
没有)。
希望能帮到那里的人。