self.add_widget不响应 pos=() 参数



我有一些代码试图在窗口顶部放置一个图表,下面有文本/按钮输入。我正在使用 FigureCanvas 生成窗口,并尝试通过 python 方法和 kivy 方法同时添加小部件(Python 方法似乎是必要的,因为它是一个专门的后门,而 kivy 用于其他一切似乎更容易)。无论如何,我有这样的功能,我的元类正在唤起一个图形类,将图形窗口小部件添加到 GridLayout 上方的主窗口中,该窗口将保存所有用户输入。我的类图(FloatLayout)响应size_hint/大小输入,但不响应pos_hint/pos。

我希望通过以下两种方式之一获得帮助:

1)如何让类图(浮动布局)占据屏幕上半部分的位置?

或者,

2)如何让kivy首先将图形添加到GridLayout中,并避免额外的类图(FloatLayout)的问题?

我的大小设置任意小,以显示图表后面的按钮。最终,我将调用其他方法来向图形添加/删除绘图(已经使该部分正常工作),因此除非必要,否则尽量不要搞砸def graph(self)部分。


import matplotlib.pyplot as plt
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.config import Config
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvas
from kivy.uix.popup import Popup
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.core.window import Window

Config.set('graphics', 'borderless', '1')
Config.set('graphics', 'width', '1200')
Config.set('graphics', 'height', '400')
Config.set('graphics', 'resizable', '0')
KV = '''
<Meta>:
GridLayout:
size: root.width, root.height/2
rows: 5
BoxLayout:
Button:
text: 'test1'
Button:
text: 'test2'
BoxLayout:
Button:
text: 'test3'
Button:
text: 'test4'
'''
Builder.load_string(KV)

class Graph(FloatLayout):
def __init__(self, **kwargs):
super(Graph, self).__init__(**kwargs)
self.add_widget(self.graph())
def graph(self):
global fig1, ax
fig1 = plt.figure()
ax = fig1.add_subplot(111)
ax.plot([], [])
wid = FigureCanvas(fig1)
return wid

class Meta(Widget):
def __init__(self, **kwargs):
super(Meta, self).__init__(**kwargs)
self.add_widget(Graph(size_hint=(None,None), size=(Window.width/5, Window.height/5), pos_hint=(None,None), pos=(1000,1000)))

class Builder(App):
def build(self):
return Meta()

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

添加一个从 KVlang 继承的额外类就可以了。

import matplotlib.pyplot as plt
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.floatlayout import FloatLayout
from kivy.config import Config
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvas
from kivy.uix.popup import Popup
from kivy.uix.widget import Widget
from kivy.lang import Builder
from kivy.core.window import Window

Config.set('graphics', 'borderless', '1')
Config.set('graphics', 'width', '1200')
Config.set('graphics', 'height', '400')
Config.set('graphics', 'resizable', '0')
KV = '''
<Meta>:
orientation: 'vertical'

<Body>:
GridLayout:
size: root.width, root.height
rows: 5
BoxLayout:
Button:
text: 'test1'
Button:
text: 'test2'
BoxLayout:
Button:
text: 'test3'
Button:
text: 'test4'
'''
Builder.load_string(KV)

class Graph(BoxLayout):
def __init__(self, **kwargs):
super(Graph, self).__init__(**kwargs)
self.add_widget(self.graph())
def graph(self):
global fig1, ax
fig1 = plt.figure()
ax = fig1.add_subplot(111)
ax.plot([], [])
wid = FigureCanvas(fig1)
return wid

class Body(Widget):
pass

class Meta(BoxLayout):
def __init__(self, **kwargs):
super(Meta, self).__init__(**kwargs)
self.add_widget(Graph())
self.add_widget(Body())
class Builder(App):
def build(self):
return Meta()

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

问题 1

如何让类图(FloatLayout)占据顶部位置 屏幕的一半?

要使用pos_hintpos将小部件放置在布局中,最好的布局是FloatLayout。有关详细信息,请参阅解决方案">方法 1 - 使用 FloatLayout 作为根"。

问题2

我怎样才能让 kivy 首先将图形添加到网格布局中,然后 完全避免额外的类图(FloatLayout)的问题?

溶液

这个问题有两种解决方案。方法 1 使用 FloatLayout 作为根,方法 2 使用 BoxLayout 作为根。这两种方法都不需要额外的类。

方法 1 - 使用 FloatLayout 作为根目录

此方法还使用pos_hint将图形放在上半部分,将按钮放在下半部分。

KV文件

  1. 为孩子添加size_hint_y: 0.5pos_hint: {'bottom': 0.5}GridLayout:

代码片段 - kv 文件

<Meta>:
GridLayout:
size_hint_y: 0.5
pos_hint: {'bottom': 0.5}
...

py 文件

  1. class Meta(Widget):替换为class Meta(FloatLayout):
  2. class Graph(FloatLayout):替换为class Graph(BoxLayout):
  3. self.add_widget(Graph(...))替换为self.add_widget(Graph(size_hint_y=0.5, pos_hint={'top': 1}))

代码片段 - py 文件

class Graph(BoxLayout):
...
class Meta(BoxLayout):
def __init__(self, **kwargs):
super(Meta, self).__init__(**kwargs)
self.ids.graph.add_widget(Graph(size_hint_y=0.5, pos_hint={'top': 1}))

class Builder(App):
title = 'Method 1 - FloatLayout, pos_hint & size_hint_y'
def build(self):
return Meta()

方法 2 - 使用 BoxLayout 作为根目录

KV文件

  1. <Meta>:orientation: 'vertical添加到类规则
  2. 添加子项、带id: graphBoxLayout:size_hint_y: 0.5
  3. GridLayout:向子项添加size_hint_y: 0.5

代码片段 - kv 文件

<Meta>:
orientation: 'vertical'
BoxLayout:
id: graph
size_hint_y: 0.5
GridLayout:
size_hint_y: 0.5
...

py 文件

  1. class Meta(Widget):替换为class Meta(BoxLayout):
  2. class Graph(FloatLayout):替换为class Graph(BoxLayout):
  3. self.add_widget(Graph(...))替换为self.ids.graph.add_widget(Graph())

代码片段 - py 文件

class Graph(BoxLayout):
...
class Meta(BoxLayout):
def __init__(self, **kwargs):
super(Meta, self).__init__(**kwargs)
self.ids.graph.add_widget(Graph())

class Builder(App):
title = 'Method 2 - BoxLayout & size_hint_y'
def build(self):
return Meta()

相关内容

最新更新