I'm trying to create this functionality that when a physical button is pressed a function is called that if true opens a popup on the main Kivy screen. The idea was to have the display showing the menu but when an external function calls it opens the popup. To make both the waiting for the press of the button and the display work at the same time I went with threading but when I press the button Kivy gives:
TypeError: Cannot create graphics instruction outside the main Kivy thread.
I spent the last couple of nights trying to find a solution online but I did not come across any. Here's the python code:
from gpiozero import Button, DigitalOutputDevice
from time import sleep
from threading import Thread
#kivy imports
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.metrics import dp
from kivy.factory import Factory
from kivy.uix.label import Label
from kivy.uix.floatlayout import FloatLayout
from kivy.clock import Clock
hatch_btn = Button(20, bounce_time=0.2)
value = 6
x = 2
def function():
if value >x:
P.show_popup()
class P(FloatLayout):
def show_popup():
show = P()
popupWindow = Popup(title='Popup Window', content=show,
size_hint=(None,None),auto_dismiss=False, size=(400,400))
popupWindow.open()
class MainMenu(Screen):
pass
class displayApp(App):
def build(self):
return MainMenu()
def btn_loop():
while True:
if hatch_btn.is_pressed:
print('pressed')
sleep(1)
function()
else:
print('not pressed')
sleep(0.2)
thread = Thread(target=btn_loop)
thread.start()
if __name__ == '__main__':
displayApp().run()
And the kv file:
#kivy 2.0.0
#:import Factory kivy.factory.Factory
MainMenu:
<MainMenu>:
BoxLayout:
orientation:'vertical'
BoxLayout:
size_hint:1,0.2
Label:
size_hint: 0.3,1
text:'Logo'
Label:
text:'Title'
BoxLayout:
padding: 50
Button:
text:'sup'
Button:
text:'sup'
Button:
text:'sup'
Button:
text:'sup'
<P>:
Label:
text:'popup from physical input'
size_hint: 0.6, 0.2
pos_hint: {'x':0.2, 'top':1}
Button:
text: 'wish I could see the popup open...'
size_hint:0.8, 0.2
pos_hint: {'x':0.1,'y':0.1}
Is there any other way around this? I read something about using kivy.clock but I did not really understand it as I am a novice in both python and kivy. I also saw from the kivy docs that you can create a popup like this directly in the kv file; if there is a way with this method it would be even better because I'm trying to keep the graphical part separate.
#:import Factory kivy.factory.Factory
<MyPopup@Popup>:
auto_dismiss: False
Button:
text: 'Plz help:(!'
on_release: root.dismiss()
Button:
text: 'Open popup'
on_release: Factory.MyPopup().open()