python - 在 Kivy 中独立移动多个小部件
问题描述
我正在尝试使用 Kivy 库创建一个带有 python 的 Ur 皇家游戏。
我正在尝试做的是为每个玩家创建一个棋盘(已经完成,但还有更复杂的工作)和 7 个棋子(数字)。我设法创建了所有 7 个,但不知道如何独立操作或移动它们。
我找到了一个允许我使用鼠标移动对象的代码,但我只需要移动鼠标所在的对象。有点像只抓住你需要的棋子,而不是一直抓住皇后。
代码:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Ellipse
from kivy.clock import Clock
from random import random
class CircleWidget(Widget):
def __init__(self, **kwargs):
Widget.__init__(self, **kwargs)
self.size = (50,50)
for i in range(0, 7):
self.circle = Ellipse(pos = self.pos, size = self.size)
self.canvas.add(self.circle)
# handle position change
def on_pos(self, obj, new_pos):
self.circle.pos = new_pos # when widget moves, so does the graphic instruction
class RootWidget(Widget):
def __init__(self, **kwargs):
Widget.__init__(self, **kwargs)
self.cw = CircleWidget()
self.add_widget(self.cw)
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:
print("This prints all the time...")
self.cw.pos = (touch.x,touch.y)
def on_touch_up(self, touch):
if touch.grab_current is self:
touch.ungrab(self)
# and finish up here
def update(self, dt):
print("No idea why I need this")
class MyApp(App):
def build(self):
rw = RootWidget()
# call update() every second
Clock.schedule_interval(rw.update, 1.0)
return rw
MyApp().run()
另外,我忘记将所有人物的位置编辑为彼此相邻,但这并不是一项艰巨的任务。
有没有帮助一一移动它们?
解决方案
类 CircleWidget
- 在画布上画一个椭圆。
- 将pos和size绑定到回调、重绘方法。
- 为每个Circlewidget实现on_touch_down、on_touch_up和on_touch_move方法。
例子
主文件
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Ellipse, Color
from kivy.core.window import Window
from random import randint
class CircleWidget(Widget):
def __init__(self, **kwargs):
super(CircleWidget, self).__init__(**kwargs)
self.size = (50, 50)
with self.canvas:
Color(0, 0, 1, 0.5)
self.circle = Ellipse(pos=self.pos, size=self.size)
self.bind(pos=self.redraw, size=self.redraw)
def redraw(self, *args):
self.circle.size = self.size
self.circle.pos = self.pos
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
# if the touch collides with our widget, let's grab it
touch.grab(self)
# and accept the touch.
return True
return super(CircleWidget, self).on_touch_down(touch)
def on_touch_up(self, touch):
# check if it's a grabbed touch event
if touch.grab_current is self:
# don't forget to ungrab ourself, or you might have side effects
touch.ungrab(self)
# and accept the last up
return True
return super(CircleWidget, self).on_touch_up(touch)
def on_touch_move(self, touch):
# check if it's a grabbed touch event
if touch.grab_current is self:
self.pos = touch.pos
# and accept the last move
return True
return super(CircleWidget, self).on_touch_move(touch)
class RootWidget(Widget):
def __init__(self, **kwargs):
super(RootWidget, self).__init__(**kwargs)
for i in range(8):
self.add_widget(CircleWidget(pos=(randint(0, Window.width - 50), randint(0, Window.height - 50))))
class MyApp(App):
def build(self):
return RootWidget()
if __name__ == "__main__":
MyApp().run()
输出
推荐阅读
- javascript - 如何清理 useffect 调用中的函数?
- python - setup.py 在分类器中包含许可证,但安装的轮子有 license=UNKNOWN
- java - 将 Spring Boot 升级到 2.3.0 时出现 Spring 数据问题
- c# - 在没有互联网的 Visual Studio 2015 中构建项目
- c++ - c ++使用递归而不是for循环
- c# - 是否可以在 C# 中删除对象?
- python - Python Bokeh - 使用两个同步的选择小部件过滤表
- alexa - 在特定 Alexa 设备上触发通知
- reactjs - 如何将 ref 类型的道具与诸如 Popover 之类的 Meterial-ui 组件一起使用?试图了解如何使用 'action'= updatePosition() 道具
- android - roboelectric 中工作经理的问题