在屏幕大小更改之前,小部件不会显示

时间:2014-02-06 12:00:51

标签: python widget kivy

我想制作游戏,我选择Kivy作为我的GUI,因为我已经用Python编写了我的后端。我目前正在使用runTouchApp(appwindow)来运行应用程序,其中appwindowFloatLayout()对象。我更新屏幕的方式是运行appwindow.clear_widgets()then appwindow.add_widget(new_screen),其中new_screen是包含所有其他小部件的布局对象。

直到现在它工作正常,但由于某种原因我无法理解我添加的小部件正确加载(根据在后台运行的cmd)但在我更改屏幕大小之前不会显示。

以下是示例代码:

import kivy
kivy.require('1.1.1')
from kivy.base import runTouchApp
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image


appwindow = FloatLayout()
class MenuScreen():
    def build(self):
        bg = Image(source = 'Images/bg/bg.jpg',allow_stretch= True,keep_ratio= False)
        box = BoxLayout(orientation = 'vertical')
        menu_items = []
        for i in range (0,4):
            button = Button(text = 'Menu item no:'+str(i))
            button.bind(state = checkMenuPress)
            menu_items.append(button)
        for button in menu_items:
            box.add_widget(button)
        floater = FloatLayout(size = bg.size)
        floater.add_widget(bg)
        floater.add_widget(box)
        floater.size_hint = 1,1
        return floater
class SecondScreen():
    def build(self):
        bg = Image(source = 'Images/bg/bg.jpg',allow_stretch= True,keep_ratio= False)
        box = BoxLayout(orientation = 'vertical')
        box.add_widget(bg)
        return box
def checkMenuPress(button,*args):
    if button.state == 'normal':
        sc = SecondScreen().build()
        appwindow.clear_widgets()
        appwindow.add_widget(sc)
if __name__ == '__main__':
    menuscreen = MenuScreen().build()
    appwindow.add_widget(menuscreen)
    runTouchApp(appwindow)

3 个答案:

答案 0 :(得分:0)

好的,这里有一些问题。要创建一个应用程序,你应该继承kivy.app.App并让它的构建方法返回“root”小部件。只有这个类需要构建方法:任何其他方法都是多余的。

一旦有了一个根小部件,只需插入和删除小部件即可。这就是我接近它的方式。

import kivy
kivy.require('1.1.1')
from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.app import App


class MenuScreen(App):
    floater = None

    def build(self):
        bg = Image(source='Images/bg/bg.jpg',
                   allow_stretch= True,
                   keep_ratio= False)
        box = BoxLayout(orientation='vertical')
        menu_items = []
        for i in range(0, 4):
            button = Button(text='Menu item no:'+str(i))
            button.bind(state=self.checkMenuPress)
            menu_items.append(button)
        for button in menu_items:
            box.add_widget(button)
        self.floater = FloatLayout(size=bg.size)
        self.floater.add_widget(bg)
        self.floater.add_widget(box)
        self.floater.size_hint = 1, 1
        return self.floater

    def checkMenuPress(self, button,*args):
        if button.state == 'normal':
            self.floater.clear_widgets()
            self.floater.add_widget(SecondScreen())


class SecondScreen(FloatLayout):
    def __init__(self, **kwargs):
        super(SecondScreen, self).__init__(**kwargs)
        self.add_widget(Image(source='Images/bg/bg.jpg',
                              allow_stretch=True,
                              keep_ratio=False))

if __name__ == '__main__':
    MenuScreen().run()

答案 1 :(得分:0)

好的,所以这里是使用Screens快速返工的例子。如果不知道你想要做什么就很难,所以如果这没有帮助,试着写下你正在寻找的行为的摘要。

from kivy.uix.button import Button
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.image import Image
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen


class MenuScreen(Screen):
    """
    The Screen containing the menu
    """
    def __init__(self, sm, **kwargs):
        super(MenuScreen, self).__init__(**kwargs)
        self.sm = sm  # Store a reference to the screen manager

        bg = Image(source='Images/bg/bg.jpg',
                   allow_stretch= True,
                   keep_ratio= False)
        box = BoxLayout(orientation='vertical')
        menu_items = []
        for i in range(0, 4):
            button = Button(text='Menu item no:'+str(i))
            button.bind(state=self.check_menu_press)
            menu_items.append(button)
        for button in menu_items:
            box.add_widget(button)
        floater = FloatLayout(size=bg.size)
        floater.add_widget(bg)
        floater.add_widget(box)
        floater.size_hint = 1, 1
        self.add_widget(floater)

    def check_menu_press(self, button, *args):
        if button.state == 'normal':
            self.sm.current = "second"


class SecondScreen(Screen):
    def __init__(self, sm, **kwargs):
        super(SecondScreen, self).__init__(**kwargs)
        self.add_widget(Image(source='Images/bg/bg.jpg',
                              allow_stretch=True,
                              keep_ratio=False))
        self.sm = sm  # Store a reference to the screen manager

    def on_touch_down(self, touch):
        self.sm.current = "menu"


class MainApp(App):
    def build(self):
        sm = ScreenManager()
        sm.add_widget(MenuScreen(sm, name="menu"))
        sm.add_widget(SecondScreen(sm, name="second"))
        return sm

if __name__ == '__main__':
    MainApp().run()

答案 2 :(得分:0)

看起来我找到了崩溃问题的根源。我曾使用多线程进行服务器客户端交互。我一直在使用两个额外的线程,一个用于服务器,另一个用于客户端。如果我尝试将客户端线程与GUI集成,则会引发另一个问题。即使socket.recv()在ScreenManager.current =" newscreen"之后一下,应用程序的屏幕不会改变。它冻结了我离开它的方式。它只有在从服务器收到消息后才会恢复。