如何在 Kivy Python 中为 GridLayout 的某些按钮设置高度?

Posted

技术标签:

【中文标题】如何在 Kivy Python 中为 GridLayout 的某些按钮设置高度?【英文标题】:How to set a height to some buttons of GridLayout in Kivy Python? 【发布时间】:2016-09-30 00:53:51 【问题描述】:

我正在使用 kivy 开发一个应用程序,但我遇到了一个涉及 GridLayout 的问题。我有一个不同行的屏幕,我希望最后一行的按钮始终具有相同的height(屏幕高度的 11.1%)。我试图修改按钮中的属性高度,但不能正常工作。使用size_hint_y 可以正常工作,但事实是我想使用height,因为屏幕不会总是有相同的行数(是响应式的,它取决于先前屏幕的选择)。我在这里附上我通过命令Window.height/9计算的属性高度所做的代码:

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window


class LoginScreen(GridLayout):
    def __init__(self,**kwargs):
        super(LoginScreen, self).__init__(**kwargs)
        self.cols=2
        self.add_widget(Label(text='Subject'))
        self.add_widget(Label(text=''))
        self.add_widget(Label(text='1'))
        self.add_widget(TextInput(multiline=False))
        self.add_widget(Label(text='2'))
        self.add_widget(TextInput(multiline=False))
        self.add_widget(Label(text='3'))
        self.add_widget(TextInput(multiline=False))
        self.add_widget(Label(text='4'))
        self.add_widget(TextInput(multiline=False))
        b1=Button(text='Exit',background_color=[0,1,0,1],height=int(Window.height)/9.0) #doesn't work properly 
        self.add_widget(b1)
        b2=Button(text='Run',background_color=[0,1,0,1],height=int(Window.height)/9.0) #doesn't work properly
        self.add_widget(b2)
        b1.bind(on_press=exit) 




class SimpleKivy(App):
    def build(self):
        return LoginScreen()


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

我知道这可以用 kivy 语言以更简单的方式完成,但对于我的应用来说,最好以这种方式完成。如果有人知道如何解决这个问题,我将不胜感激。

【问题讨论】:

【参考方案1】:

如果您希望网格/框布局中的小部件具有固定大小,则应首先将其 size_hint 设置为 None。并且始终在此类任务中使用 kivy lang - 没有例外。

from kivy.app import App
from kivy.uix.screenmanager import Screen

from kivy.lang import Builder

gui = '''
LoginScreen:

    GridLayout:
        cols: 2

        Label:
            text: 'Subject'

        Label:

        Label:
            text: '1'

        SingleLineTextInput:

        Label:
            text: '2'

        SingleLineTextInput:

        Label:
            text: '3'

        SingleLineTextInput:

        Label:
            text: '4'

        SingleLineTextInput:

        GreenButton:
            text: 'Exit'
            on_press: app.stop()

        GreenButton:
            text: 'Run'


<SingleLineTextInput@TextInput>:
    multiline: False


<GreenButton@Button>:
    background_color: 0, 1, 0, 1
    size_hint_y: None
    height: self.parent.height * 0.111
'''


class LoginScreen(Screen):
    pass


class SimpleKivy(App):

    def build(self):
        return Builder.load_string(gui)


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

【讨论】:

事实上我是在用 python 语言而不是 kivy 语言做的,因为它更适合我开发应用程序。 gridlayout 屏幕是使用先前屏幕的先前选择构建的,它们保存在一个列表中,该列表被迭代以创建最终屏幕。我想使用 kivy 语言,但我不知道如何阅读例如 7 个元素的列表并在 kivy 语言中创建 7 行,每行带有标签和文本输入。最后我决定用 Python 语言来做。您的回答对我帮助很大,我从来没有想过将size_hint 设置为None 是解决方案。【参考方案2】:

试试这个

class LoginScreen(GridLayout):
def __init__(self,**kwargs):
    super(LoginScreen, self).__init__(**kwargs)
    self.cols=2
    self.add_widget(Label(text='Subject'))
    self.add_widget(Label(text=''))
    self.add_widget(Label(text='1'))
    self.add_widget(TextInput(multiline=False))
    self.add_widget(Label(text='2'))
    self.add_widget(TextInput(multiline=False))
    self.add_widget(Label(text='3'))
    self.add_widget(TextInput(multiline=False))
    self.add_widget(Label(text='4'))
    self.add_widget(TextInput(multiline=False))
    b1=Button(text='Exit',background_color=[0,1,0,1],size_hint_y=None, height=int(Window.height)/8.9)  
    self.add_widget(b1)
    b2=Button(text='Run',background_color=[0,1,0,1],size_hint_y=None, height=int(Window.height)/8.9)
    self.add_widget(b2)
    b1.bind(on_press=exit) 

修改为将其更改为 11%。

这里的按钮保持在 11% 以响应窗口大小,您可以在调整窗口大小时重绘网格层(例如通过绑定到“on_resize”)。

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.floatlayout import FloatLayout


class LoginScreen(GridLayout):


def __init__(self,**kwargs):
    super(LoginScreen, self).__init__(**kwargs)

    #init and add grid layer
    self.cols=2
    self.layout = GridLayout(cols=self.cols)
    self.add_widget(self.layout)
    #function to set the buttons based on the current window size
    self.set_content(Window.width, Window.height)
    #bind above function to get called whenever the window resizes
    Window.bind(on_resize=self.set_content)


def set_content(self, width, height, *args):
    #first remove the old sized grid layer
    self.remove_widget(self.layout)
    #now build a new grid layer with the current size
    self.layout =GridLayout(cols=self.cols)
    self.layout.add_widget(Label(text='Subject'))
    self.layout.add_widget(Label(text=''))
    self.layout.add_widget(Label(text='1'))
    self.layout.add_widget(TextInput(multiline=False))
    self.layout.add_widget(Label(text='2'))
    self.layout.add_widget(TextInput(multiline=False))
    self.layout.add_widget(Label(text='3'))
    self.layout.add_widget(TextInput(multiline=False))
    self.layout.add_widget(Label(text='4'))
    self.layout.add_widget(TextInput(multiline=False))
    b1=Button(text='Exit',background_color=[0,1,0,1],size_hint_y=None, height=int(Window.height)/8.9)  
    self.layout.add_widget(b1)
    b2=Button(text='Run',background_color=[0,1,0,1],size_hint_y=None, height=int(Window.height)/8.9)
    self.layout.add_widget(b2)
    b1.bind(on_press=exit) 
    #add the newly sized layer
    self.add_widget(self.layout)


class SimpleKivy(App):
def build(self):
    return LoginScreen()


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

【讨论】:

我编辑了代码,因为它是错误的。这两个属性是高度,如果它运行良好并且我得到了相同的结果,我已经尝试过。我认为我做错了事。 我明白了,所以上面的代码应该让你一开始按钮的大小是窗口大小的 11%。如果你想改变它(比如说你的一半窗口用于其他用途,并且你想使用半个窗口的 11%),你需要在此之后更新按钮大小,并且你需要在单独的函数(不是 init)。您可以删除您的登录屏幕并使用新维度创建一个新屏幕,但这不是最干净的。我自己目前正在解决同样的问题.. 比这更容易。只有我希望屏幕底部的两个按钮是屏幕的 1/9。我不关心其他领域(labelstextinputs)。我尝试设置像素值(例如“50px”),但得到了相同的结果...

以上是关于如何在 Kivy Python 中为 GridLayout 的某些按钮设置高度?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 中为桌面创建 kivy 应用程序?

在 pydev eclipse (Debian) 中配置 kivy 路径

Python Kivy - 下划线在标签中不起作用

Kivy 定义标签的背景颜色

Python:如何在 Kivy 中创建一个简单的框架?

Kivy ObjectProperty 更新标签文本