我有一个getDirTree
和一个ScrollView
,它与它部分重叠并包含Bubble
问题:
我已经阅读了关于该主题的question的答案,建议要么合并GridLayout
和disabled
属性,这是我最终使用的属性,或者暂时将小部件移出屏幕。使用第一种隐藏opacity
的方法,我发现即使它被禁用,它也会阻止其后面的视图滚动,即使文档说明了这个属性
指示此窗口小部件是否可以与输入进行交互
所以我认为它不应该阻止滚动。有趣的是,当它没有被隐藏(Bubble
)时,滚动正好通过它,这更加令人困惑
我之前还有disabled=False
包含Bubble
,而ScrollView
又持有GridLayout
。以下问题不再是问题,但仍然是一个有趣的行为:
Bubble
通过向上滚动,但没有通过向下滚动?要理解我的意思,请运行代码,将鼠标移到Bubble
上,然后尝试使用鼠标滚轮向不同方向滚动。这是考虑到GridLayout
中的ScrollView
不包含任何内容,即使它不会影响行为
以下是两个问题的代码以及获得所需行为的一些说明:
from kivy.app import App
from kivy.lang import Builder
from kivy.core.window import Window
from kivy.uix.screenmanager import Screen
from kivy.uix.widget import Widget
from kivy.uix.textinput import TextInput
from kivy.uix.scrollview import ScrollView
from kivy.uix.gridlayout import GridLayout
from kivy.uix.bubble import Bubble
from kivy.properties import ListProperty
Builder.load_string('''
<SmileBubble>:
size_hint: None, None
pos: 220, 90
size: 175, 250
#ScrollView:
#GridLayout:
#rows: 8 # To see the second question's example, uncomment this section
# and comment out the one below
GridLayout:
rows: 8
<MessageView>:
canvas:
Color:
rgba: 1, 1, 1, 1
Rectangle:
pos: self.pos
size: self.size
<Message>:
BoxLayout:
pos: root.pos
height: self.height
TextInput:
pos: root.pos
size: root.size
id: msg
''')
class Message(Widget):
bg_color = ListProperty([0.99, 0.99, 0.99, 1])
class SmileBubble(Bubble):
def hide(self):
self.disabled = True
def show(self):
self.disabled = False
class MessageView(ScrollView):
pass
class TestApp(App):
def msg_in(self, text):
msg = Message()
msg.ids['msg'].text = text
msg.size_hint = [None, None]
msg.width = 160
self.msg_layout.add_widget(msg)
def build(self):
self.scr = Screen()
self.sv1_main = MessageView()
self.msg_layout = GridLayout(cols = 1,
size_hint_y = None)
self.msg_layout.bind(minimum_height = self.msg_layout.setter('height'))
self.smile_bbl = SmileBubble()
for i in range(10):
self.msg_in("test")
self.smile_bbl.hide() # To hide/show the Bubble, comment out this line. For the second question, comment out this line
self.scr.add_widget(self.sv1_main)
self.sv1_main.add_widget(self.msg_layout)
self.scr.add_widget(self.smile_bbl)
return self.scr
TestApp().run()
如果重要,我会使用Kivy v1.9.2-dev0
答案 0 :(得分:1)
如果你不想要不透明度和禁用技巧(很好的)或类似y = 5000
之类的东西,例如ScrollView
不能正常工作BoxLayout - 并明确使用它会导致你的canvas.clear
拉伸,我看到“两个”简单的选项,虽然不是没有删除 - 但保留!
首先,如果你可以访问它们,可以获取所有画布说明,将它们复制到某处from kivy.lang import Builder
from kivy.base import runTouchApp
from kivy.uix.boxlayout import BoxLayout
Builder.load_string('''
<Test>:
orientation: 'vertical'
Button:
on_release: root.move_me()
BoxLayout:
id: box
Button:
text: 'Hi %s!' % self.parent
Button:
id: box2
''')
class Test(BoxLayout):
def move_me(self):
if self.ids.box.children:
button = self.ids.box.children[0]
self.ids.box.remove_widget(button)
self.ids.box2.add_widget(button)
else:
button = self.ids.box2.children[0]
self.ids.box2.remove_widget(button)
self.ids.box.add_widget(button)
runTouchApp(Test())
,但如果出现问题,可以找到错误。
第二个基本上是第一个,但是在三个命令中,除非你忘记了小部件的去向(hehe),否则你不能搞砸了什么:
button.<something>
您可以看到小部件仍然存在于变量中,您可以通过text
访问其属性,如Boxlayout
中所示。
现在,如果你在例如GridLayout
或pos
以错误的方式:父级中的小部件[1, 2, 3].remove(2)
得到更新,与列表[1, 3]
完全相同,最终列表为BoxLayout
,其中my_widgets = <parent>.children[<widget you want to hide>:len(<parent>.children)-1]
表示将大小分成两半而不是三分之一。
如何解决这个问题?简单地说,再次使用上面的技巧,但现在保存更多小部件 - 您要隐藏的小部件+稍后添加到父的每个小部件
Widget
它将为您提供一个对象列表,即再次按原样保留所有内容,您只会“弹出”您不想看到的小部件。最后使用相同的size
(甚至可能是pos
制作占位符(例如for child in my_widgets:
<parent>.add_widget(child)
或透明的任何内容),但这是自动计算的,因此...)您想要的小部件隐藏和:
disabled=True
这种方法(或者更确切地说是我的解释)可能看起来很难,但比从父母的边界框中丢弃一个小部件或尝试Bubble
更简单,这对你来说导致无法滚动(否则我肯定会那样做。)将Widget
替换为Color
,您就可以滚动了。它会被放置到[0,0],但这不是一个参数,好像你用Rectangle
&amp; Widget
看到它,滚动光标放在master
上(至少对我来说from kivy.lang import Builder
from kivy.base import runTouchApp
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.widget import Widget
Builder.load_string('''
<Test>:
orientation: 'vertical'
Button:
text: 'hide'
on_release: root.hide(box)
BoxLayout:
id: box
Button:
text: 'Hi %s!' % self.parent
Button
text: 'Retrieve'
on_release: root.hide(root.placeholder, root.saved)
''')
class Test(BoxLayout):
def hide(self, what, retrieve=None):
# you'll need that object accessible and ".parent" will disappear
parent = what.parent
children = what.parent.children[:]
# check for position in children list
place = children.index(what)
# save the widget you want to hide
self.saved = children[place]
# save children from the latest added to the removed one
saved_children = children[0:place+1]
# sizes are optional here
self.placeholder = Widget(size_hint=[None, None],
size=saved_children[0].size)
for child in saved_children:
parent.remove_widget(child) # here you still can use what.parent
# here the ".parent" is not available - the reason for "parent" var.
# add Widget instead of whatever you will "hide"
# pass to "retrieve" the saved widget if you want it back
parent.add_widget(self.placeholder if not retrieve else retrieve)
# add widgets in order they were originally added to the parent
for child in list(reversed(saved_children[:place])):
parent.add_widget(child)
# cleanup mess ^^
del children, saved_children
runTouchApp(Test())
使用你的代码)。
最后:从中创建一个函数
NSTextFieldDelegate