让I/O读取器在Kivy中改变屏幕



当我开始学习kivy时,我想要一个NFC读卡器来检测NFC卡,并在使用的两个读卡器上是否有卡上显示某些屏幕。

我的问题现在包括这样一个事实,我根本不能通过check_variables函数改变屏幕。是否有任何方法可以访问布尔属性的值,或者我必须使用回调?

如果我必须使用回调函数,我如何区分卡片是放在读卡器1上,2上还是两者上都有卡片?(我希望有一个相应的屏幕,上面写着"在读卡器2上放置卡片";反之亦然)

.kv文件


ScreenManager:
id: screen_manager
IdleScreen:
id: idle        
manager: screen_manager
TagOn1Screen:
name:"tagon1"
id: tagon1
manager: screen_manager
TagOn2Screen:
name: "tagon2"
manager: screen_manager
TagOnBothScreen:
id: tagonboth
manager: screen_manager
ErrorScreen:
id: error
manager: screen_manager
<IdleScreen>:

BoxLayout:

Label:
text:"IdleScreen"

<TagOn1Screen>:

Label:
text:"Tagon1Screen"

<TagOn2Screen>:

Label:
text:"Tagon2Screen"

<TagOnBothScreen>:

Label:
text:"tagonbothScreen"

<ErrorScreen>:
Label:
text:"ErrorScreen"

.py文件

#!/usr/bin/env python3.7
from time import sleep
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.clock import Clock
from kivy.uix.widget import Widget
from kivy.properties import BooleanProperty, ObjectProperty
from kivy.event import EventDispatcher
from functools import partial
from time import sleep
#import concurrent.futures
from Simple_RFID import SimpleMFRC522
import RC522_mod
import RPi.GPIO as GPIO
from threading import Thread

TAG_ON_1 = False
TAG_ON_2 = False
id1 = ObjectProperty(None)
id2 = ObjectProperty(None)
text1 = ObjectProperty(None)
text2 = ObjectProperty(None) 

class IdleScreen(Screen):




def check_for_tag(reader, msg):
global TAG_ON_1
global TAG_ON_2
print(msg)
(status, TagType) = reader.READER.MFRC522_Request(reader.READER.PICC_REQIDL)
while status != reader.READER.MI_OK:
sleep(0.1)
(status, TagType) = reader.READER.MFRC522_Request(reader.READER.PICC_REQIDL)
if status == reader.READER.MI_OK:
break
if status == reader.READER.MI_OK:
if msg == "1":
TAG_ON_1=True
id1, text1 = reader.read()
print("Funktion hier: TAG auf 1 zu true gesetzt")
else:
TAG_ON_2 = True
print("Funktion hier: TAG auf 2 zu true gesetzt")
id2, text2 = reader.read()
#print (f" Tag Read, id= {id} Reader = {msg}")
pass 

def on_enter(self, *args):
reader_0 = SimpleMFRC522(0,0,15)
reader_1 = SimpleMFRC522(1,0,22)
t1= Thread(target=IdleScreen.check_for_tag, args=(reader_0,'1'))
t2= Thread(target=IdleScreen.check_for_tag, args=(reader_1,"2"))
t1.daemon=True
t2.daemon=True
t1.start()
t2.start()
print("Startup initialized")

pass
class TagOn1Screen(Screen):
pass
class TagOn2Screen(Screen):
pass
class TagOnBothScreen(Screen):
pass
class ErrorScreen(Screen):
pass

kv = Builder.load_file('Stylefile.kv')
class FotoboxApp(App):
global TAG_ON_1
global TAG_ON_2
global id1
global id2
global text1
global text2



def build(self):
'''
sm = ScreenManager()
sm.add_widget(IdleScreen(name="idle"))
sm.add_widget(TagOn1Screen(name="tagon1"))
sm.add_widget(TagOn2Screen(name="tagon2"))
sm.add_widget(TagOnBothScreen(name="tagonboth"))
sm.add_widget(ErrorScreen(name="error"))
return sm
'''

return kv

def on_stop(self):
print("Kehring & Beenden!")
Clock.stop()
GPIO.cleanup()

def check_variables(self, *args):

print("checking variables")
print(f"Tag on 1 = {TAG_ON_1}")
print(f"Tag on 2 = {TAG_ON_2}")
if TAG_ON_1 == True and TAG_ON_2 == False:
self.root.ids.screen_manager.current = self.root.ids.screen_manager.tagon1
if TAG_ON_1 is False and TAG_ON_2:
self.root.ids.screen_manager.current=tagon2
if TAG_ON_1 is True and TAG_ON_2 is True:
self.root.ids.screen_manager.current=tagonboth
if TAG_ON_1 is False and TAG_ON_2 is False:
print("No tag Found")

Clock.schedule_interval(check_variables,1)
if __name__ == '__main__':
FotoboxApp().run()

提前感谢!

EDIT更新了。ky和。py文件,并移动了主应用程序类中的check_variables

不是在IdleScreen类中定义check_variables,而是在主应用程序中定义它。在.kv中使用屏幕管理器来管理屏幕并给它一个id,让我们说screen_manager。然后,当你想改变屏幕时,只需使用代码self.root.ids.screen_manager.current = "screen_name"

最新更新