你好我想在kivy的图形图中创建缩放效果(我在Windows上使用python 3.6 64bits中的kivy 1.10)
我想在我的图表小部件中检测鼠标滚轮事件,但我无法找到如何执行此操作。
我的代码:
import itertools
from math import sin, cos, pi
from random import randrange
from kivy.utils import get_color_from_hex as rgb
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from graph import Graph,MeshLinePlot
from kivy.uix.popup import Popup
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.stacklayout import StackLayout
class Visu(GridLayout):
def __init__(self, **kwargs):
super(Visu, self).__init__(**kwargs)
self.cols = 2
self.row = 2
b = BoxLayout(orientation='vertical', on_press=self.zoom)
graph = Graph(xlabel='X', ylabel='Y', x_ticks_minor=5,
x_ticks_major=25, y_ticks_major=1,
y_grid_label=True, x_grid_label=True, padding=5,
x_grid=True, y_grid=True, xmin=-0, xmax=50, ymin=-1, ymax=1)
#graph.add_x_axis(0,10)
plot1 = MeshLinePlot(color=[1, 0, 0, 1])
plot1.points = [(x, sin(x / 10.)) for x in range(0, 65000)]
graph.add_plot(plot1)
plot2 = MeshLinePlot(color=[1, 0, 0, 1])
plot2.points = [(x, sin(x / 10.)) for x in range(65000, 120000)]
graph.add_plot(plot2)
b.add_widget(graph)
graph.xmax=1000
graph.xmax=40
self.add_widget(b)
def zoom(self):
print("if mousewheel i change graph.xmin and graph.xmax")
class MyApp(App):
def build(self):
return Visu()
if __name__ == '__main__':
MyApp().run()
我使用此代码 https://github.com/kivy-garden/garden.graph/blob/master/init.py 使用kivy创建图表,但使用此代码我无法放大图表。
我想检测鼠标滚轮并运行我的函数self.zoom
答案 0 :(得分:1)
您必须实施on_touch_down事件,并通过is_mouse_scrolling
和button
检查是否存在滚动及其类型。
class Visu(GridLayout):
def __init__(self, **kwargs):
...
def on_touch_down(self, touch):
if touch.is_mouse_scrolling:
if touch.button == 'scrolldown':
print('down')
elif touch.button == 'scrollup':
print('up')
GridLayout.on_touch_down(self, touch)
def zoom(self):
print("if mousewheel i change graph.xmin and graph.xmax")
答案 1 :(得分:1)
on_press 和 on_release 事件可绑定到Button小部件。我们可以使用 on_touch_down 来模拟 on_press 事件和 on_touch_up 来模拟 on_release 事件。
使用 on_touch_down 事件,使用我们的小部件检查 touch 的 collision ,并检查按钮配置文件 。如果按钮配置文件,请检查鼠标按钮单击,或鼠标滚轮滚动( scrollup 或 scrolldown < / em>的)。如果单击了按钮,请抓住触摸事件,增加触摸事件计数器,然后开始重复缩放。
使用 on_touch_up 事件,检查已抓取的触摸事件,如果已抓取未触摸触摸事件,减少触摸事件计数器,如果触摸事件计数器为零,则停止重复缩放。
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
if 'button' in touch.profile:
if touch.button in ("right", "left"):
...
dist = 1 if touch.button == 'left' else -1
touch.grab(self)
self._touch_count += 1
...
return True
elif touch.is_mouse_scrolling:
dist = 1 if touch.button == 'scrollup' else -1
...
return True
return super(..., self).on_touch_down(touch)
def on_touch_up(self, touch):
if touch.grab_current == self:
touch.ungrab(self)
self._touch_count -= 1
if self._touch_count == 0:
print("\tanimate to the closest zoom")
return True
return super(RootWidget, self).on_touch_up(touch)
Programming Guide » Input management » Touch event basics
默认情况下,会将触摸事件分派给当前显示的所有内容 小部件。这意味着小部件接收触摸事件是否发生 在他们的物理区域内与否。
为了提供最大的灵活性,Kivy发送了 所有小部件的事件,让他们决定如何对它们做出反应。 如果您只想响应窗口小部件中的触摸事件,那么 只需检查碰撞。
配置文件值:按钮
说明:鼠标按钮('左', 'right','middle','scrollup'或'scrolldown')。通过访问 按钮属性。is_mouse_scrolling
如果触摸是鼠标滚轮,则返回True
from math import sin
from kivy.garden.graph import Graph, MeshLinePlot
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty
class RootWidget(BoxLayout):
_touch_count = NumericProperty(0)
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
self.graph = Graph(xlabel='X', ylabel='Y', x_ticks_minor=5,
x_ticks_major=25, y_ticks_major=1,
y_grid_label=True, x_grid_label=True, padding=5,
x_grid=True, y_grid=True, xmin=-0, xmax=100, ymin=-1, ymax=1)
plot = MeshLinePlot(color=[1, 0, 0, 1])
plot.points = [(x, sin(x / 10.)) for x in range(0, 101)]
self.graph.add_plot(plot)
self.add_widget(self.graph)
def on_touch_down(self, touch):
"""
If the touch falls inside of our widget, we check button profile. If mouse button click, we set dist to 1 for
left mouse button clicked else -1 for right mouse button clicked. If not mouse button click, we check for mouse
wheel scrolling. If mouse is scrolling, we set dist to 1 if scrollup else -1 for scrolldown. If mouse button
clicked or mouse wheel scrolling, we return True, indicating that we have consumed the touch and don’t want it
to propagate any further.
Finally, if the touch falls outside our widget, not mouse button clicked (left / right button clicked), or not
mouse wheel scrolling, we call the original event using super(…) and return the result. This allows the touch
event propagation to continue as it would normally have occurred.
:param touch:
:return:
"""
print("\non_touch_down:")
if self.collide_point(*touch.pos):
if 'button' in touch.profile:
if touch.button in ("right", "left"):
print("\t", touch.button, "mouse clicked")
print("\ttouch.pos =", touch.pos)
dist = 1 if touch.button == 'left' else -1
self.zoom(dist)
return True
elif touch.is_mouse_scrolling:
print("\tmouse wheel", touch.button)
print("\ttouch.pos =", touch.pos)
dist = 1 if touch.button == 'scrollup' else -1
self.zoom(dist)
return True
return super(RootWidget, self).on_touch_down(touch)
def on_touch_up(self, touch):
print("\non_touch_up:")
if touch.grab_current == self:
print("\ttouch.button is", touch.button)
print("\ttouch.pos is", touch.pos)
touch.ungrab(self)
self._touch_count -= 1
if self._touch_count == 0:
# TODO
print("\tanimate to the closest zoom")
return True
return super(RootWidget, self).on_touch_up(touch)
def zoom(self, dist):
self.graph.xmax += dist * 10
self.graph.xmin += dist
class GraphDemo(App):
def build(self):
return RootWidget()
if __name__ == "__main__":
GraphDemo().run()