在Kivy中使用和移动小部件/按钮 [英] Using and moving Widgets/Buttons in Kivy
问题描述
我只是从Kivy开始,这与我习惯的不同,如果我犯了愚蠢的错误,我深表歉意!
I'm just starting off with Kivy and it's different to what I'm used to, apologies if I'm making stupid mistakes!
现在,我正在尝试创建一个执行以下操作的应用程序:
Right now I'm trying to create an app that does the following:
- 允许创建节点(现在为椭圆).
- 允许用户通过拖动来定位节点.
- 允许用户用线连接节点.
到目前为止,我已经取得了第一个,而第二个则有所成就.
So far I've achieved the first, and the second somewhat.
目前,我的拖动效果不太好.如果我太快地移动了鼠标,它将取消move方法(因为它不再处于接触状态).有没有更好的方法来产生拖动效果,或者我只是提高刷新率(如果可以,怎么办?).
Right now my dragging is not working too well. If I move the mouse too quickly it cancels the move method (as it is no longer in contact). Is there a better way to produce dragging or do I just increase the refresh rate (if so how?).
def on_touch_move(self, touch):
if self.collide_point(touch.x, touch.y):
self.pos=[touch.x-25, touch.y-25]
我尝试使用按钮来代替,使用on_press方法来更好地跟踪运动.但是现在我很难更新按钮的位置(主要是语法).
I've tried using Buttons instead, using the on_press method to track the moving better. However now I'm having difficulty updating the position of the button (mostly just syntax).
class GraphNode(Button):
background_disabled_down=1
background_disabled_normal=1
def moveNode(self):
with touch:
self.pos=[touch.x-25, touch.y-25]
我不知道如何使用接触值,并不断出现一系列错误. (显然当前的尝试没有用,我只是觉得很有趣).
I have no idea how to use the touch value, and keep getting an array of errors. (Obviously the current attempt doesn't work, I just thought it was funny).
您可能会说,我还不知道如何摆脱按钮图形,因为我想使用椭圆形.另外,如果有人可以告诉我如何在按钮按下时改变椭圆的颜色,那会很酷!
As you could probably tell, I also don't know how to get rid of the button graphics, as I want to use the ellipse. As an added bonus if someone could show me how to change the colour of the ellipse on button press that would be cool!
kv文件:
<GraphNode>:
size: 50, 50
canvas:
Ellipse:
pos: self.pos
size: self.size
on_press:
root.moveNode()
我希望能够使用触摸信息来更新位置,但是不知道如何在此处实现.
I want to be able to use the touch information to update the position, but don't know how to implement it here.
全核心python代码:
Full core python code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.properties import NumericProperty, ReferenceListProperty,\
ObjectProperty
from kivy.graphics import Color, Ellipse, Line
class GraphInterface(Widget):
node = ObjectProperty(None)
class GraphApp(App):
def build(self):
node = GraphNode()
game = GraphInterface()
createNodeButton = Button(text = 'CreateNode', pos=(100,0))
createEdgeButton = Button(text = 'CreateEdge')
game.add_widget(createNodeButton)
game.add_widget(createEdgeButton)
def createNode(instance):
game.add_widget(GraphNode())
print "Node Created"
def createEdge(instance):
game.add_widget(GraphEdge())
print "Edge Created"
createNodeButton.bind(on_press=createNode)
createEdgeButton.bind(on_press=createEdge)
return game
class GraphNode(Button):
def moveNode(self):
with touch:
self.pos=[touch.x-25, touch.y-25]
#def onTouchMove(self, touch):
# if self.collide_point(touch.x, touch.y):
# self.pos=[touch.x-25, touch.y-25]
pass
class GraphEdge(Widget):
def __init__(self, **kwargs):
super(GraphEdge, self).__init__(**kwargs)
with self.canvas:
Line(points=[100, 100, 200, 100, 100, 200], width=1)
pass
if __name__ == '__main__':
GraphApp().run()
如果您需要任何其他信息,或者有任何不清楚的地方,请告诉我!
If you need any other info, or anything is unclear, please let me know!
第二个问题移至:在Kivy中创建动态绘制的线.
推荐答案
首先,您应该阅读触摸事件在Kivy中.这里特别有趣的是有关捕获触摸事件的部分.基本上,您可以抓住"触摸以确保抓取小部件将始终从该触摸接收到更多事件,换句话说,该触摸事件之后的on_touch_move
和on_touch_up
将被发送到您的小部件.
First, you should read up on touch events in Kivy. Of particular interest here is the section on grabbing touch events. Basically, you can "grab" a touch to ensure that the grabbing widget will always receive further events from that touch - in other words, the on_touch_move
and on_touch_up
following that touch event will be sent to your widget.
基本示例:
class MyWidget(Widget):
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
touch.grab(self)
# do whatever else here
def on_touch_move(self, touch):
if touch.grab_current is self:
# now we only handle moves which we have grabbed
def on_touch_up(self, touch):
if touch.grab_current is self:
touch.ungrab(self)
# and finish up here
但是,甚至更好!如果您希望能够拖动窗口小部件,则Kivy已经具有以下功能: Scatter
.
But, even better! If you want to be able to drag widgets around, Kivy already has that: Scatter
.
只需将窗口小部件包装在Scatter
中,即可将其拖动.您还可以使用多点触控来旋转和缩放Scatter
,但是您可以轻松地禁用该(kv):
Just wrap your widget in a Scatter
and you can drag it around. You can also use multitouch to rotate and scale a Scatter
, but you can easily disable that (kv):
FloatLayout:
Scatter:
do_scale: False
do_rotation: False
MyWidget:
旁注-这是不正确的:
Side note - this is incorrect:
class GraphNode(Button):
background_disabled_down=1
background_disabled_normal=1
background_disabled_down
和background_disabled_normal
是 Kivy属性-您应设置__init__
中的那些值.
background_disabled_down
and background_disabled_normal
are Kivy properties - you should set those values in __init__
.
强制这些值:
class GraphNode(Button):
def __init__(self, **kwargs):
super(GraphNode, self).__init__(background_disabled_down='',
background_disabled_normal='', **kwargs)
建议这些值(更好的选择):
Suggest these values (better option):
class GraphNode(Button):
def __init__(self, **kwargs):
kwargs.setdefault('background_disabled_down', '')
kwargs.setdefault('background_disabled_normal', '')
super(GraphNode, self).__init__(**kwargs)
最后,请注意,这些属性是指向用于禁用的Button
的图像的文件名.如果删除这些值并禁用按钮,则不会绘制任何背景.
Finally, note that these properties are filenames pointing to the images used for the disabled Button
. If you remove these values, and disable your button, it will draw no background whatsoever.
这篇关于在Kivy中使用和移动小部件/按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!