<i id='uEyBW'><tr id='uEyBW'><dt id='uEyBW'><q id='uEyBW'><span id='uEyBW'><b id='uEyBW'><form id='uEyBW'><ins id='uEyBW'></ins><ul id='uEyBW'></ul><sub id='uEyBW'></sub></form><legend id='uEyBW'></legend><bdo id='uEyBW'><pre id='uEyBW'><center id='uEyBW'></center></pre></bdo></b><th id='uEyBW'></th></span></q></dt></tr></i><div id='uEyBW'><tfoot id='uEyBW'></tfoot><dl id='uEyBW'><fieldset id='uEyBW'></fieldset></dl></div>
    • <bdo id='uEyBW'></bdo><ul id='uEyBW'></ul>

    <small id='uEyBW'></small><noframes id='uEyBW'>

    1. <legend id='uEyBW'><style id='uEyBW'><dir id='uEyBW'><q id='uEyBW'></q></dir></style></legend>
      <tfoot id='uEyBW'></tfoot>

      1. 在kivy中的触摸事件上旋转对象

        时间:2023-06-07
              <tbody id='k1QDh'></tbody>
          • <tfoot id='k1QDh'></tfoot>

            • <i id='k1QDh'><tr id='k1QDh'><dt id='k1QDh'><q id='k1QDh'><span id='k1QDh'><b id='k1QDh'><form id='k1QDh'><ins id='k1QDh'></ins><ul id='k1QDh'></ul><sub id='k1QDh'></sub></form><legend id='k1QDh'></legend><bdo id='k1QDh'><pre id='k1QDh'><center id='k1QDh'></center></pre></bdo></b><th id='k1QDh'></th></span></q></dt></tr></i><div id='k1QDh'><tfoot id='k1QDh'></tfoot><dl id='k1QDh'><fieldset id='k1QDh'></fieldset></dl></div>

              <small id='k1QDh'></small><noframes id='k1QDh'>

              <legend id='k1QDh'><style id='k1QDh'><dir id='k1QDh'><q id='k1QDh'></q></dir></style></legend>
              • <bdo id='k1QDh'></bdo><ul id='k1QDh'></ul>

                  本文介绍了在kivy中的触摸事件上旋转对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我正在制作一个会像大表盘一样旋转的圆圈.目前,我在顶部有一个箭头来显示表盘的朝向.我希望它的行为有点像老式的旋转电话,这样当你的手指/光标向下时你可以旋转它,但在你放手后它会(慢慢地)拉回顶部.

                  I'm working on making a circle that will spin kind of like a large dial. Currently, I have an arrow at the top to show which direction the dial is facing. I'd like its behavior to be kind of like an old timey rotary phone, such that while your finger/cursor is down you can rotate it, but it'll (slowly) yank back to top after you let go.

                  这是我的对象的样子:

                  这是我的代码:

                  #!/usr/bin/kivy
                  import kivy
                  kivy.require('1.7.2')
                  import math
                  
                  from random import random
                  from kivy.app import App
                  from kivy.uix.widget import Widget
                  from kivy.uix.gridlayout import GridLayout
                  from kivy.uix.anchorlayout import AnchorLayout
                  from kivy.uix.relativelayout import RelativeLayout
                  from kivy.graphics import Color, Ellipse, Rectangle
                  
                  class MinimalApp(App):
                      title = 'My App'
                      def build(self):
                          root = RootLayout()
                          return(root)
                  
                  class RootLayout(AnchorLayout):
                      pass
                  
                  class Circley(RelativeLayout):
                      angle = 0
                      def on_touch_down(self, touch):
                          ud = touch.ud
                          ud['group'] = g = str(touch.uid)
                          return True
                      def on_touch_move(self, touch):
                          ud = touch.ud
                  #        print(touch.x, 0)
                  #        print(self.center)
                  #        print(0, touch.y)
                  #        print(touch.x - self.center[0], touch.y - self.center[1])
                          y = (touch.y - self.center[1])
                          x = (touch.x - self.center[0])
                          calc = math.degrees(math.atan2(y,x))
                          angle = calc if calc > 0 else (360 + calc)
                          print(angle)
                      def on_touch_up(self, touch):
                          touch.ungrab(self)
                          ud = touch.ud
                          return True
                  
                  if __name__ == '__main__':
                      MinimalApp().run()
                  

                  还有kv:

                  #:kivy 1.7.2
                  #:import kivy kivy
                  
                  <RootLayout>:
                      anchor_x: 'center'                              # I think this /is/ centered
                      anchor_y: 'center' 
                      canvas.before:
                          Color:
                              rgba: 0.4, 0.4, 0.4, 1
                          Rectangle:
                              pos: self.pos
                              size: self.size
                      Circley:
                          anchor_x: 'center'                          # this is /not/ centered.
                          anchor_y: 'center' 
                          canvas.before:
                              PushMatrix
                              Color:
                                  rgba: 0.94, 0.94, 0.94, 1
                              Rotate:
                                  angle: self.angle
                                  axis: 0, 0, 1
                                  origin: self.center
                              Ellipse:
                                  source: 'arrow.png'
                                  size: min(self.size), min(self.size)
                                  pos: 0.5*self.size[0] - 0.5*min(self.size), 0.5*self.size[1] - 0.5*min(self.size)
                                  Label:
                                      text: unicode(self.size)    # this is /not/ appearing
                                      color: 1,0,0,1
                          canvas.after:
                              PopMatrix
                  

                  部分内容来自 kivy touchtracer 演示,来自这个 SO question.

                  Parts of that are borrowed from the kivy touchtracer demo, and from this SO question.

                  您可以看到我的计算正确地打印了圆的原点和触摸事件之间的角度(不确定这将如何响应多个手指,还没有考虑那么远),但不确定如何将其集成到界面中的旋转"反馈事件中.

                  You can see I have a calculation that is correctly printing the angle between the origin of the circle and the touch event (not sure how this'll respond to multiple fingers, haven't thought that far through), but not sure how to integrate this into a "spinning" feedback event in the interface.

                  推荐答案

                  您可以将画布的角度绑定到 NumericProperty,以便从代码内部进行更改.您需要做的就是正确计算这些角度.在玩了一下之后,我创建了以下代码:

                  You can bind angle of canvas to NumericProperty, to change it from inside your code. All you need to do is to compute those angles correctly. After playing a bit with it I created following code:

                  from kivy.app import App
                  from kivy.uix.widget import Widget
                  from kivy.lang import Builder
                  from kivy.animation import Animation
                  from kivy.properties import NumericProperty
                  
                  import math 
                  
                  kv = '''
                  <Dial>:
                      canvas:
                          Rotate:
                              angle: root.angle
                              origin: self.center
                          Color:
                              rgb: 1, 0, 0
                          Ellipse:    
                              size: min(self.size), min(self.size)
                              pos: 0.5*self.size[0] - 0.5*min(self.size), 0.5*self.size[1] - 0.5*min(self.size)
                          Color:
                              rgb: 0, 0, 0
                          Ellipse:    
                              size: 50, 50
                              pos: 0.5*root.size[0]-25, 0.9*root.size[1]-25
                  '''
                  Builder.load_string(kv)
                  
                  class Dial(Widget):
                      angle = NumericProperty(0)
                  
                      def on_touch_down(self, touch):
                          y = (touch.y - self.center[1])
                          x = (touch.x - self.center[0])
                          calc = math.degrees(math.atan2(y, x))
                          self.prev_angle = calc if calc > 0 else 360+calc
                          self.tmp = self.angle
                  
                      def on_touch_move(self, touch):
                          y = (touch.y - self.center[1])
                          x = (touch.x - self.center[0])
                          calc = math.degrees(math.atan2(y, x))
                          new_angle = calc if calc > 0 else 360+calc
                  
                          self.angle = self.tmp + (new_angle-self.prev_angle)%360
                  
                      def on_touch_up(self, touch):
                          Animation(angle=0).start(self)
                  
                  class DialApp(App):
                      def build(self):
                          return Dial()
                  
                  if __name__ == "__main__":
                      DialApp().run()
                  

                  我正在计算 on_touch_move 中初始角度(按下鼠标后)和后期角度之间的差异.由于角度是一个属性,我还可以使用 kivy.animation 对其进行修改,以在释放鼠标按钮后使表盘回旋.

                  I'm calculating difference between initial (after pressing mouse) and later angle in on_touch_move. Since angle is a property I can also modify it using kivy.animation to make dial spin back after releasing mouse button.

                  编辑

                  on_touch_down 子圈子事件:

                  from kivy.app import App
                  from kivy.uix.widget import Widget
                  from kivy.uix.floatlayout import FloatLayout
                  from kivy.lang import Builder
                  from kivy.animation import Animation
                  from kivy.properties import NumericProperty
                  
                  import math 
                  
                  kv = '''
                  <Dial>:
                      circle_id: circle_id
                      size: root.size
                      pos: 0, 0
                      canvas:
                          Rotate:
                              angle: self.angle
                              origin: self.center
                          Color:
                              rgb: 1, 0, 0
                          Ellipse:    
                              size: min(self.size), min(self.size)
                              pos: 0.5*self.size[0] - 0.5*min(self.size), 0.5*self.size[1] - 0.5*min(self.size)
                      Circle:
                          id: circle_id   
                          size_hint: 0, 0
                          size: 50, 50
                          pos: 0.5*root.size[0]-25, 0.9*root.size[1]-25
                          canvas:
                              Color:
                                  rgb: 0, 1, 0
                              Ellipse:    
                                  size: 50, 50
                                  pos: self.pos              
                  '''
                  Builder.load_string(kv)
                  
                  class Circle(Widget):
                      def on_touch_down(self, touch):
                          if self.collide_point(*touch.pos):
                              print "small circle clicked"
                  
                  class Dial(Widget):
                      angle = NumericProperty(0)
                  
                      def on_touch_down(self, touch):
                          if not self.circle_id.collide_point(*touch.pos):
                              print "big circle clicked"
                  
                          y = (touch.y - self.center[1])
                          x = (touch.x - self.center[0])
                          calc = math.degrees(math.atan2(y, x))
                          self.prev_angle = calc if calc > 0 else 360+calc
                          self.tmp = self.angle
                  
                          return super(Dial, self).on_touch_down(touch) # dispatch touch event futher
                  
                      def on_touch_move(self, touch):
                          y = (touch.y - self.center[1])
                          x = (touch.x - self.center[0])
                          calc = math.degrees(math.atan2(y, x))
                          new_angle = calc if calc > 0 else 360+calc
                  
                          self.angle = self.tmp + (new_angle-self.prev_angle)%360
                  
                      def on_touch_up(self, touch):
                          Animation(angle=0).start(self)
                  
                  
                  class DialApp(App):
                      def build(self):
                          return Dial()
                  
                  if __name__ == "__main__":
                      DialApp().run()
                  

                  这篇关于在kivy中的触摸事件上旋转对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:如何在 kivy FileChooser Python 中访问所有硬盘 下一篇:Kivy 'NoneType' 对象没有属性 'ids'

                  相关文章

                    <tfoot id='GCSnb'></tfoot>

                  1. <small id='GCSnb'></small><noframes id='GCSnb'>

                  2. <i id='GCSnb'><tr id='GCSnb'><dt id='GCSnb'><q id='GCSnb'><span id='GCSnb'><b id='GCSnb'><form id='GCSnb'><ins id='GCSnb'></ins><ul id='GCSnb'></ul><sub id='GCSnb'></sub></form><legend id='GCSnb'></legend><bdo id='GCSnb'><pre id='GCSnb'><center id='GCSnb'></center></pre></bdo></b><th id='GCSnb'></th></span></q></dt></tr></i><div id='GCSnb'><tfoot id='GCSnb'></tfoot><dl id='GCSnb'><fieldset id='GCSnb'></fieldset></dl></div>

                        <bdo id='GCSnb'></bdo><ul id='GCSnb'></ul>
                      <legend id='GCSnb'><style id='GCSnb'><dir id='GCSnb'><q id='GCSnb'></q></dir></style></legend>