答案 0 :(得分:3)
您可以改进和扩展的一个简单示例:
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.widget import Widget
from kivy.core.window import Window
from kivy.uix.actionbar import ActionButton
from kivy.uix.label import Label
from kivy.clock import Clock
Builder.load_string("""
<Tooltip>:
size_hint: None, None
size: self.texture_size[0]+5, self.texture_size[1]+5
canvas.before:
Color:
rgb: 0.2, 0.2, 0.2
Rectangle:
size: self.size
pos: self.pos
<MyWidget>
ActionBar:
ActionView:
MyActionButton:
icon: 'atlas://data/images/defaulttheme/audio-volume-high'
MyActionButton:
icon: 'atlas://data/images/defaulttheme/audio-volume-high'
""")
class Tooltip(Label):
pass
class MyActionButton(ActionButton):
tooltip = Tooltip(text='Hello world')
def __init__(self, **kwargs):
Window.bind(mouse_pos=self.on_mouse_pos)
super(ActionButton, self).__init__(**kwargs)
def on_mouse_pos(self, *args):
if not self.get_root_window():
return
pos = args[1]
self.tooltip.pos = pos
Clock.unschedule(self.display_tooltip) # cancel scheduled event since I moved the cursor
self.close_tooltip() # close if it's opened
if self.collide_point(*self.to_widget(*pos)):
Clock.schedule_once(self.display_tooltip, 1)
def close_tooltip(self, *args):
Window.remove_widget(self.tooltip)
def display_tooltip(self, *args):
Window.add_widget(self.tooltip)
class MyWidget(Widget):
pass
class ClientApp(App):
def build(self):
return MyWidget()
if __name__ == '__main__':
ClientApp().run()
首先,我将on_mouse_pos
方法绑定到Window.mouse_pos
事件,以便我可以检测鼠标光标悬停在ActionButton
的子类上的时间。这基于this snippet。然后,如果我不能移动光标,我会使用Clock.schedule_once()
进行操作以使我的工具箱可见。要显示我只是将一个Label的子类添加到小部件堆栈中。您可以将display_tooltip()
和close_tooltip()
方法替换为更复杂的方法。
编辑:相应地将代码更新为this answer
答案 1 :(得分:0)
好的,我将其扩展了一点。
现在可以用KV语言设置工具提示文本。因此,每个对象/实例都有其自己的工具提示。
Tooltip
及其文本tooltip_txt
是ToolTipSpinner
的属性。
from kivy.app import App
from kivy.core.window import Window
Window.minimum_width, Window.minimum_height = 800, 600
from kivy.clock import Clock
from kivy.compat import string_types
from kivy.uix.spinner import Spinner
from kivy.uix.label import Label
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.properties import ObjectProperty
from kivy.factory import Factory
from kivy.lang import Builder
Builder.load_string("""
<ToolTipSpinner>:
<Tooltip>:
size_hint: None, None
size: self.texture_size[0]+5, self.texture_size[1]+5
canvas.before:
Color:
rgb: 0.2, 0.2, 0.2
Rectangle:
size: self.size
pos: self.pos
<MyBar>:
orientation: 'horizontal'
padding: 2
spacing: 2
canvas.before:
Color:
rgba: 1, 1, 1, 1
Line:
width: 1.
rectangle: (self.x+1, self.y-1, self.width, self.height)
BoxLayout:
orientation: 'horizontal'
padding: 2,2,2,2
spacing: 2
size_hint: None, 1
width: 110
ToolTipSpinner:
id: _spinner_type_1
tooltip_txt: 'Tooltip T1'
text: 'Type 1'
values: ['0', '1', '2', '3']
size_hint: None, .45
on_text: self.on_spinner_select(self.text)
ToolTipSpinner:
id: _spinner_type_2
tooltip_txt: 'Tooltip T2\\nwith newline'
text: 'Type 2'
values: ['4', '5', '6', '7', '8', '9']
size_hint: None, .45
on_text: self.on_spinner_select(self.text)
""")
class Tooltip(Label):
pass
class MyBar(BoxLayout):
pass
class ToolTipSpinner(Spinner):
tooltip_txt = StringProperty('')
tooltip_cls = ObjectProperty(Tooltip)
def __init__(self, **kwargs):
self._tooltip = None
super(ToolTipSpinner, self).__init__(**kwargs)
fbind = self.fbind
fbind('tooltip_cls', self._build_tooltip)
fbind('tooltip_txt', self._update_tooltip)
Window.bind(mouse_pos=self.on_mouse_pos)
self._build_tooltip()
def _build_tooltip(self, *largs):
if self._tooltip:
self._tooltip = None
cls = self.tooltip_cls
if isinstance(cls, string_types):
cls = Factory.get(cls)
self._tooltip = cls()
self._update_tooltip()
def _update_tooltip(self, *largs):
txt = self.tooltip_txt
if txt:
self._tooltip.text = txt
else:
self._tooltip.text = ''
def on_spinner_select(self, text):
print(text)
def on_mouse_pos(self, *args):
if not self.get_root_window():
return
pos = args[1]
self._tooltip.pos = pos
Clock.unschedule(self.display_tooltip) # cancel scheduled event since I moved the cursor
self.close_tooltip() # close if it's opened
if self.collide_point(*self.to_widget(*pos)):
Clock.schedule_once(self.display_tooltip, 1)
def close_tooltip(self, *args):
Window.remove_widget(self._tooltip)
def display_tooltip(self, *args):
Window.add_widget(self._tooltip)
class MainApp(App):
def build(self):
return MyBar()
if __name__ == '__main__':
MainApp().run()