首页 > 解决方案 > 具有长时间运行进程的 wxPython 冻结动画 gif

问题描述

我正在尝试运行 python 长进程,但我需要对未冻结显示动画 gif 的用户说。

我的问题是我有 3 或 4 个长进程,要运行第二个进程,这取决于第一个进程的结果,因此这使得无法在线程中运行这些进程。有没有办法做到这一点?在我的示例中,我只有两个过程来说明我这样做的方式。

import wx
from wx.adv import Animation, AnimationCtrl
import speedtest
import socket

class MainFrame(wx.Frame):
    def __init__(self, *args, **kw):
        # ensure the parent's __init__ is called
        super(MainFrame, self).__init__(*args, **kw)

        # create a panel in the frame
        self.pnl = wx.Panel(self)
        self.pnl.SetBackgroundColour(wx.Colour(81, 87, 129))

        # and put some text with a larger bold font on it
        st = wx.StaticText(self.pnl, label="Speed Test", pos=(200,10))
        font = st.GetFont()
        font.PointSize = 14
        font = font.Bold()
        st.SetForegroundColour("white")
        st.SetFont(font)

        self.anim = Animation('pictures/wait.gif')
        self.ctrl = AnimationCtrl(self.pnl, -1, self.anim)
        self.ctrl.SetPosition((70,50))

    def AnimeControl(self, status):
        if status:
            self.ctrl.Play()
        else:
            self.ctrl.Stop()

class NetworkChecks():
    def __init__(self):
        pass

    def resolve_dns(self, host):
        try:
            data = socket.gethostbyname_ex(host)
            if "error" in data:
                return False
        except Exception, e:
            print "resolve_dns: ", e
            return False
        return data

    def speed_test(self):
        try:
            servers = []
            threads = None
            st = speedtest.Speedtest()
            st.get_servers(servers)
            st.get_best_server()
            st.download(threads=threads)
            st.upload(threads=threads)
            st.results.share()
            return st.results.dict()
        except Exception, e:
            print "speed_test: ", e
            return False 

if __name__ == '__main__':
    app = wx.App()
    frm = MainFrame(None, title='NDT', size=(480, 330), style=wx.DEFAULT_DIALOG_STYLE | wx.MINIMIZE_BOX)
    frm.AnimeControl(True)
    frm.Show()

    wx.Yield()

    dns_name = NetworkChecks().resolve_dns('dns.google')

    if dns_name != False:
        speed_results = NetworkChecks().speed_test()
        if speed_results != False:
            print "Speed test results:"
            print "Internet ip: " + speed_results['client']['ip']
            print "Service ip : " +  speed_results['client']['isp']
            print "Download tx: " + '{0:.4g}'.format(speed_results['download'] / 1000000) + " Mbps"
            print "Upload tx  : " + '{0:.4g}'.format(speed_results['upload'] / 1000000) + " Mbps"
        else:
            print "Was not possible to test the internet link speed "
    frm.AnimeControl(False)
    app.MainLoop()

标签: pythonmultithreadingwxpythonanimated-gif

解决方案


您应该在单独的线程中启动长时间运行的进程,而不是在主 GUI 中。有关一些想法和实现,请参见此处:

https://wiki.wxpython.org/LongRunningTasks

使用 wx.CallAfter 和 wx.PostEvent 是保持 GUI 响应的最佳选择,而其他线程和进程继续执行它们的操作。


推荐阅读