Kivy with asyncio. Error when changing screen in .kv file - python

I have cut down my code to focus on only the problem I have.
The asyncio part of my code is working -I have left stubs for these procs.
When I incorporated my user interface kivy code and my asyncio kivy code, I get the above error on a screen change.
I think I need to get an "App" setup with Builder.load_file() inside it ??, but my attempts to do so have failed.
Hope someone can help ?
On clicking the "Post a Photo!" button I get this error...
File "C:\TEMP\kivy1\kivy_venv\src\screens.kv", line 31, in <module>
on_press: app.switch_screen='TakePhotoScreen'
File "C:\TEMP\kivy1\kivy_venv\lib\site-packages\kivy\lang\parser.py", line 83, in __setattr__
object.__getattribute__(self, '_ensure_app')()
File "C:\TEMP\kivy1\kivy_venv\lib\site-packages\kivy\lang\parser.py", line 70, in _ensure_app
app.bind(on_stop=lambda instance:
AttributeError: 'NoneType' object has no attribute 'bind'
Code: screen.kv
Manager:
TestMyFeedScreen3:
TakePhotoScreen:
#:import ScrollEffect kivy.effects.scroll.ScrollEffect
#:import Window kivy.core.window.Window
<TestMyFeedScreen3>:
name:'TestMyFeedScreen3'
id:TestMyFeedScreen3
orientation: 'vertical'
GridLayout:
cols:1
rows:2
height: 50
Label:
text: 'My Story'
size_hint_y: None
height: 50
GridLayout:
cols:2
rows:1
height: 50
Button:
text: 'Post a Photo!'
size_hint_y: None
height: '48dp'
# ERROR HERE >>>>>>>>>>>>>>>>>>>>>>>>>>>>
#on_press: app.root.current='TakePhotoScreen'
on_press: app.switch_screen='TakePhotoScreen'
Button:
text: 'Back'
size_hint_y: None
height: '48dp'
on_release:
app.root.current='TestMyFeedScreen3'
root.manager.transition.direction = "left"
ScrollView:
effect_cls: ScrollEffect
size_hint: 1, None
size: Window.width, (Window.height -100)
bar_width: 5
bar_color: 1, 0, 0, 1 # red
bar_inactive_color: 0, 0, 1, 1 # blue
scroll_type: ['bars','content'] # move scrool by bar or photos
GridLayout:
id:picsx
do_scroll_x: False
height: self.minimum_height
size_hint_y: None
spacing: 3, 3
cols: 3
Button:
#text:'Pic'
background_normal: "Image1.PNG"
background_down: 'Click.PNG'
size_hint_y:None
height:100
<TakePhotoScreen>:
name:'TakePhotoScreen'
orientation: 'vertical'
GridLayout:
cols:1
rows:3
Button:
text: 'Take Photo and Post It !'
size_hint_y: None
height: '48dp'
Button:
text: 'Back'
size_hint_y: None
height: '48dp'
Image:
id: imageView
source: 'mob_photo.jpg'
allow_stretch: True
Code: mainx.py
# This code has been cut down to focus on the error
from __future__ import print_function
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
from kivy.config import Config
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
import asyncio
from kivy.app import async_runTouchApp
from kivy.cache import Cache
import aioconsole
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
images = 1
#client_number = sys.argv[1]
client_number = "0"
print("This is client " + client_number)
Config.set('graphics', 'width', '380')
Config.set('graphics', 'height', '700')
async def send_messages(writer, stdin):
print("In send_messages stub")
async def receive_messages(reader, stdout):
print("In receive_messages stub")
async def run_client():
print("In run_client")
Code
# This code has been cut down to focus on the error
from __future__ import print_function
import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.lang import Builder
from kivy.config import Config
from kivy.uix.popup import Popup
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
import asyncio
from kivy.app import async_runTouchApp
from kivy.cache import Cache
import aioconsole
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty
images = 1
#client_number = sys.argv[1]
client_number = "0"
print("This is client " + client_number)
Config.set('graphics', 'width', '380')
Config.set('graphics', 'height', '700')
async def send_messages(writer, stdin):
print("In send_messages stub")
async def receive_messages(reader, stdout):
print("In receive_messages stub")
async def run_client():
print("In run_client")
# Screen code
class TestMyFeedScreen3(Screen):
pass
class TakePhotoScreen(Screen):
pass
class Manager(ScreenManager):
pass
kv=Builder.load_file('screens.kv')
root = kv
async def run_app_happily(root, other_task):
# This method, which runs Kivy, is run by the asyncio loop as one of the coroutines.
# we don't actually need to set asyncio as the lib because it is the
# default, but it doesn't hurt to be explicit
await async_runTouchApp(root, async_lib='asyncio') # run Kivy
print('App done')
# now cancel all the other tasks that may be running
other_task.cancel()
if __name__ == '__main__':
def root_func():
while True:
print("In __main__")
other_task = asyncio.ensure_future(run_client())
return asyncio.gather(run_app_happily(kv, other_task), other_task)
loop = asyncio.get_event_loop()
loop.run_until_complete(root_func())
loop.close()

Since you don't have an actual App in your code, you cannot reference it in the line:
on_press: app.switch_screen='TakePhotoScreen'
but you can reference the ScreenManager and change the current Screen like this:
Button:
text: 'Post a Photo!'
size_hint_y: None
height: '48dp'
# ERROR HERE >>>>>>>>>>>>>>>>>>>>>>>>>>>>
on_press: root.manager.current='TakePhotoScreen'
You have a similar situation elsewhere in your code.

Related

Pictures comes up on simulator but doesn’t on iPhone

I’m trying to make app with kivy-iOS. It works perfectly on simulator, but doesn’t on iPhone.
On iPhone, App works with characters, but only pictures are vanished.
My app has only easy structure, Buttom has .jpg background, once push it, it goes to other buttons.
I use Pycharm to make .py and .kv file. On .kv,
<MenuScreen>:
canvas:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
GridLayout:
rows: 3
cols: 3
Button:
background_normal: "../file-ios/filename/filename.jpg"
text_size: self.size
valign: "top"
color: 0, 1, 0, 1
font_size: "30"
bold: True
text: "text"
on_press: root.manager.current = 'Ask'
(abbreviate)
On main.py
from kivy.config import Config
Config.set('graphics', 'width', '500')
Config.set('graphics', 'height', '500')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.uix.behaviors import ButtonBehavior
from kivy.uix.image import Image
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.graphics.texture import Texture
from kivy.properties import NumericProperty
from kivy.core.text import LabelBase, DEFAULT_FONT
from kivy.resources import resource_add_path
resource_add_path("/System/Library/Fonts")
LabelBase.register(DEFAULT_FONT, "ヒラギノ角ゴシック W0.ttc")
class MenuScreen(Screen):
pass
(abbreviate)
class mainApp(App):
def build(self):
sm = ScreenManager()
sm.add_widget(MenuScreen(name='menu'))
(abbreviate)
return sm
def __init__(self, **kwargs):
super(mainApp, self).__init__(**kwargs)
self.title = "Filename"
if __name__ == "__main__":
mainApp().run()
I’ve already tried CleanBuildFolder.
If you have some advice, please help me. Thanks in advance.

i was trying to make an app using python and kivy although code is fine and not throwing any error i am getting black screen

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.button import Button
Window.size = (500,700)
Builder.load_file('calc.kv')
class MyLayout(Widget):
pass
class App(App):
def build(self):
return MyLayout()
if __name__ == "__main__":
App().run()
this is my calc.py please help me to solve the problem
#:kivy 2.0.0
BoxLayout:
orientation:"vertical"
size: root.width, root.height
TextInput:
id: clac_input
text: "0"
halign: "right"
font_size : 65
size_hint: (1, .15)
GridLayout:
cols:4
rows:5
Button:
size_hint: (.2, .2)
font_size: 32
text: "%"
this is my calc.kv
From what I'm seeing the app is not returning any screens for your widgets to show on. I've changed a bit of your code to what I believe is correct that solves the issue.
.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.core.window import Window
from kivy.uix.button import Button
Window.size = (500,700)
Builder.load_file('calc.kv')
class MyLayout(Widget):
pass
class Screen1(Screen):
pass
class WindowManager(ScreenManager):
pass
class App(App):
def build(self):
return WindowManager()
if __name__ == "__main__":
App().run()
calc.kv
<WindowManager>:
Screen1
<Screen1>:
BoxLayout:
orientation:"vertical"
size: root.width, root.height
GridLayout:
cols:4
rows:5
TextInput:
id: clac_input
text: "0"
halign: "right"
font_size : 65
size_hint: (1, .15)
Button:
size_hint: (.2, .2)
font_size: 32
text: "%"

Kivy Cover Whole Screen

This is my kivy code:
Manager:
StartMenu:
SetupMenu:
<StartMenu>
name: "start"
size: root.width, root.height
GridLayout:
Image:
source: "Logo.png"
keep_ratio: True
size_hint: 1,1
AnchorLayout:
anchor_x: "center"
anchor_y: "bottom"
Button:
background_normal: ''
background_color: 242, 242, 242, .50
width: root.width/5
text: "Begin"
size_hint: None, None
on_release:
app.root.current: "setUp"
root.manager.transition.direction: "left"
</StartMenu>
<SetupMenu>
name: "setUp"
Button:
text: "Go Back"
on_release:
app.root.current: "startMenu"
root.manager.transition.direction: "left"
This is my Python code:
import kivy
from kivy.uix.button import Button
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.relativelayout import RelativeLayout
=from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
class StartMenu(Screen):
pass
class SetupMenu(Screen):
pass
class Manager(ScreenManager):
pass
class StartMenu(Screen):
pass
kv = Builder.load_file("lordofthe90.kv")
class lordOfThe90(App):
def build(self):
return kv
lordOfThe90.run()
How do I make both screens cover the entire window? I force a full screen within my game so I'd require their size to be the same as the screen resolution of the device they're on.
Also, does my code roughly look good? I'm very new to kivy as a whole.
I had to define at least rows: 1 in GridLayout: to display it correctly.

Can't get ObjectProperty to work with Kivy in python

I've been trying to fine a solution for a while. I rather not create the button in python, as I'm trying to keep the style away from the functionality. It reports this error every time I try to use Object Property. I've scoured all over trying a bunch of solutions on stackoverflow, so I'm hoping someone can help me out.
TypeError: bind() takes exactly 2 positional arguments (0 given)
As for the actual code, here is the python:
# Function import libraries
import sys
import json
import googlemaps
import pygatt
import time
import asyncio
from bleak import discover
from urllib.request import urlopen
from twilio.rest import Client
import asynckivy as ak
from asynckivy.process_and_thread import \
thread as ak_thread, process as ak_processt
# UI import libraries
from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.properties import StringProperty
from kivy.uix.widget import Widget
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.anchorlayout import AnchorLayout
from kivy.uix.label import Label
from kivy.uix.image import Image
from functools import partial
from kivy.event import EventDispatcher
class Screen1(Screen):
def __init__ (self,**kwargs):
super (Screen1, self).__init__(**kwargs)
pairbtn = ObjectProperty(None)
pairbtn.bind(on_press=self.pair_pressed)
# self.add_widget(pairbtn)
def pair_pressed(self, event):
async def run():
devices = await discover()
for d in devices:
print(d)
if (str(d).find('DSD TECH') != -1):
address = str(d)[0:17]
print("Device Discovered" + address)
exit()
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
class Screen2(Screen):
pass
class esosApp(App):
def build(self):
screen_manager = ScreenManager()
screenone = Screen1(name='s1')
screentwo = Screen2(name='s2')
screen_manager.add_widget(screenone)
screen_manager.add_widget(screentwo)
return screen_manager
if __name__ == '__main__':
esosApp().run()
And here is the kv file (screen2 omitted):
#:kivy 1.11.1
<Screen1>:
orientation: "vertical"
pairbtn: pairbtn
canvas.before:
Color:
rgb: 0.965,0.965, 0.965
Rectangle:
pos: self.pos
size: self.size
Image:
source: 'icon.png'
size: self.texture_size
AnchorLayout:
anchor_y: 'top'
BoxLayout:
size_hint: 1,.07
canvas.before:
Color:
rgb: 0.6745 , 0.8353 , 0.8784
Rectangle:
pos: self.pos
size: self.size
Image:
source: 'Logo.PNG'
size: self.texture_size
AnchorLayout:
anchor_x: 'center'
anchor_y: 'bottom'
padding: (0, 10, 0, 10)
Button:
id: pairbtn
text: "Pair Device"
background_normal: ''
background_color: 0.6745 , 0.8353 , 0.8784, 1
size_hint: (.8, .1)
A property should not and cannot be declared within a method of the class but at the same level of a method, something like:
class Foo(Base):
prop = XProperty(default_value)
def __init__(self, **kwargs):
super().__init__(self, **kwargs)
# ...
And clearly your code does not meet that condition, also with your logic pairbtn is None so you cannot make the binding with on_press, and finally the easiest thing is to make the connection in kv:
# ...
Button:
id: pairbtn
text: "Pair Device"
background_normal: ''
background_color: 0.6745 , 0.8353 , 0.8784, 1
size_hint: (.8, .1)
on_press: root.pair_pressed()

Scrollview to display different videos in kivy lags after a while

I'm a beginner in kivy and python. I've been trying to create a scrollview in a page that displays selected video on the screen. But after a while when i selected 5-6 videos to display even though i delete the video widget it starts to lag. And i'm open to any suggestions to better way to handle this kind of application.
from kivy.config import Config
Config.set('graphics', 'width', '1920')
Config.set('graphics', 'height', '1080')
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.properties import StringProperty
from kivy.uix.scrollview import ScrollView
from kivy.uix.label import Label
from kivy.clock import Clock
from kivy.uix.button import Button
import os
from kivy.uix.video import Video
from kivy.uix.videoplayer import VideoPlayer
from kivy.clock import mainthread
from functools import partial
from kivy.core.window import Window
Window.clearcolor = (0, 0, 0, 0)
isThereVideo=False
picture_path="/home/linux/kivyFiles/kivyLogin/assets"
video_path="/home/linux/kivyFiles/kivyLogin/videoAssets/"
class Image(Image):
pass
class MainScreen(Screen):
pass
class AnotherScreen(Screen):
pass
class Selfie(Screen):
pass
class RootWidget(Widget):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
Clock.schedule_once(self.createMultipleButton)
#mainthread
def createMultipleButton(self, dt):
self.root = Widget()
size_y=150;
size_x=150;
for i in range(1):
folderList = os.listdir(picture_path)
if len(folderList)==0:
time.sleep(1)
break
fileList = os.listdir(picture_path)
print fileList
for file in fileList:
x = (picture_path+"/"+file)
button = Button(id=str(file),text="" + str(file),size_hint=(None, None),height=size_y,width=size_x, pos_hint={'x': 0, 'y': 1},background_normal=x)
button.bind(on_release=partial(self.VideoContainer, file))
print file
self.scrollview.content_layout.add_widget(button)
print button.id
print("Parent of ScreenTwo: {}".format(self.parent))
#print(button.pos)
def VideoContainer(self,name,btn):
global isThereVideo
if isThereVideo==True:
#self.videocontainer.video_layout.unload()
self.videocontainer.clear_widgets()
mylist=name.split('.')
emailButton = Button(id='email')
video = Video(source="/home/linux/kivyFiles/kivyLogin/videoAssets/"+mylist[0]+".mp4", state='play',options={'eos': 'loop'})
video.size=(self.parent.width,self.parent.height)
video_pos=(self.parent.x,self.parent.y)
#video.pos_hint={'x': self.parent.width /2, 'y': self.parent.height/2}
video.play=True
#video.pos=(self.parent.width /2 , self.parent.height/2)
#self.videocontainer.video_layout.add_widget(emailButton)
self.videocontainer.add_widget(emailButton)
emailButton.add_widget(video)
isThereVideo=True
print("Parent of ScreenTwo: {}".format(self.parent))
return 0
class ScreenManagement(ScreenManager):
pass
class VideoContain(Widget):
pass
class ScrollableContainer(ScrollView):
pass
presentation = Builder.load_file("login.kv")
class MainApp(App):
def build(self):
return presentation
if __name__ == '__main__':
Window.fullscreen = True
app=MainApp()
app.run()
And my Kv file
ScreenManagement:
MainScreen:
Selfie:
<MainScreen>:
name: 'main'
Button:
on_release: app.root.current = 'selfie'
text: 'Another Screen'
font_size: 50
<Selfie>:
name: 'selfie'
Button:
on_release: app.root.current = 'login'
text: 'Selfie Screen'
font_size: 10
pos_hint: {"right": 1, 'top':1}
size_hint: (0.1, 0.1)
RootWidget:
<RootWidget>
size_hint: (0.1, None)
scrollview: scrollview
videocontainer:videocontainer
size:(self.parent.width, self.parent.height)
VideoContain:
id:videocontainer
##size:(self.parent.width, self.parent.height)
size:(root.width, root.height)
ScrollableContainer:
id: scrollview
size: root.size
pos: root.pos
<VideoContain>
video_layout:video_layout
FloatLayout:
cols:1
id: video_layout
<ScrollableContainer>:
scroll_timeout: 75
scroll_distance: 10
app: app
content_layout: content_layout
GridLayout:
id: content_layout
cols: 1
size_hint: (0.1, None)
pos: root.pos
height: self.minimum_height
padding: 25
spacing: 25
I posted all my code since i don't know which part may causing the problem i'm facing.
Solved it.
def VideoContainer(self,name,btn):
global isThereVideo
if isThereVideo:
# self.videocontainer.video_layout.unload()
self.videocontainer.clear_widgets()
In this part i'm clearing the widgets but i also need to unload the video somehow.
self.video.unload() solved my problem

Categories