I am wrote a piece of python code that handles multiple processes and it works great, but I am trying to add a Kivy based display to this code. I have updated the code to be able to use threads instead of processes, which works. The issue that I have is that I can't seem to get the threads to write back to the screen. I am using @mainthread
. I found a sample code here, and was able to get the threads to update the screen, but for some reason my code doesn't seem to work.
->Edit, I have removed the extra code that I don't believe is pertinent to my question.
->Edit #2:, I have still simplified the code to what I believe is bare. To still show the issue that I have. From what I have read, it may be the x.join
code that is causing me the issue, and locking up the main loop. I need to run the while loop 5 times, but can only run 2 threads at a time. Need to hold the while loop in a non-blocking state while threads finish before proceeding.
Here is menu.kv
<ScreenManagement>:
MenuScreen:
ProgramScreen:
<MenuScreen>:
name: 'menu'
AnchorLayout:
GridLayout:
cols: 2
Button
text: "Start Application"
on_release: root.routine()
<ProgramScreen>:
filler1: filler1
filler2: filler2
filler3: filler3
filler4: filler4
name: 'program'
GridLayout:
cols: 4
Button:
id: filler1
text: 'Filler 1'
halign: 'center'
padding_y: '300'
bcolor: 1,0,1,1
Button:
id: filler2
text: 'Filler 2'
halign: 'center'
padding_y: '300'
bcolor: 1,0,0,1
Button:
id: filler3
text: 'Filler 3'
halign: 'center'
padding_y: '300'
bcolor: 1,0,1,0
Button:
id: filler4
text: 'Filler 4'
halign: 'center'
padding_y: '40 '
bcolor: 0,0,1,1
Here is my main.py
from kivy.app import App
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.lang import Builder
from kivy.properties import *
from kivy.core.window import Window
from kivy.clock import Clock, mainthread
import threading
import time
########################################################################
class ScreenManagement(ScreenManager):
pass
class MenuScreen(Screen):
def routine(self):
self.parent.current = 'program'
threading.Thread(target=ProgramScreen().build).start()
class ProgramScreen(Screen):
@mainthread
def update_label(self, int_counter, new_text):
if int_counter == 0 :
print "here ", int_counter, new_text
self.filler1.text = new_text
elif int_counter == 1 :
self.filler2.text = new_text
elif int_counter == 2 :
self.filler3.text = new_text
elif int_counter == 3 :
self.filler4.text = new_text
else:
self.filler1.text = "fault"
#dummy function to be replaced with a function that will call GPIO for input and feedback.
def func (self,value):
print 'func', value, 'starting'
for i in xrange(10*(value+1)):
if ((i%3) == 0):
self.update_label(int(value),str(i))
print value, i
time.sleep(1)
print 'func', value, 'finishing'
def build(self):
NumberofFiller = 2
NumberofCells = 5
CellCounter = 0
while CellCounter < NumberofCells:
try:
threads = []
print ('Counter:',CellCounter,'Fillers:',NumberofFiller,'Cells:',NumberofCells)
for i in range (NumberofFiller):
t = threading.Thread(target=self.func, args=((CellCounter%NumberofFiller),))
t.start()
threads.append(t)
CellCounter = CellCounter +1
for x in threads:
#Problem I believe is here.
x.join()
#Need a way to pause the While loop for the first set of threads to finish before starting the next threads.
# print (threads)
except (KeyboardInterrupt, SystemExit):
functions.cleanAndExit()
########################################################################
#Builder.load_file("Menu_red.kv") #Not needed
class Menu_red2App(App):
def build(self):
return ScreenManagement()
#----------------------------------------------------------------------
if __name__ == "__main__":
Menu_red2App().run()
The only way that I could find to have the screen update, after executing self.parent.current = 'program'
was to run the rest of the code as a thread. But I now I can't seem to get the threads to write back to the main function to update the screen. In the end, once the text has been updated, I will need to change the color of the boxes, but that will come in due course.