Althoug my example code isn't one of the shortest this is the minimal code that presents the inner working of my App.
My Goal is to have saving popup dialog that updates progress bar (not in this example-not the issue). If you try to run this code you will see button "save" - after clicking it popup displays.
However I present update loop in the progress_bar() method suddenly the Popup is no longer displayed - WHY?
I was looking around the internet for the solution. At first I thought this has something to do with treading I was using to have popup updated while actually saving the file in another thread, but this example has no threading and the actual method is commented so the problem must be elsewhere.
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.popup import Popup
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from time import sleep
# Main app with save method
class MainApp(App):
def build(self):
sm = ScreenManager()
self.save = save(app=self, name='save')
sm.add_widget(self.save)
self.saved_percent = 0.0
return sm
def save_file(self,file_path):
for i in range(0,10):
sleep(1)
self.saved_percent = i * 10.0
print("saved",i)
self.save_finnished = True
return 256 # check for written bytes
# one of many screens - this one is for saving
class save(Screen):
def __init__(self, app, **kwargs):
super(Screen,self).__init__(**kwargs)
self.app = app
lyo = BoxLayout(orientation='vertical')
btn = Button(text="Save", size=(10,10))
btn.bind(on_press=self.begin_save)
lyo.add_widget(btn)
self.add_widget(lyo) # basic layout to init the save
def begin_save(self,*args):
self.app.save_finnished = False
self.cancel_save = False
file_path = 'foo.txt' # debug static
self.progress_bar(file_path) # TODO put in separate thread and continue
#save_file(self,file_path)
def progress_bar(self, file_path):
btn = Button(text="Cancel")
btn.bind(on_press=self.btn_cancel_save)
pop = Popup(title="Saving", content=btn, auto_dismiss=False)
pop.open() # does not open
# this loop is somehow causing the Popup not to display
#while (not self.app.save_finnished and not self.cancel_save):
# pass # progres bar is being updated here
#pop.dismiss() # dismiss after exiting the loop
def btn_cancel_save(self, *args):
print("Cancel clicked")
self.cancel_save = True
if __name__ == "__main__":
top=MainApp()
top.run()
#
#import kivy
#from kivy.app import App
#from kivy.uix.screenmanager import ScreenManager, Screen
#from kivy.uix.boxlayout import BoxLayout
#from kivy.uix.progressbar import ProgressBar
#from kivy.uix.popup import Popup
#import threading
#from kivy.uix.label import Label
#from kivy.uix.button import Button
#from kivy.uix.boxlayout import BoxLayout
#from time import sleep
#from kivy.lang import Builder
#import queue
#
## Main app with save method
#class MainApp(App):
# def build(self):
# sm = ScreenManager()
# self.save = save(app=self, name='save')
# sm.add_widget(self.save)
# self.saved_percent = 0.0
# return sm
#
# def save_file(self,file_path):
# for i in range(0,10):
# sleep(1)
# self.saved_percent = i * 10.0
# print("saved",i)
# return 256 # check for written bytes
#
## one of many screens - this one is for saving
#class save(Screen):
# def __init__(self, app, **kwargs):
# super(Screen,self).__init__(**kwargs)
# self.app = app
# lyo = BoxLayout(orientation='vertical')
# btn = Button(text="Save", size=(10,10))
# btn.bind(on_press=self.begin_save)
# lyo.add_widget(btn)
# self.add_widget(lyo) # basic layout to init the save
#
# def begin_save(self,*args):
# self.save_finnished = False
# self.cancel_save = False
# file_path = 'foo.txt' # debug static
# #written = self.poi.save_file(file_path)
# #self.progress_bar(file_path)
#
# # some black magic with threads to get ret value
# # https://www.edureka.co/community/31966/how-to-get-the-return-value-from-a-thread-using-python
# #que = queue.Queue()
# #t = threading.Thread(target=lambda q, arg1: q.put(self.app.save_file(arg1)), args=(que, file_path))
# #t.start()
# self.progress_bar(file_path)
# #progress_bar_thread = threading.Thread(target=self.progress_bar, args=(file_path,))
# #progress_bar_thread.start()
# #t.join()
# #written = que.get()
#
## self.save_finnished = True
## size = os.path.getsize(file_path)
## if(not self.btn_cancel_save):
## if(written == size):
## print("OK")
## self.ok_dialog(True)
## else:
## print("Error saving to POI")
## self.ok_dialog(False)
#
# def progress_bar(self, file_path):
# print("progress bar fnc ")
# #lyo = BoxLayout(orientation='vertical')
# #pb = ProgressBar(max=100.0)
# #lbl = Label(text='0 %')
# btn = Button(text="Cancel")
# btn.bind(on_press=self.btn_cancel_save)
# #lyo.add_widget(Label(text=file_path))
# #lyo.add_widget(pb)
# #lyo.add_widget(lbl)
# #lyo.add_widget(btn)
#
# #pop = Popup(title="Saving", content=lyo, auto_dismiss=False)
# pop = Popup(title="Saving", content=btn, auto_dismiss=False)
# pop.open() # does not open
#
## print("start update loop")
## print("finished?",self.save_finnished, "cancel?" ,self.cancel_save)
# while (not self.save_finnished or not self.cancel_save):
# pass # progres bar is being updated here
## pb.value = self.app.saved_percent
## s = '%.12f' % self.app.saved_percent
## i, p, d = s.partition('.')
## str_percent = '.'.join([i, (d+'0'*2)[:2]])
## lbl.text = str_percent +' %'
## #print(" # ")
# print("out of update loop - dismiss pop")
# pop.dismiss()
#
# def ok_dialog(self,success):
# if(success):
# title = "SUCCESS"
# else:
# title = "FAILED"
# btn = Button(text="OK")
#
# pop = Popup(title=title, content=btn, auto_dismiss=False)
# btn.bind(on_press=pop.dismiss)
# pop.open()
#
#
# def btn_cancel_save(self, *args):
# print("Cancel clicked")
# self.cancel_save = True
#
#
#if __name__ == "__main__":
# top=MainApp()
# top.run()