簡體   English   中英

Kivy、Python - 使用 ScreenManager 時應用程序中的功能不起作用

[英]Kivy, Python - Functions in app not working when using ScreenManager

一旦我使用 ScreenManager,我的應用程序就不會 function。

我遇到了秒表 function 的問題, 這里已解決 簡而言之,秒表需要在暫停按鈕打開彈出菜單時暫停,並在菜單關閉時恢復。

使用 ScreenManager 時又出現問題,所以我可能沒有正確使用 ScreenManager,或者缺少一些關於 Kivy 或 Python 的基本知識來做我想做的事情。

Python代碼:

import kivy
from kivy.app import App
from kivy.lang import Builder
from kivy.properties import NumericProperty
from kivy.uix.popup import Popup
from kivy.clock import Clock

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.screenmanager import ScreenManager, Screen

root_widget = Builder.load_file('app.kv')


class ExampleWidget(Screen):
    time = NumericProperty(0)
    paused = False
    stop = False

    # Keeping time
    def increment_time(self, interval):

        self.time += .1
        print(self.time)  # To check if stopwatch is running or not

    # Stop should mean that the stopwatch must reset when it starts again.
    # When paused it should resume when it starts again

    def start(self):
        # Keeping time
        self.time = 0
        Clock.schedule_interval(self.increment_time, .1)

    def stop(self):
        Clock.unschedule(self.increment_time)
        print('Stopped')

    def pause(self):

        # Pause stopwatch
        if self.paused:
            Clock.unschedule(self.increment_time)
            print("!!", self.time)  # To make it easier to see if stopwatch actually resumes where it left off
            print('unscheduled')  # Just to confirm and to make it a bit easier to see

        # resume stopwatch
        elif not self.paused:
            Clock.schedule_interval(self.increment_time, .1)


class PopupMenu(Popup):
    example = ExampleWidget()


class Menu(Screen, BoxLayout):
    pass


class WindowManager(ScreenManager):
    pass


class MyApp(App):
    ExampleWidget = ExampleWidget()
    WindowManager = WindowManager()

    def build(self):
        return self.WindowManager


MyApp().run()

.kv 文件:

#:import Factory kivy.factory.Factory
#: import WipeTransition kivy.uix.screenmanager.WipeTransition
<WindowManager>:
    transition: WipeTransition()
    canvas.before:
        Color:
            rgba: 0, 0, 0, 1
        Rectangle:
            pos: self.pos
            size: self.size
    Menu:
    ExampleWidget:

<PopupMenu@Popup>
    auto_dismiss: False
    size_hint_y: .8
    size_hint_x: .9
    title: 'Pause'
    example: app.ExampleWidget

    BoxLayout:
        Button:
            text: 'resume'
            on_press: root.example.paused = False
            on_release: root.dismiss(); root.example.pause()
            size: self.size



<Menu>:
    id: menu
    name: "first"
    orientation: 'vertical'
    size: root.width, root.height
    secondary_color: .4,.4,.4,1
    secondary_color2: 0,.7,.7,1
    canvas.before:
        Color:
            rgba: 1, 1, 1, 1
        Rectangle:
            pos: self.pos
            size: self.size
    Button:
        id: start_button
        text: "Start"
        font_size: 32
        on_release: app.root.current = "second"
        size: root.width/2, root.height/12
        size_hint: None, None
        pos: root.width/4, root.height/2.5
        background_color: 0, 0, 0, 0
        canvas.before:
            Color:
                rgba: menu.secondary_color if start_button.state=='normal' else menu.secondary_color2
            RoundedRectangle:
                size: start_button.width, start_button.height
                pos: start_button.pos

<ExampleWidget>:
    name: 'second'
    GridLayout:
        col: 2
        rows: 3
        size: root.size
        Button:
            text: 'start'
            size: self.size
            on_press: root.start()
        Button:
            text: 'stop'
            size: self.size
            on_press: root.stop()
        Button:
            text: 'Pause menu'
            size: self.size
            on_press: root.paused = True
            on_release: Factory.PopupMenu().open(); root.pause()
        Label:
            text: str(round(root.time))
            size: self.size


提前感謝您的幫助或想法。

它不起作用的原因是因為您在彈出窗口(您在應用程序中創建的那個)中使用了 ExampleWidget 的新實例。 但是您應該訪問的是您在 ScreenManager 中添加的那個。 要訪問它,您可以執行類似的操作。

<WindowManager>:
    example: example
    ExampleWidget:
        id: example

# and in popup
    example: app.root.example

問題是您引用了不屬於您的 GUI 的ExampleWidget 編碼:

class PopupMenu(Popup):
    example = ExampleWidget()

正在創建對ExampleWidget的新實例的引用,該實例不在您的 GUI 中。 這可以替換為:

class PopupMenu(Popup):
    pass

然后,在您的kv中,如果您為實際在您的 GUI 中的ExampleWidget實例添加一個id

<WindowManager>:
    transition: WipeTransition()
    canvas.before:
        Color:
            rgba: 0, 0, 0, 1
        Rectangle:
            pos: self.pos
            size: self.size
    Menu:
    ExampleWidget:
        id: example  # added to enable accessing this instance of ExampleWidget

現在您的MyApp class 可以是:

class MyApp(App):
    WindowManager = WindowManager()

    def build(self):
        self.ExampleWidget = self.WindowManager.ids.example
        return self.WindowManager

現在app.ExampleWidget將引用您的 GUI 中的ExampleWidget實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM