Keeping the GUI responsive during shutil.copy command.

60 views
Skip to first unread message

Michael

unread,
Jul 22, 2016, 6:39:29 PM7/22/16
to Kivy users support


I've got a simple PC app that has a command that will transfer/copy larger sized media files using shutil.copy.

I'd rather not have the interface be completely unresponsive ( spinning beach ball, etc.) until that operation is complete.  This may be completely unavoidable but it would be great if there was an approach that allowed some degree of responsiveness ( or feedback ) during the process.

If so what is the best approach to this?

Thanks!

Damien Moore

unread,
Jul 22, 2016, 6:41:59 PM7/22/16
to Kivy users support
Do your copying on a threading.Thread and notify the main thread when you are done using Kivy's Clock.schedule_once.

Michael

unread,
Jul 22, 2016, 6:49:01 PM7/22/16
to Kivy users support
Awesome.  Thanks Damien.  I'll look into that.  I'm still kind of new to this GUI stuff.

Damien Moore

unread,
Jul 22, 2016, 9:12:36 PM7/22/16
to Kivy users support
Also see https://github.com/kivy/kivy/wiki/Working-with-Python-threads-inside-a-Kivy-application

There's a nice @mainthread decorator that lets you define functions that even if you call from a thread will get called from Kivy's UI thread. If you try to modify kivy classes (or possibly just even touch them) from a worker thread your app can and most likely will crash.

Message has been deleted

Michael

unread,
Jul 23, 2016, 5:44:38 PM7/23/16
to Kivy users support
Alright, I feel like an idiot but I've spent the whole day trying to wrap my head around this threading thing.  Most of the examples I've seen are still a little too elaborate for my feeble mind to follow and I'm not sure I'm any closer to working something in.  The Kivy example above unfortunately crashes for me so I haven't been able to dissect it as well as I had hoped.  I know it's slightly beyond the purview of this forum but could someone please show me a simple example based on this simple script below to get me going?


Thanks so much!

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
import os
import time
import threading



Builder.load_string("""
<MainScreen>:

BoxLayout:
orientation: 'vertical'
BoxLayout:
Label:
id: _Log

#this button's activity should be in it's own thread:
Button:
text: 'GO'
on_release: root.go()
""")


class MainScreen(FloatLayout):



###This would be in it's own thread:
def WriteFile(self):
print 'Hello'
print "This shoud be happening in it's own thread"
self.ids._Log.text = "This shoud be happening in it's own thread"
def go(self):
for i in xrange(3):
time.sleep(1)
self.WriteFile()  





class SimpleTest(App):
def build(self):
return MainScreen()

if __name__ == "__main__":
SimpleTest().run()


Damien Moore

unread,
Jul 23, 2016, 6:03:17 PM7/23/16
to Kivy users support
Try this:

from kivy.app import App
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.clock import mainthread
import os
import time
import threading


Builder.load_string(
"""

<MainScreen>:


    BoxLayout:
        orientation: 'vertical'
        BoxLayout:
        Label:
            id: _Log
            text: 'test'



#this button's activity should be in it's own thread:
        Button:
            text: 'GO'
            on_release: root.go()
"""
)




class MainScreen(FloatLayout):
   
def WriteFile(self):
       
print 'Hello'
       
self.update_label('starting worker job')
        time
.sleep(1)
       
self.update_label('ended worker job')
       
self.notify_finished()
   
def go(self):
       
print 'pressed go'
        thread
= threading.Thread(target = self.WriteFile)
        thread
.start()


   
@mainthread
   
def notify_finished(self):
       
print 'job done'
       
self.ids._Log.color = (200,200,0,255)


   
@mainthread
   
def update_label(self, message):
       
print 'got message request',message
       
self.ids._Log.text = message






class SimpleTest(App):
   
def build(self):
       
return MainScreen()


if __name__ == "__main__":


   
SimpleTest().run()


Michael

unread,
Jul 23, 2016, 6:19:38 PM7/23/16
to Kivy users support
Fantastic once again Damien.  Helpful and educational.

Thanks!
Reply all
Reply to author
Forward
0 new messages