gpt4 book ai didi

python - 为什么根小部件的窗口大小不同?

转载 作者:行者123 更新时间:2023-11-28 22:00:55 26 4
gpt4 key购买 nike

我正在尝试使用带有 GridLayout 的自定义小部件,但结果总是在角落里出现一个非常小的网格,而不是在整个窗口中展开的网格。

示例代码:

import kivy
kivy.require('1.5.1')

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout



class MyWidget(Widget):
def __init__(self):
super(MyWidget, self).__init__()

grid_layout = GridLayout(cols=3)
grid_layout.add_widget(Button(text='A'))
grid_layout.add_widget(Button(text='B'))
grid_layout.add_widget(Label(text='text'))
grid_layout.add_widget(Label(text='other'))
grid_layout.add_widget(Button(text='text'))
self.add_widget(grid_layout)


class MyApp(App):
def build(self):
float =
return MyWidget()


MyApp().run()

由于 Widget 的默认 size_hint(1,1) 它应该在整个窗口中扩展,并且 GridLayout 还有。为什么这没有发生?我怎样才能得到我想要的结果?

最佳答案

`class MyWidget(Widget):`

您的根小部件是 MyWidget,它继承自 Widget 而不是其中一个布局,因此不控制其子项的大小 如前所述 here , "size_hint 是layouts 用来管理其子项大小的值的元组"。

您的根小部件确实占据了窗口的整个空间。您可以通过向 MyWidget 的 Canvas 添加一个 Rectangle 来测试它,如下所示::

with self.canvas.before:
Color(1,0,0,1)
Rectangle(pos=self.pos, size=self.size)

您应该熟悉 Canvas ,canvas.before and canvas.after .它们基本上是指令组,前组在小部件的 Canvas 指令之前绘制,后组在后。

Kivy 中一个关键的不同之处在于小部件的大小/布局会延迟到下一帧,所以如果您只是将上面的代码片段添加到您的代码中,就像这样::

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.label import Label
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import *


class MyWidget(Widget):

def __init__(self, **kwargs):
# I'd make sure to pass of kwargs through to the super
# as there are widgets's that process their initial
# arguments through.
super(MyWidget, self).__init__(**kwargs)

grid_layout = GridLayout(cols=3)
grid_layout.add_widget(Button(text='A'))
grid_layout.add_widget(Button(text='B'))
grid_layout.add_widget(Label(text='text'))
grid_layout.add_widget(Label(text='other'))
grid_layout.add_widget(Button(text='text'))
self.add_widget(grid_layout)
with self.canvas.before:
Color(1,0,0,1)
Rectangle(pos=self.pos, size=self.size)


class MyApp(App):
def build(self):
return MyWidget()

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

这只会在您的小部件的初始位置和大小处显示一个红色矩形,这在当时将是它的默认位置和大小,分别为 (0, 0) 和 (100, 100)。

为了使红色矩形符合小部件的大小,我们应该bind它的大小与小部件的大小相同,如下所示::

...
grid_layout.add_widget(Button(text='text'))
self.add_widget(grid_layout)
with self.canvas.before:
Color(1,0,0,1)
self.rect = Rectangle(pos=self.pos, size=self.size)
self.bind(size=self.update_rect)

def update_rect(self, instance, value):
self.rect.pos = self.pos
self.rect.size = self.size

class MyApp(App):
def build(self):
...

如上面代码的输出所示,您的小部件占用了整个窗口的大小。但是,这并不能解决您的问题,子布局仍保持其原始位置和原始大小。这是因为小部件无法如上所述控制其子项的大小。

您在这里有两个选择,要么更新小部件的子/子项的大小和位置,就像您更新矩形一样(如果有多个子项,很快就会变得复杂),或者使用其中一个布局作为您的根小部件。

这也可以像这样在 kv 中完成::

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang import Builder

Builder.load_string('''
# this is the rule for MyWidget that defines
# what MyWidget looks like i.e.drawing
# instructions and widgets etc
<MyWidget>:
canvas.before:
Color:
rgba: 1, 0, 0, 1
Rectangle:
# this implicitly binds the size of the
# rect to the size of the widget
size: self.size
# self here still refers to the widget as Rectangle is only a
# graphics instruction and not a widget
pos: self.pos
GridLayout:
cols: 3
# root here refers to the `MyWidget`, bind the size of the
# GridLayout to the size of your root widget
size: root.size
Button:
text: 'A'
Button:
text: 'B'
Label:
text: 'text'
Label:
text: 'other'
Button:
text: 'text'
''')


class MyWidget(Widget):
pass


class MyApp(App):
def build(self):
return MyWidget()

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

上面的示例将子控件的大小绑定(bind)到它的父控件的大小。我仍然建议使用布局作为根小部件,并且不要犹豫嵌套布局。

关于python - 为什么根小部件的窗口大小不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14029010/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com