2015-06-19 73 views
10

我在ScreenManager中有兩個屏幕,兩個屏幕都包含ScrollView中的多個按鈕。這個想法是通過點擊一個按鈕向前(右)。然後往後退(左)。所以我試圖添加一個Carousel來實現第二頁上的那個滑動。這是我所嘗試過的:Kivy:滑動(旋轉木馬和屏幕管理器)

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()方法以幻燈片作爲參數。假設他們是幻燈片,意味着一個旋轉木馬。鑑於我將有很多頁面,我可能需要動態加載Carousel,使用add_widget()remove_widget()。會欣賞一些指針。代碼

工作的例子,我到目前爲止有:http://dpaste.com/33464R2

+0

我去了源代碼,看到這個屬性'min_move'爲**旋轉木馬**如果將此設置爲'min_move = 1',則在滑動時不會更改該屏幕。也許這可以爲你工作。這裏是:https://github.com/kivy/kivy/blob/master/kivy/uix/carousel.py – kiok46

+0

謝謝,我可以使用它。無法讓Carousel添加多個屏幕。 –

+0

發現本教程,可能會有所幫助,並給你一些其他的想法:) http://davideddu.org/blog/posts/kivy-back-btn-navigation/ – kiok46

回答

9

您可以通過使用的ScreenManager手勢做到這一點。 (../kivy/examples/gestures/)

看到這裏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的輸出是。此

( '手勢表示:',「eNq1WMtSHEcQvM + PiIs36t3dP4CujuADHFhsACEZNmBlW3/vnOrZxyCWmYPFQQu5OdlVldXVPbp6/Pr494/N/FZ1 // 1lO3yePnc0XN3teLj59HT71/bTsBP8ig8dXm8 + ve5fnr9uX/GnDVffdj5cvStyk7RhF6NUwfO758en/fhYHR9rFx77fWQNO + 4RjCH8wCMsw/VvtCFhZWuspJXZfQzn3/FrHa5pE6WIca0NH00agv3z9uNFLBfx4f6i/v0krRKspZE7PnyFdKbNZYU0mykjZo3mXlZI15Ruy9Lu4ZWKSiFi9bIoLVl14RXSHI3xHQuLqyxHLZLS + iuk00ZZYaMFmqOYYAEn5hUFSRtlhY0mptZQ6mJsXpeV00Vp/7 + ypom6wkQ0dEGRpXqgtW250pom6goT1biQRWth0Ddflk4T9cxErkSNpTRG3vVcm4TUpVR2GMoUy + Jpo57ZyFZI1aCOddjbSV0CO9FRkohCpdQVoaeV2n6NuqWddmYntWIW4UwmCvtO4oLODlPn0qyYy7J4GmpnhhKer7W0VkngXZSjOjdz9EtwiBf3FZ1o6amdeYrKQJdEGmae1ob9dZQPTEGBtw0UjMIV8umqTa6mehXEJVVauHLBpDyqq1NDsZpiZUeSy + rpqrWTulqphuHfEGr4eL4cxJmbSyiaEt5ili + Ke5rqfBLHucKKbega3BqdxOlNx7Rl8TTV9SQeCFwCa3hg59ip6KRNMGSDYLhSkxWRp6fua8Q5qFoNDC/sVCq8LJ6OelkU76MHuhHaGrQxJJa73dNSb6vkrWrBNrJWYSm226J6pKdx8pSxU4nMEaIX8jPtWsmKRuAf zMm2bGmkpXGyFIeXoZmrEKaukcpJnXGhaAptw4hwXZ4wkZaGrxJHw1QMN6/NcBtaUZW0NMoqcVyCzDB9WA0jhpYdjXQ02nLNhfAnYEyBEAzmRemSdhZe0yzYobhnRcMSaEpaHi4l/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') ('cross:',-1.2199187170964643) ('check:',-2.0522778 18300959) ( '圈子:',0.4973932910874005) ( '方:',0.2907537534396739)

就是這樣,你有你的字符串:d

+0

你只是不放棄你;)我喜歡它。在週末看看這個。謝謝。 –

+0

解決新的挑戰,讓我快速學習!也謝謝你!我從來沒有用過手勢:) – kiok46

+0

太棒了。有用。我改變了你的答案。將'miniscore'設置爲0.3以使其更易於滑動。並指定主按鈕上的過渡方向。仍然代碼只支持回到主,當子頁面應該帶你回到父頁面,而不是主要的。但無論如何要獎賞你的賞金。如果你知道如何去做,請告訴我。 –

1

當您在您的評論問。

我有一堆的網頁。每個頁面都會有一堆按鈕。有些 網頁有且可在屏幕上更多的按鈕,所以他們需要 滾動。

現在,可以滾動的部分,你已經知道了(你也可以在kivy文件中做),See here。你可以輕鬆地添加,在下面的代碼。

點擊一個按鈕,應該帶你到下一個孩子 屏(帶滾動效果)。任何一個孩子應該可以到 回到它的父通過刷回來。

這裏(下面的代碼)你既可以刷卡或點擊按鈕進行瀏覽。

現在,

鑑於我將有很多的網頁,我可能需要的輪播 動態加載,使用add_widget()和remove_widget()。

這些例子可以幫助你。 Kivy-ShowcaseContainer

在kivy-展櫃看看load_screen方法,也是build功能

下面是一個例子來add_widgets上的按鈕

Builder.load_string(''' 
[[email protected]]: 
    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() 

這是主要的。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:

Q-如何使用load_slide()方法?

load_slide()方法以幻燈片作爲參數def load_slide(self, slide):

Q-所以現在如何讓幻燈片?

slide是一個列表屬性slides = ListProperty([])

打印此哪裏按鈕具有文本"go back (3)"

on_release: print(self.parent.parent.parent.parent.parent.ids.carousel.slides) 你會得到下ID(旋轉木馬)所有幻燈片的列表。

這是你如何使用它。 .....ids.carousel.load_slide(....ids.carousel..slides[2])

+0

謝謝你。但我已經設法做類似的事情。但問題是,它不應該可以從主屏幕上滑動。在兒童頁面上,只能輕掃一次。 可能與旋轉木馬不可能。也許人們必須創建自己的手勢。不知道爲什麼ScreenManager不支持這一點。 –

+0

如果是這樣的話,也許你必須用_start_animation,on_touch_move,使用screenmanager等方法制作自己的小部件:) – kiok46

+0

是的,也在考慮這個。正在尋找Carousel源代碼。但我懷疑我可以把它關閉。 –