我在ScreenManager中有两个屏幕,它们都包含ScrollView中的许多按钮。这个想法是通过单击按钮向前迈出一步(右)。然后向后退(向左)。所以我试图添加一个Carousel来实现第二页上的一次滑动。这就是我的尝试:
self.root = ScreenManager(id = 'screen_manager')
main_screen = Screen(name = 'main_screen')
scroller = Scroller()
button_text = ['teach', 'move', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8']
for text in button_text:
scroller.view.add_widget(Field(name=text, direction='left', current='teach'))
main_screen.add_widget(scroller)
self.root.add_widget(main_screen)
carousel = Carousel(direction='left', id='carousel')
teach = Screen(name = 'teach')
scroller2 = Scroller()
button_text = ['vocab', 'drills']
for text in button_text:
scroller2.view.add_widget(Field(name=text, direction='right', current='main_screen'))
carousel.add_widget(scroller2)
teach.add_widget(carousel)
self.root.add_widget(teach)
但由于我只添加了第二个屏幕,因此无法向任一方向滑动。轮播的load_slide()
方法以幻灯片作为参数。假设通过幻灯片他们意味着旋转木马。鉴于我将有很多页面,我可能需要使用add_widget()
和remove_widget()
动态加载轮播。会不胜感激。
到目前为止我所拥有的代码的工作示例:http://dpaste.com/33464R2
答案 0 :(得分:9)
您可以使用 ScreenManager 和手势来完成此操作。 (../ kivy /示例/手势/)
请参阅此处kivy-github-gestures
我在评论代码中解释了所有内容。
首先,您需要创建一个名为gesture_box.py的新Python文件。
gesture_strings copy from here
from kivy.gesture import GestureDatabase
from kivy.uix.boxlayout import BoxLayout
from kivy.gesture import Gesture
[Paste gesture_strings here]
#This database can compare gestures the user makes to its stored gestures
#and tell us if the user input matches any of them.
gestures = GestureDatabase()
for name, gesture_string in gesture_strings.items():
gesture = gestures.str_to_gesture(gesture_string)
gesture.name = name
gestures.add_gesture(gesture)
class GestureBox(BoxLayout):
def __init__(self, **kwargs):
for name in gesture_strings:
self.register_event_type('on_{}'.format(name))
super(GestureBox, self).__init__(**kwargs)
def on_left_to_right_line(self):
pass
#To recognize a gesture, you’ll need to start recording each individual event in the
#touch_down handler, add the data points for each call to touch_move , and then do the
#gesture calculations when all data points have been received in the touch_up handler.
def on_touch_down(self, touch):
#create an user defined variable and add the touch coordinates
touch.ud['gesture_path'] = [(touch.x, touch.y)]
super(GestureBox, self).on_touch_down(touch)
def on_touch_move(self, touch):
touch.ud['gesture_path'].append((touch.x, touch.y))
super(GestureBox, self).on_touch_move(touch)
def on_touch_up(self, touch):
if 'gesture_path' in touch.ud:
#create a gesture object
gesture = Gesture()
#add the movement coordinates
gesture.add_stroke(touch.ud['gesture_path'])
#normalize so thwu willtolerate size variations
gesture.normalize()
#minscore to be attained for a match to be true
match = gestures.find(gesture, minscore=0.3)
if match:
print("{} happened".format(match[1].name))
self.dispatch('on_{}'.format(match[1].name))
super(GestureBox, self).on_touch_up(touch)
现在创建你的main.py文件。
import gesture_box as gesture
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
class Runner(gesture.GestureBox):
pass
class MainApp(App):
def build(self):
return Runner()
if __name__ == '__main__':
app = MainApp()
app.run()
你的main.kv文件
<Runner>:
#Handling the gesture event.
on_left_to_right_line: manager.current = 'main_screen'; manager.transition.direction = 'right'
ScreenManager:
id: manager
Screen:
name: "main_screen"
BoxLayout:
orientation: 'vertical'
Label:
Button:
text: "Child 1"
on_release:
manager.current = "child1"
manager.transition.direction = 'left'
Label:
Button:
text: "Child 2"
on_release:
manager.current = "child1"
manager.transition.direction = 'left'
Label:
Screen:
name: "child1"
Label:
text: "Swipe from left to right to go to main screen (CHILD 1)"
Screen:
name: "child2"
Label:
text: "Swipe from left to right to go to main screen (CHILD 1)"
编辑:很多人问我这些手势字符串是如何生成的。
Kivy家伙在他们的例子中提供了这个。
点击此处https://github.com/kivy/kivy/blob/master/examples/gestures/gesture_board.py 运行这个文件。
python gesture_board.py
它应该打开一个空白窗口。
使用鼠标或触摸在其上做手势。
当触发on_touch_up事件时,它将在终端输出手势字符串。
例如right_to_left_line的输出将是。此
(&#39;手势表示:&#39 ;,&#39; eNq1WMtSHEcQvM + PiIs36t3dP4CujuADHFhsACEZNmBlW3 / vnOrZxyCWmYPFQQu5OdlVldXVPbp6 / Pr494 / N / FZ1 // 1lO3yePnc0XN3teLj59HT71 / bTsBP8ig8dXm8 + ve5fnr9uX / GnDVffdj5cvStyk7RhF6NUwfO758en / fhYHR9rFx77fWQNO + 4RjCH8wCMsw / VvtCFhZWuspJXZfQzn3 / FrHa5pE6WIca0NH00agv3z9uNFLBfx4f6i / v0krRKspZE7PnyFdKbNZYU0mykjZo3mXlZI15Ruy9Lu4ZWKSiFi9bIoLVl14RXSHI3xHQuLqyxHLZLS + iuk00ZZYaMFmqOYYAEn5hUFSRtlhY0mptZQ6mJsXpeV00Vp / 7 + ypom6wkQ0dEGRpXqgtW250pom6goT1biQRWth0Ddflk4T9cxErkSNpTRG3vVcm4TUpVR2GMoUy + Jpo57ZyFZI1aCOddjbSV0CO9FRkohCpdQVoaeV2n6NuqWddmYntWIW4UwmCvtO4oLODlPn0qyYy7J4GmpnhhKer7W0VkngXZSjOjdz9EtwiBf3FZ1o6amdeYrKQJdEGmae1ob9dZQPTEGBtw0UjMIV8umqTa6mehXEJVVauHLBpDyqq1NDsZpiZUeSy + rpqrWTulqphuHfEGr4eL4cxJmbSyiaEt5ili + Ke5rqfBLHucKKbega3BqdxOlNx7Rl8TTV9SQeCFwCa3hg59ip6KRNMGSDYLhSkxWRp6fua8Q5qFoNDC / sVCq8LJ6OelkU76MHuhHaGrQxJJa73dNSb6vkrWrBNrJWYSm226J6pKdx8pSxU4nMEaIX8jPtWsmKRuAfzMm2bGmkpXGyFIeXoZmrEKaukcpJnXGhaAptw4hwXZ4wkZaGrxJHw1QMN6 / NcBtaUZW0NMoqcVyCzDB9WA0jhpYdjXQ02nLNhfAnYEyBEAzmRemS dhZe0yzYobhnRcMSaEpaHi4l / Sy6uP9HcVw + MXQKegYt4ysiTz + LL8 / FUb1h7uJ72KoYYHkHGC / 5X16226fjlb3EeGcvZbi6xiStGxqug6E87HelDreJ2gxtHTU5Ryt1VGYKlTtKM4UqiSLoGaodtbmCdZTnXE + UY64bHaWYoSVR8rlC5oazcAZmam3ObJkZfNu085 + RYJ2QSWKM96dqBzPHSl1fJmamiNteBydmZoiZkaBOzEywUI9EwTz74ZGQucYkZVOomWpYlzJ + EzEImXUP / H1CVsDrpNCDwc5LdOqOI5p54x4 / RzNx5zdoZo53tzmaqeNSMEczd3OfR2fDlNlIyeztsHSd0EzfpqWdfioaU + ZvRJcZWQCtlzU4i6HlsgZnYXRqiHcZ0hkfaGTB1D5gZPFUP2BkIVXmVeKsnR564IBm7XTaOkc06yXTLjmiWSOpc1SoozRHsxYyVevgn2T + uDHP0cxZfN4kknmKzVtSvKPz1pHMTdTmaOnom3Yv55SeqLQPKD1rKe9Qft5ImHmd7ivpvU7joDj / 0Uv0XkChlfReWa4r6b3kl8cEzoTOoMuMbsW01aYBxdqH8WEOHNB + 0Eyt8860w90kGSUuMqwfQNOJMI1RvF8m6jFH + wE0bb8j2g + g6fw5oqhFPzgfto / 3D / VX / 6Tw3nNtbzYctiM4 / zze7R + SEsN4ao0rAN4 / f9u + 3D592eZXJd8sRnw65f / YvTzfff / StetwrRu8huCVAFT0PS484 + V98x / WYONd&#39;) (&#39; cross:&#39;, - 1.2199187170964643) (&#39;检查:&#39;, - 2.052277818300959) (&#39;圈:&#39;,0.4973932910874005) (&#39; square:&#39;,0.2907537534396739)
那就是它,你有你的字符串:D
答案 1 :(得分:1)
正如您在评论中提到的那样。
我有很多页面。每个页面都有一堆按钮。一些 页面上的按钮比屏幕上的按钮多,所以它们需要 滚动的。
现在,Scrollable部分,你已经想通了。(你也可以在kivy文件中做到),See here。您可以在下面的代码中轻松添加它。
点击按钮可以带您到下一个孩子 屏幕(具有滚动效果)。任何孩子都应该可以 通过向后滑回到它的父母那里。
此处(下面的代码)您可以滑动或点击按钮进行导航。
现在,
鉴于我将有很多页面,我可能需要Carousel 使用add_widget()和remove_widget()动态加载。
这些例子对您有所帮助。 Kivy-Showcase和Container
在kivy-showcase中查看load_screen
方法以及build
函数
以下是点击按钮时add_widgets
的示例
Builder.load_string('''
[SideBar@BoxLayout]:
content: content
orientation: 'vertical'
size_hint: .2,1
BoxLayout:
orientation: 'vertical'
# just add a id that can be accessed later on
id: content
<Root>:
Button:
center_x: root.center_x
text: 'press to add_widgets'
size_hint: .2, .2
on_press:
sb.content.clear_widgets()
root.load_content(sb.content)
SideBar:
id: sb
''')
class Root(BoxLayout):
def load_content(self, content):
for but in range(20):
content.add_widget(Button(text=str(but)))
class MyApp(App):
def build(self):
return Root()
if __name__ == '__main__':
MyApp().run()
以下是屏幕示例。
这是main.py文件
from kivy.app import App
from kivy.uix.screenmanager import Screen
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
class ShowTime(BoxLayout):
carousel = ObjectProperty(None)
class Screen1(Screen):
pass
class Screen2(Screen):
pass
class MainApp(App):
def build(self):
return ShowTime()
if __name__ == '__main__':
MainApp().run()
这是main.kv文件
<Screen1>:
name: "screen1"
BoxLayout:
orientation: 'vertical'
padding: 50
spacing: 50
Button:
text: "Next (2)"
on_release: self.parent.parent.parent.parent.parent.ids.carousel.load_next()
Button:
text: "Go back (2)"
on_release: self.parent.parent.parent.parent.parent.ids.carousel.load_previous()
<Screen2>:
name: "screen2"
BoxLayout:
orientation: 'vertical'
padding: 100
spacing: 100
Button:
text: "go back (3)"
on_release: self.parent.parent.parent.parent.parent.ids.carousel.load_previous()
<Showtime>:
carousel: carousel
Carousel:
id: carousel
loop: True
BoxLayout:
padding: 100
spacing: 100
Button:
text: 'Tap me or Swipe (1)'
on_release: carousel.load_next()
Screen1:
Screen2:
编辑1:
问:如何使用load_slide()
方法?
load_slide()方法将幻灯片作为参数def load_slide(self, slide):
slide
是列表属性slides = ListProperty([])
,
在按钮包含文字"go back (3)"
on_release: print( self.parent.parent.parent.parent.parent.ids.carousel.slides)
您将获得id(carousel)下所有幻灯片的列表。
这就是你如何使用它。
.....ids.carousel.load_slide(....ids.carousel..slides[2])
答案 2 :(得分:0)
我有另一种可以使用的方法。它不是通过Carousel,而是允许您通过滑动来更改屏幕。您可以创建一个方法,该方法将屏幕的初始接触点的x点和屏幕的最终接触点的x点相减。这是视频的链接(https://www.youtube.com/watch?v=8pqtMAUEUyo&t=65s)
def on_touch_move(self, touch):
if touch.ox - touch.x > 50: # check for swiping gestures
# ScreenManger change screen
touch.ox
是屏幕(x轴)的初始接触点,touch.x
是最终的接触点。如果差异大于设定值,则会更改屏幕。