使用python / kivy处理小部件放置以解决屏幕旋转的好方法是啥?
Posted
技术标签:
【中文标题】使用python / kivy处理小部件放置以解决屏幕旋转的好方法是啥?【英文标题】:What is a good way to handle widget placement to account for screen rotation using python / kivy?使用python / kivy处理小部件放置以解决屏幕旋转的好方法是什么? 【发布时间】:2017-04-10 23:52:54 【问题描述】:当我使用 kivy 构建应用程序时,我可以在任何地方获得所需的一切,但是当我将屏幕从纵向旋转到横向时,我的小部件开始相互碰撞。有什么好的方法可以防止这种情况发生?
在附加的示例中,我能够将设置按钮的位置绑定到我的标题标签小部件,但我没有成功让我的滚动视图绑定到它,因此当它旋转时,它与标签的底部。
Python:
class First_Screen(Screen):
def __init__(self, **kwargs):
super(First_Screen, self).__init__(**kwargs)
list_of_buttons = [
'button1',
'button2',
'button3',
'button4',
'button5',
'button6 ',
'button7',
'button8',
]
class My_Grid(FloatLayout, ScrollView):
grid = ObjectProperty(None)
def on_grid(self, *args):
for btn in list_of_buttons:
btn = Button(
text = btn,
)
btn.bind(on_press= First_Screen.print_message)
self.grid.add_widget(btn)
def print_message(self):
print ('Congratulations! You have clicked a button!')
class ScreenManagement(ScreenManager):
pass
class Stack_Overflow(App):
def build(self):
sm = ScreenManager(transition = FadeTransition())
sc0 = First_Screen(name = 'first_screen')
sm.add_widget(sc0)
return sm
if __name__ == '__main__':
Stack_Overflow().run()
kv:
ScreenManagement:
First_Screen:
<ImageButton@ButtonBehavior+Image>:
<First_Screen>:
name: 'first_screen'
Label:
id: header
text: 'header'
pos_hint: ('left' : 1, 'top' : 1)
size_hint: (1,None)
height: dp(50)
canvas.before:
Color:
rgba: (.6, .6, .6, 1)
Rectangle:
pos: self.pos
size: self.size
ScrollView:
size_hint: (1,.8)
pos_hint: ('center_x' : .5, 'center_y' : .5)
My_Grid:
grid: grid
GridLayout:
id: grid
cols: 1
size_hint_y: None
row_default_height: "40dp"
height: self.minimum_height
ImageButton:
id: settings
size_hint: None, None
height: dp(30)
width: dp(30)
pos: header.x, header.y + 10
pos_hint: 'right': 1
source: 'settings_black.png'
图片:portrait、landscape
谢谢!
【问题讨论】:
【参考方案1】:编辑:我误解了这个问题,我以为你对Image
不满意。在ScrollView
的情况下,问题不在于ScrollView
本身,因为它使用相对位置和大小。
问题在于Label
(header),它的高度设置为绝对数字,即50
密集像素。这意味着无论您拥有什么屏幕,或者无论您设置什么尺寸,这个小部件都将有 50 像素 corrected 和屏幕的 dpi。
实际上,这意味着如果您的屏幕达到400x100
分辨率,您的Label
将占据屏幕的一半,而ScrollView
将被放置在其顶部(很可能您不会看到Label
然后)。
要解决这个问题,您有两个选择。如果您想单独使用FloatLayout
,则需要使用正确定位/大小,即相对,并确保小部件没有重叠。
否则,只需将小部件拖放到 BoxLayout
或类似的其他布局,自行管理此类事情:
class First_Screen(BoxLayout, Screen):
def __init__(self, **kwargs):
super(First_Screen, self).__init__(orientation='vertical', **kwargs)
或有点不同(更好看):
class First_Screen(BoxLayout, Screen):
def __init__(self, **kwargs):
在 kv 中:
<First_Screen>:
name: 'first_screen'
orientation: 'vertical'
另外请注意,有一个screen
module,这使得测试这些东西比在不必要时将代码放到 apk 和 android 上更容易。示例:
python main.py -m screen:note2,landscape,scale=.5
【讨论】:
我的设置按钮实际上完全按照我的意愿行事。我是这样设置的,所以当我旋转手机时,它仍然保持在标题标签的中间。我的主要问题是我无法弄清楚如何让我的滚动视图小部件在我的标题标签下方开始一定数量的像素,而是当手机旋转时它与标题标签碰撞,而设置按钮恰好停留在它的位置应该。我尝试使用 header.x 和 header.y 设置滚动视图的位置,但这似乎不起作用,我发布的示例是我能做的最接近的示例 @Indeciski ping 放入 BoxLayout 似乎效果很好。至于使用 FloatLayout,我注意到如果您创建一个按钮然后旋转手机,它往往会被压扁并且看起来很尴尬。这是通过使用 RelativeLayout 修复的吗看看哪个更适合我?无论如何,非常感谢您的帮助和详细的解释! @Indeciski 好吧,正如你所说,任何使位置自动的东西,所以here 是基础,其余的要么读取每个布局页面的顶部(如果它也有位置) 或直接source code 以查看其行为方式。要获得一些最小尺寸,您可以使用size_hint_min
和size_hint_max
作为最大尺寸,这在移动布局中可能很有用。就个人而言,我认为在移动设备上使用 FloatLayout
没有任何意义,因为旋转屏幕会改变一些东西。
感谢您让我知道 FloatLayout 不是移动设备的最佳选择,因为试图让它正确地采取行动已经让我很头疼,因为显然有更好的方法来完成什么我正在尝试做以上是关于使用python / kivy处理小部件放置以解决屏幕旋转的好方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章