【问题标题】:Python Kivy: bind a command inside popup executes commandPython Kivy:在弹出窗口中绑定命令执行命令
【发布时间】:2018-07-27 14:58:11
【问题描述】:

我想要一个弹出窗口来确认用户确实想要退出应用程序。现在,当我尝试将命令绑定到两个按钮时,我可以直接在函数内添加关闭,而不是通过回调。那可能没问题。 但我只能通过回调调用我的关闭例程,而不是在函数内部。当我在此函数中绑定 quit_app() 时,它会在打开弹出窗口时直接执行。为什么?它只是应该绑定,而不是执行。

(Old script deleted.)

我稍微更新了我的脚本并包含了一个最小的 kv 文件。它基本上可以工作(和以前一样),但看起来有点奇怪。

UI-Test.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
# Kivy imports:
import kivy
from kivy.app import App
from kivy.uix import popup
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.uix.tabbedpanel import TabbedPanel


VersionString = "DRAFT"
AppName = 'UI-Test'

def CloseProgram(Message, Level):
     print('Closing, level {} ({})'.format(Level, Message))
     sys.exit()

def OnClosing(self):
    print('Closing...')
    # ToDo: call popup


def init():
    print('Starting {} Version {}.'.format(AppName, VersionString))
    print('You are using Python version: {}'.format(sys.version))


class TestApp(App):
    title = AppName + ' ' + VersionString

    def on_pause(self):
        return True

    def quit_app(self,btn):
        CloseProgram('Normal Closing', 'Debug')


    class Pop(BoxLayout):

        def __init__(self, **kwargs):
            super(Pop, self).__init__(**kwargs)
            self.up()

        def callback(instance):
            if instance.id == 'quit':
                TestApp.quit_app(TestApp, 1)

        def up(self):
            print('popup')
            qbutton = Button(text='Quit', id='quit')
            abutton = Button(text='Return to Program', id='return')
            blayout = BoxLayout()
            blayout.add_widget(qbutton)
            blayout.add_widget(abutton)
            self.popup = kivy.uix.popup.Popup(title='Quit Program?', content=blayout, size_hint=(None, None), size=(400, 400))
            abutton.bind(on_release=self.popup.dismiss)
            qbutton.bind(on_release=TestApp.Pop.callback)
            self.popup.open()


if __name__ == '__main__':
    init()
    TestApp().run()

Test.kv:

#:kivy 1.9

<Button>:
    font_size: 15

# Main Layout:
BoxLayout:
    orientation: 'vertical'

    Button:
        text: "Quit"
        id: "quit_button"
        size_hint: (0.1, None)
        size: (150, 50)
        on_release: app.Pop.up(self)

【问题讨论】:

  • 你正在调用它...而不是使用 lambda on_release= lambda evt:aempApp.quit_app(aempApp, 1) ...
  • 抱歉,我不认识 Kivy,但您的 callback 方法似乎缺少其 self 参数。顺便说一句,Python 中的类名通常以大写字母开头。您没有必须这样做,但不这样做会使其他读者感到困惑。

标签: python popup kivy


【解决方案1】:

问题

如何从 kv 文件中调用此弹出窗口?在我的版本中时(请参阅 更新的脚本) Pop 不是 TestApp 的一部分我无法从 kv 访问它 文件

解决方案 - 使用 kv 文件

kv 文件

  1. 添加导入语句,#:import Factory kivy.factory.Factory
  2. 定义类规则,&lt;Pop&gt;: 并添加小部件。
  3. 使用Factory.Pop().open()注册、实例化和打开class Pop()

Factory object

工厂可用于自动注册任何类或模块 并在项目中的任何地方实例化它的类。

Python 代码

  1. 使用App.get_running_app() 获取class TestApp() 的实例

示例 - 带有 kv 文件

main.py

​​>
#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys

# Kivy imports:
import kivy
kivy.require('1.11.0')

from kivy.app import App
from kivy.uix.popup import Popup


VersionString = "DRAFT"
AppName = 'UI-Test'


def CloseProgram(Message, Level):
     print('Closing, level {} ({})'.format(Level, Message))
     sys.exit()


def OnClosing(self):
    print('Closing...')
    # ToDo: call popup


def init():
    print('Starting {} Version {}.'.format(AppName, VersionString))
    print('You are using Python version: {}'.format(sys.version))


class Pop(Popup):

    def callback(self, instance):
        App.get_running_app().quit_app(instance)


class TestApp(App):
    title = AppName + ' ' + VersionString

    def on_pause(self):
        return True

    def quit_app(self, btn):
        CloseProgram('Normal Closing', 'Debug')


if __name__ == '__main__':
    init()
    TestApp().run()

test.kv

#:kivy 1.11.0
#:import Factory kivy.factory.Factory

<Pop>:
    title: 'Quit Program?'
    size_hint: None, None
    size: 400, 400

    BoxLayout:
        Button:
            text: 'Quit'
            on_release:
                root.dismiss()
                root.callback(self)
        Button:
            text: 'Return to Program'
            on_release: root.dismiss()


<Button>:
    font_size: 15

# Main Layout:
BoxLayout:
    orientation: 'vertical'

    Button:
        text: "Quit"
        id: "quit_button"
        size_hint: (0.1, None)
        size: (150, 50)
        on_release: Factory.Pop().open()

输出 - 带有 kv 文件

解决方案 - 没有 kv 文件

  1. 调用Popup.open()之前绑定所有按钮
  2. 使用 App.get_running_app() 获取 aempAPP 类的实例

片段

    def callback(self, instance):
        print("\ncallback:")
        self.popup.dismiss()
        App.get_running_app().quit_app(1)

    def up(self):
        ...
        self.popup = Popup(title='Quit Program?', content=blayout, size_hint=(None, None), size=(400, 400))
        abutton.bind(on_release=self.popup.dismiss)
        qbutton.bind(on_release=self.callback)
        self.popup.open()

...
class aempApp(App):
    ...
    def quit_app(self, value):
        print(value)

示例 - 没有 kv 文件

main.py

​​>
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.button import Button


class Pop(BoxLayout):

    def __init__(self, **kwargs):
        super(Pop, self).__init__(**kwargs)
        self.up()

    def callback(self, instance):
        print("\ncallback:")
        self.popup.dismiss()
        App.get_running_app().quit_app(1)

    def up(self):
        print('popup')
        qbutton = Button(text='Quit', id='quit')
        abutton = Button(text='Return to Program', id='return')
        blayout = BoxLayout()
        blayout.add_widget(qbutton)
        blayout.add_widget(abutton)
        self.popup = Popup(title='Quit Program?', content=blayout, size_hint=(None, None), size=(400, 400))
        abutton.bind(on_release=self.popup.dismiss)
        qbutton.bind(on_release=self.callback)
        self.popup.open()


class TestApp(App):

    def build(self):
        return Pop()

    def quit_app(self, value):
        print("value=", value)


if __name__ == "__main__":
    TestApp().run()

输出 - 没有 kv 文件

【讨论】:

  • 如何从 kv 文件中调用此弹出窗口?在我的版本中(请参阅更新的脚本) Pop 不是 TestApp 的一部分,我无法从 kv 文件访问它。
  • 在 kv 文件中,使用 Factory.Pop().open() 注册、实例化并打开 `class Pop()`。请参考我更新的帖子。
  • 谢谢!效果很好。我用的是kv版本。现在代码看起来好多了。而且我明白了一点。
猜你喜欢
  • 1970-01-01
  • 2015-06-09
  • 2013-01-11
  • 1970-01-01
  • 1970-01-01
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
相关资源
最近更新 更多