Kivy锚点和网格布局居中

2 投票
1 回答
9460 浏览
提问于 2025-04-18 12:36

我正在使用锚点布局来放置小部件,我的小部件是一个网格布局。问题是,我想要一个紧凑的登录界面,但我发现有三个控件靠在一起,登出按钮在最后,所有控件之间的间距太大了(应该没有太多空隙),而且它们应该在锚点布局中居中显示。

现在的效果看起来不太好:

enter image description here

代码如下:

main.py:

from kivy.app import App
from formcontrol import FormControl

class MyApp(App):

    def build(self):
        self.title="sample App"
        self.formcontrol = FormControl()
        return self.formcontrol

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

FormControl.py:

from kivy.uix.boxlayout import BoxLayout
from kivy.uix.anchorlayout import AnchorLayout
from login.logincodes import LoginControl
from login.logincodes import AfterLogin

class FormControl(AnchorLayout):
    '''
    classdocs
    '''

    def __init__(self, **kwargs):
        '''
        Constructor
        '''
        super(FormControl,self).__init__(**kwargs)
        c= LoginControl()
        c.setparent(self)
        self.add_widget(c)

    def changewidget(self,to):
        if to == 'AfterLogin':
            self.clear_widgets()
            self.add_widget(AfterLogin())

logincodes.py:

from kivy.uix.gridlayout import GridLayout


class LoginControl(GridLayout):
    _parentwidget=None

    def __init__(self, **kwargs):
        super(LoginControl,self).__init__(**kwargs)
        self.userid.text='Welcome'

    def setparent(self,parent):
        self._parentwidget=parent

    def changewidget(self,to):
        self._parentwidget.changewidget(to)

    def login_pressed(self,button):
        print(button.text)
        print(self.userid.text)
        print(self.userpw.text)
        self.changewidget('AfterLogin')

    def close_pressed(self,button):
        print(button.text)
        exit()


class AfterLogin(GridLayout):

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

my.ky 文件:

<LoginControl>:
    rows: 3
    cols: 1

    userid: userid
    userpw: userpw

    BoxLayout:
        size_hint_y: None
        height: '32dp'
        Label:
            text: 'User ID'

        TextInput:
            id: userid
            text: 'some password'

    BoxLayout:
        size_hint_y: None
        height: '32dp'
        Label:
            text: 'Password'

        TextInput:
            id: userpw
            password: True
            text: 'some password'

    Button:
        text: 'Login'
        on_press: root.login_pressed(self)
        size_hint_y: None
        height: '32dp'

    Button:
        text: 'Close'
        on_press: root.close_pressed(self)
        size_hint_y: None
        height: '32dp'



<AfterLogin>:
    rows: 1
    Label:
        text: 'Logged In'

请告诉我我在配置用户界面时哪里出错了,我不想使用浮动布局,因为那就像用点来放置小部件。我对Python和Kivy都很陌生。你的支持和建议对我提高非常重要。

1 个回答

3

在你的 GridLayout 中,你设置了 rows 为 3 和 cols 为 1,这意味着这个布局可以放下 3 个子元素。当要放置关闭按钮时,所有的行和列都已经用完了,所以关闭按钮就被放到了默认位置 (0, 0)。我建议你只设置 cols,而不设置 rows,这样它会根据需要自动使用足够的行来放置子元素。

其次,这不是个问题,但有个更快的方法可以把所有子元素的高度设置为 32dp。与其在每个子元素上都设置 size_hintheight,你可以直接在 GridLayout 上设置 row_default_heightrow_force_default

最后,你的 GridLayout 仍然占用了所有的空间,这就是它在 AnchorLayout 中没有居中的原因。这个问题很容易解决,只需利用 minimum_height 属性 - 将 height 设置为 minimum_height,并将 size_hint_y 设置为 None,这样它就会居中了。

把这些结合起来:

<LoginControl>:
    cols: 1
    row_force_default: True
    row_default_height: '32dp'
    size_hint_y: None
    height: self.minimum_height

居中的 GridLayout 示例

撰写回答