简体   繁体   中英

wxPython with long running process freeze the animated gif

I'm trying to run python long processes, but I need to say to the user that is not frozen showing an animated gif.

My issue is I have 3 or 4 long processes and to run the second, it depends the result from the first, so this make not possible to run those processes in threads. Is there some way to do this? In my example I have only two process just for illustrate the way that I'm doing this.

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

You should start your long-running processes in a separate thread, not in the main GUI one. See here for some ideas and implementations:

https://wiki.wxpython.org/LongRunningTasks

The use of wx.CallAfter and wx.PostEvent is your best bet to keep the GUI responsive while other threads and processes go along doing their things.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM