【问题标题】:Kivy with asyncio. Error when changing screen in .kv fileKivy 与 asyncio。在 .kv 文件中更改屏幕时出错
【发布时间】:2021-08-13 18:02:25
【问题描述】:

我已经减少了我的代码,只关注我遇到的问题。 我的代码的 asyncio 部分正在工作 - 我为这些 procs 留下了存根。 当我合并我的用户界面 kivy 代码和我的 asyncio kivy 代码时,我在屏幕更改时收到上述错误。 我认为我需要在其中安装一个带有 Builder.load_file() 的“应用程序”设置 ??,但我这样做的尝试失败了。 希望有人能帮忙? 点击“发布照片!”按钮我收到此错误...

   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'

代码: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

代码: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")

代码

# 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()

【问题讨论】:

    标签: python kivy python-asyncio kivy-language


    【解决方案1】:

    由于您的代码中没有实际的App,因此您无法在该行中引用它:

    on_press: app.switch_screen='TakePhotoScreen'
    

    但您可以引用 ScreenManager 并像这样更改 current Screen

            Button:
                text: 'Post a Photo!'
                size_hint_y: None
                height: '48dp'
                # ERROR HERE >>>>>>>>>>>>>>>>>>>>>>>>>>>>
                on_press: root.manager.current='TakePhotoScreen'
    

    您的代码中的其他地方也有类似的情况。

    【讨论】:

      猜你喜欢
      • 2018-05-25
      • 1970-01-01
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 1970-01-01
      • 2013-10-29
      • 1970-01-01
      相关资源
      最近更新 更多