問題描述
我剛開始使用 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.
現在我的拖動效果不太好.如果我移動鼠標太快,它會取消移動方法(因為它不再接觸).有沒有更好的方法來產生拖動或者我只是增加刷新率(如果有的話怎么辦?).
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]
我嘗試使用 Buttons,使用 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 中創建動態繪制的線.
推薦答案
首先,你應該閱讀 觸摸事件.這里特別感興趣的是關于抓取觸摸事件的部分.基本上,您可以抓取"一個觸摸以確保抓取小部件將始終從該觸摸接收更多事件 - 換句話說,該觸摸事件之后的 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 已經有了:分散
.
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 中使用和移動小部件/按鈕的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!