Perl Tk:更新文本窗口的混乱

发布于 2024-12-07 08:03:09 字数 1856 浏览 1 评论 0原文

我有一个带有文本窗口的小型 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(): 在我的子进程中,但我仍然看到相同的 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
    }   
     }

I have a small Perl Tk app with a text window that I want to be updated in a non buffered way like I have with my log files but I can't get it to work due to my poor understanding of everything to do with Perl.

The app reads an xml index, parses it then loads each id found in the xml as a url to cache the page. These can number from 1700 to 19,000 depending on which $pubId is entered and takes a couple of hours.

I have the following code for the Submit button and the text window:

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);

which works if the button is pressed with an empty or invalid $pubId (request_url does a further check to see if the html body contains the word 404 and errors out a message to the window).

But if everything is ok and request_url() runs, then the whole Tk window freezes and I can't use my exit button and have to close it via the command prompt.

I know I should be doing this differently but so far every site I have looked at is too complicated for me and I just get baffled. I'm looking for some noddy instructions to enable me to work through this.

Thanks.

EDIT: I have now tried to use MainLoop(); and the DoOneEvent(): within my sub but I am still seeing the same gui freeze and no window updates.

I will continue to research and experiment.

-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
    }   
     }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

寒江雪… 2024-12-14 08:03:09

不确定这是否会帮助其他人解决类似的问题,但以防万一:

MainLoop();

这就是“启动”tk 过程的原因。好的做法是先设置所有小部件、回调以及您想要在屏幕上显示的任何内容,然后调用 MainLoop()。处理应该在调用 MainLoop() 之后进行。在上面,您可能需要

$myLabel->update;

在循环内部调用用于显示输出的任何内容。就我而言,我使用 Label 在使用 system() 进行调用的循环中输出进度消息。使用 ->update 完美解决了这个问题(而 DoOneEvent() 没有)。

希望能帮助那里的人。

Not sure if this will help others with a similar problem, but just in case it does:

MainLoop();

is what "starts" the tk process. Good practice would be to set up all your widgets, callbacks and anything you want to show up on screen first, then call the MainLoop(). Processing should occur after the MainLoop() is called. In the above, you will probably need to call

$myLabel->update;

inside the loop on whatever it is you are using to display your output. In my case I was using a Label to output progress messages in a loop that made calls using system(). Using ->update solved it perfectly (while DoOneEvent() did not).

Hope that helps somebody out there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文