I have an Open CV Kivy app that has 2 screens. The screen 1 (ProblemWindow) will get the user input and The live video from the webcam will be shown on screen 2 (StepsWindow). However, I need to pass one of the values (Spinner id: problem_id) from screen 1 (ProblemWindow) into screen 2 (StepsWindow) and also use the value in the python file for additional logic.
Can anyone please guide me on how to achieve this? I am stuck here.
Python File:
# importing kivy dependencies
from kivy.app import App
from kivy.clock import Clock
from kivy.graphics.texture import Texture
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.uix.widget import Widget
# import other dependencies
import cv2 as cv
import numpy as np
from cv2 import aruco
# defining different screens
class WindowManager(ScreenManager):
pass
class ProblemWindow(Screen):
def selected_problem(self, value):
self.ids.click_label.text = f'selected problem: {value}'
return value
class StepsWindow(Screen):
def __init__(self, **kwargs):
print('Steps Window')
super().__init__(**kwargs)
# Capture the frames from the webcamera
self.capture = cv.VideoCapture(0)
Clock.schedule_interval(self.run_webcam, 1.0/30.0)
def run_webcam(self, *args):
"""Run continuously to get webcam feed"""
ret, frame = self.capture.read()
# Flip Horizontal and convert image into texture
buf = cv.flip(frame, 0).tobytes()
img_texture = Texture.create(size = (frame.shape[1], frame.shape[0]), colorfmt = 'bgr')
img_texture.blit_buffer(buf, colorfmt = 'bgr', bufferfmt = 'ubyte')
self.ids.web_cam.texture = img_texture # id is the id of the image from the kv file.
kv = Builder.load_file('window_manager.kv')
class main(App):
def build(self):
return kv
if __name__ == '__main__':
main().run()
cv.destroyAllWindows()
Kivy File:
WindowManager:
ProblemWindow:
StepsWindow:
<ProblemWindow>:
name: "problem_window"
GridLayout:
rows: 3
size: root.width, root.height
Label:
id: click_label
text: "Select a Problem"
font_size: 32
height: 20
Spinner:
id: problem_id
text: "selected problem"
values: ["Problem_1", "Problem_2"]
on_text: root.selected_problem(problem_id.text)
size_hint: 0.5, 0.5
Button:
text: "Show Steps"
font_size: 32
size_hint: 0.3, 0.3
on_release:
app.root.current = "steps_window"
root.manager.transition.direction = "left"
<StepsWindow>:
name: "steps_window"
web_cam: web_cam
GridLayout:
rows: 3
size: root.width, root.height
Label:
id: problem_name
text: "Selected Problem Name should come here"
font_size: '42'
size_hint_y: None
height: 50
Image:
id: web_cam
Button:
text: "Exit"
font_size: 32
size_hint: 0.1, 0.1
on_release:
app.root.current = "problem_window"
root.manager.transition.direction = "right"
CodePudding user response:
You can let Kivy handle that for you, by assigning the text to the problem_name
Label
using Properties
. First, assign an id
to the ProblemWindow
Screen
:
WindowManager:
ProblemWindow:
id: pw
StepsWindow:
Then use that id
to assign the text:
Label:
id: problem_name
text: root.manager.ids.pw.ids.problem_id.text
font_size: '42'
size_hint_y: None
height: 50
Because the text is assigned based on ids
and Properties
, Kivy will keep it updated for you. If you tried to use root.manager.get_screen('problem_window')
, it would not work because Kivy will not repeat method calls to update a value.