如何:main.py,带有 kivy 轮播代码的新类,kv 文件
Posted
技术标签:
【中文标题】如何:main.py,带有 kivy 轮播代码的新类,kv 文件【英文标题】:howto: main.py, new class with code for kivy carousel, kv file 【发布时间】:2019-08-18 05:22:49 【问题描述】:我正在调整 kivy 的展示面板。主要有 kv 文件,通过 screenmanager 定义一个单独的屏幕。
我的目标是创建一个屏幕 (DiashowApp),用于启动 kivy 应用轮播 (https://kivy.org/doc/stable/api-kivy.uix.carousel.html)。因此我设置了两个类,加载轮播和显示图像,它们在 kv 文件 (diashowapp.kv) 中定义。
请帮助我运行代码。
问候 斯蒂芬
不要让类运行,带有打印语句的调试例程告诉我,没有执行两个新类的代码。
from time import time
from kivy.app import App
from os.path import dirname, join
from kivy.lang import Builder
from kivy.properties import NumericProperty, StringProperty, BooleanProperty,\
ListProperty
from kivy.clock import Clock
from kivy.animation import Animation
from kivy.uix.screenmanager import Screen
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from subprocess import call
import subprocess
from kivy.logger import Logger
import random
Logger.info('title: This is a info message.')
Logger.debug('title: This is a debug message.')
skript_axis_all = "data/screens_axis.sh"
skript_kill_axis = "data/screens_kill_axis.sh"
skript_axis_01 = "data/screens_axis01.sh"
skript_axis_02 = "data/screens_axis02.sh"
skript_axis_03 = "data/screens_axis03.sh"
skript_axis_04 = "data/screens_axis04.sh"
class CarouselApp(Carousel):
def __init__(self, **kwargs):
super(CarouselApp, self).__init__(**kwargs)
self.direction = "right"
bilderliste = []
cmd2 = ['find', '/home/pi/Bilder/', '-maxdepth', '2', '-type', 'f', '-name', '*.JPG']
proc2 = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
o2, e2 = proc2.communicate()
#print('Output: ' + o2.decode('utf-8'))
#print('Error: ' + e2.decode('utf-8'))
#print('code: ' + str(proc2.returncode))
o2_zeilen = o2.split('\n')
counter = 0
for zeile2 in o2_zeilen:
bilderliste.append(zeile2.replace('\n',''))
random.shuffle(bilderliste, random.random)
for bildpfad in bilderliste:
if counter < 50:
counter = counter + 1
print(counter)
src = "%s" % bildpfad
print type(bildpfad)
if bildpfad is not None:
print('Bildpfad ist: %s') % src
image = AsyncImage(source = src, keep_ratio = True, allow_stretch = True)
try:
self.add_widget(image)
except Exception:
Logger.exception('Something happened in the add.widget!')
else:
pass
self.loop = True
Clock.schedule_interval(self.load_next, 5)
#print(self.slides)
class ShowcaseScreen(Screen):
fullscreen = BooleanProperty(False)
def add_widget(self, *args):
if 'content' in self.ids:
return self.ids.content.add_widget(*args)
return super(ShowcaseScreen, self).add_widget(*args)
class ShowcaseApp(App):
index = NumericProperty(-1)
current_title = StringProperty()
time = NumericProperty(0)
show_sourcecode = BooleanProperty(False)
sourcecode = StringProperty()
screen_names = ListProperty([])
hierarchy = ListProperty([])
def build(self):
self.title = 'hello world'
Clock.schedule_interval(self._update_clock, 1 / 60.)
self.screens =
self.available_screens = sorted([
'CarouselApp', 'Carousel', 'Scatter', 'Cameras'])
self.screen_names = self.available_screens
curdir = dirname(__file__)
self.available_screens = [join(curdir, 'data', 'screens',
'.kv'.format(fn).lower()) for fn in self.available_screens]
self.go_next_screen()
carouselapp.kv
ShowcaseScreen:
name: 'CarouselApp'
fullscreen: True
CarouselApp:
预期: 自动旋转的显示屏。
实际: 图片显示正确,手动刷卡也正常。
【问题讨论】:
嗨 Stefan,欢迎来到 ***。请花几分钟阅读how to ask a good question。我不完全确定你在这里实际问的是什么,所以我建议你修改和改进你的问题。 你的应用类甚至不是应用类,而是屏幕类。 ...更改为“class DiashowApp(App)”,但没有效果。我误解了你的评论吗,el3ien? @Stefan 将Carousel:
更改为 Diashow:
@eyllanesc 我将 Carousel:
更改为 Diashow:
,但没有定期 load_next()。
【参考方案1】:
欢迎来到 SO :)
我不会修复你的代码。但是,如果您以示例为例,则再次链接到:kivy carousel。 如果您想要一个自动轮播,那么您可以使用 kivy 的Clock 来安排滚动轮播之间的 2 秒间隔。 试试这个:(编辑:在 kv 的屏幕中实现)
from kivy.app import App
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from kivy.clock import Clock
from kivy.lang import Builder
class MyCarousel(Carousel):
def __init__(self, **kwargs):
super(MyCarousel, self).__init__(**kwargs)
self.direction = "right"
for i in range(10):
src = "http://placehold.it/480x270.png&text=slide-%d&.png" % i
image = AsyncImage(source=src, allow_stretch=True)
self.add_widget(image)
self.loop = True
Clock.schedule_interval(self.load_next,2)
KV = """
ScreenManager:
Screen:
name: "scr1"
BoxLayout:
Button:
text: "Carousel"
on_release: root.current = "scr2"
Screen:
name: "scr2"
BoxLayout:
Button:
text: "Back"
on_release: root.current = "scr1"
MyCarousel:
"""
class CarouselApp(App):
def build(self):
return Builder.load_string(KV)
CarouselApp().run()
【讨论】:
早上好! :-) 感谢您的回答和示例代码(这是肯定的)。我的任务是通过kv文件集成到screenmanager中。 @Stefan Morning :) 我编辑了答案以在 kv 的屏幕上实现它。 哇,您的示例代码运行良好。试图在showcase.kv 中实现它是相当困难的...... @Stefan 应该很简单。你可能做错了。 它是一个观点,什么是简单的! :-) 那又怎样,由于您的代码注入 :-) 我走对了。我承认我必须编写更多代码,并通过 python 中的类获得更多基本编程的内部知识。谢谢你,el3ien,你用代码帮助了我很多,你不会给我主要的(当然是为了教学)!最好的问候,斯特凡。 (上面我已经插入了固定的代码行......)【参考方案2】:@el3ien 提前谢谢你。你是个好人,带我走上理解的道路。 :-) 在进一步集成 sreenmanager 之前,我会尝试调整您给我的代码。
在这里我遇到了一个问题,到目前为止我无法调试。我实现了一个带有文件路径的列表的创建。我遍历该列表,但无法加载该文件。是否有限制,asyncimage 源必须在目录中,main.py 存在?
问候! 斯蒂芬
from kivy.app import App
from kivy.uix.carousel import Carousel
from kivy.uix.image import AsyncImage
from kivy.clock import Clock
from subprocess import call
import subprocess
class CarouselApp(App):
def build(self):
carousel = Carousel(direction='right')
bilderdirliste = []
bilderliste = []
cmd2 = ['find', '/photo/imac-Backup/', '-maxdepth', '2', '-type', 'f', '-name', '*.JPG']
proc2 = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
o2, e2 = proc2.communicate()
print('Output: ' + o2.decode('utf-8'))
print('Error: ' + e2.decode('utf-8'))
print('code: ' + str(proc2.returncode))
o2_zeilen = o2.split('\n')
counter = 0
for zeile2 in o2_zeilen:
bilderliste.append(zeile2.replace('\n','').replace(' ','\ '))
for bildpfad in bilderliste:
if counter < 10:
counter = counter + 1
print(counter)
src = "%s" % bildpfad
print('Bildpfad ist: %s') % src
image = AsyncImage(source = src, keep_ratio=True)
carousel.add_widget(image)
carousel.loop = True
Clock.schedule_interval(carousel.load_next, 3)
print(carousel.index)
return carousel
CarouselApp().run()
控制台输出为:
...
/photo/imac-Backup/4. März 2014/IMG_1704.JPG
/photo/imac-Backup/29. März 2012/IMG_0100.JPG
/photo/imac-Backup/25. September 2014/IMG_3018.JPG
/photo/imac-Backup/25. September 2014/IMG_3017.JPG
/photo/imac-Backup/25. September 2014/IMG_3015.JPG
/photo/imac-Backup/25. September 2014/IMG_3016.JPG
/photo/imac-Backup/25. September 2014/IMG_3019.JPG
/photo/imac-Backup/18. Mai 2015/IMG_3966.JPG
/photo/imac-Backup/18. Mai 2015/IMG_3965.JPG
/photo/imac-Backup/7. Mai 2013/IMG_0843.JPG
/photo/imac-Backup/1. Oktober 2016/IMG_6076.JPG
/photo/imac-Backup/1. Oktober 2016/IMG_6077.JPG
Error:
code: 0
1
Bildpfad ist: /photo/imac-Backup/13.\ Juni\ 2014/IMG_2484.JPG
[INFO ] [Loader ] using a thread pool of 2 workers
2
Bildpfad ist: /photo/imac-Backup/13.\ Juni\ 2014/IMG_2483.JPG
3
Bildpfad ist: /photo/imac-Backup/9.\ August\ 2015/IMG_4254.JPG
4
Bildpfad ist: /photo/imac-Backup/8.\ Dezember\ 2016/IMG_6187.JPG
5
Bildpfad ist: /photo/imac-Backup/3.\ Januar\ 2013/IMG_0643.JPG
0
Unable to connect to X server
[INFO ] [ProbeSysfs ] device match: /dev/input/event1
[INFO ] [MTD ] Read event from </dev/input/event1>
[INFO ] [ProbeSysfs ] device match: /dev/input/event0
[INFO ] [MTD ] Read event from </dev/input/event0>
[INFO ] [ProbeSysfs ] device match: /dev/input/event1
[INFO ] [HIDInput ] Read event from </dev/input/event1>
[INFO ] [ProbeSysfs ] device match: /dev/input/event0
[INFO ] [HIDInput ] Read event from </dev/input/event0>
[INFO ] [Base ] Start application main loop
[INFO ] [MTD ] </dev/input/event1> range position X is 0 - 4095
[INFO ] [MTD ] </dev/input/event0> range position X is 0 - 0
[INFO ] [MTD ] </dev/input/event1> range position Y is 0 - 4095
[INFO ] [HIDMotionEvent] using <USBest Technology SiS HID Touch Controller>
[INFO ] [MTD ] </dev/input/event0> range position Y is 0 - 0
[INFO ] [MTD ] </dev/input/event1> range touch major is 0 - 0
[INFO ] [HIDMotionEvent] <USBest Technology SiS HID Touch Controller> range ABS X position is 0 - 4095
[INFO ] [MTD ] </dev/input/event0> range touch major is 0 - 0
[INFO ] [MTD ] </dev/input/event1> range touch minor is 0 - 0
[INFO ] [MTD ] </dev/input/event0> range touch minor is 0 - 0
[INFO ] [HIDMotionEvent] <USBest Technology SiS HID Touch Controller> range ABS Y position is 0 - 4095
[INFO ] [HIDMotionEvent] using <PC Camera: PC Camera>
[INFO ] [MTD ] </dev/input/event1> range pressure is 0 - 255
[INFO ] [MTD ] </dev/input/event0> range pressure is 0 - 255
[INFO ] [HIDMotionEvent] <USBest Technology SiS HID Touch Controller> range position X is 0 - 4095
[INFO ] [MTD ] </dev/input/event1> axes invertion: X is 0, Y is 0
[INFO ] [MTD ] </dev/input/event0> axes invertion: X is 0, Y is 0
[INFO ] [HIDMotionEvent] <USBest Technology SiS HID Touch Controller> range position Y is 0 - 4095
[INFO ] [MTD ] </dev/input/event1> rotation set to 0
[INFO ] [MTD ] </dev/input/event0> rotation set to 0
显示的是一个黑色屏幕,带有一个运动图标(向左圆圈的点),就像一个进度条。
【讨论】:
找到了上面代码不显示图片的一个重要原因:带有iamges的目录是cifs挂载。将图像复制到树莓派闪存卡会使轮播开始滚动。以上是关于如何:main.py,带有 kivy 轮播代码的新类,kv 文件的主要内容,如果未能解决你的问题,请参考以下文章