首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >围绕基维中心点旋转一个小部件的圆圈

围绕基维中心点旋转一个小部件的圆圈
EN

Stack Overflow用户
提问于 2022-03-06 11:00:30
回答 1查看 79关注 0票数 0

我有一些that输入,安排了圆形,我正在寻找一种方式,旋转这些小部件的整个包围绕他们的中心,就像一个轮子,拖动鼠标在其中的一部分。我试图组合一些代码,我在一些页面中发现,但不知道如何使它正常工作。

代码语言:javascript
运行
复制
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from kivy.properties import NumericProperty
from kivy.core.window import Window
import math

pi = math.pi

kv = '''
<-RotatableTI>:
    size_hint: None, None
    canvas.before:
        PushMatrix
        Rotate:
            angle: root.angle
            axis: 0,0,1
            origin: self.center

        Color:
            rgba: self.background_color
        BorderImage:
            border: self.border
            pos: self.pos
            size: self.size
            source: self.background_active if self.focus else (self.background_disabled_normal if self.disabled else self.background_normal)
        Color:
            rgba:
                (self.cursor_color
                if self.focus and not self._cursor_blink
                else (0, 0, 0, 0))
        Rectangle:
            pos: self._cursor_visual_pos
            size: root.cursor_width, -self._cursor_visual_height
        Color:
            rgba: self.disabled_foreground_color if self.disabled else (self.hint_text_color if not self.text else self.foreground_color)
    canvas.after:
        PopMatrix
        
<Dial>:
    canvas:
        Rotate:
            angle: self.angle
            origin: self.center

'''
Builder.load_string(kv)

class Circle(Widget):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            pass

class RotatableTI(TextInput):
    angle = NumericProperty(0)

class Scat(FloatLayout,Widget):
    Window.size = (600, 600)
    def __init__(self, **kwargs):
        super(Scat, self).__init__(**kwargs)
        p_x = 0
        p_y = 0
        b = 0
        r = 150
        div = 20
        pt = []
        for i in range(div):
            angle = 360.0 / (div - 1) * i
            p_x = Window.size[0] / 2 + math.cos(2 * pi / (div - 1) * i) * r
            p_y = Window.size[1] / 2 + math.sin(2 * pi / (div - 1) * i) * r
            pt.append(p_x)
            pt.append(p_y)
            if i > 0:
                self.add_widget(RotatableTI(text="hi" + str(i), size=(50, 30), pos=(p_x, p_y), angle=angle))
                
    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

        return super(Scat, 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

class DialApp(App):
    def build(self):
        return Scat()

if __name__ == "__main__":
    DialApp().run()

我想数组极性的一些文本输入在kivy,但只找到一种方式旋转文本输入与鼠标拖动在分散类。我所有的尝试都指向一个没有旋转的文本输入,只有当我键入它时,文本才会显示为旋转(没有旋转的文本输入框!),而且看起来不太好,所以我想找一种更好的方法,我可以用按钮接近解决方案,但是它们不是我想要的,只是它们的位置是极性的,而不是它们的位置。有什么方法可以让textInputs像描述的那样排列吗?

最后,我正在寻找一种方法,有3或4这个旋转包的文本输入,我想知道鼠标拖动会识别其中一个完美的选择或选择,有时错误?因为当我想用鼠标旋转一个项目时,如果选择对象边框的外部,还可以选择和旋转它。

编辑了一步,与亲爱的约翰安德森的反应,但仍然工作不好。我在第二张图片中提到下面(代码下面)的问题。

代码语言:javascript
运行
复制
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.uix.textinput import TextInput
from kivy.properties import NumericProperty
from kivy.core.window import Window
import math

pi = math.pi

kv = '''

<Scat>:
    canvas.before:
        PushMatrix
        Rotate:
            angle: self.angle
            origin: self.center
    canvas.after:
        PopMatrix
<-RotatableTI>:
    size_hint: None, None
    canvas.before:
        PushMatrix
        Rotate:
            angle: root.angle
            axis: 0,0,1
            origin: self.center

        Color:
            rgba: self.background_color
        BorderImage:
            border: self.border
            pos: self.pos
            size: self.size
            source: self.background_active if self.focus else (self.background_disabled_normal if self.disabled else self.background_normal)
        Color:
            rgba:
                (self.cursor_color
                if self.focus and not self._cursor_blink
                else (0, 0, 0, 0))
        Rectangle:
            pos: self._cursor_visual_pos
            size: root.cursor_width, -self._cursor_visual_height
        Color:
            rgba: self.disabled_foreground_color if self.disabled else (self.hint_text_color if not self.text else self.foreground_color)
    canvas.after:
        PopMatrix
        
    canvas:
        Rotate:
            angle: self.angle
            origin: self.center

'''
Builder.load_string(kv)

class Circle(Widget):
    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            pass

class RotatableTI(TextInput):
    angle = NumericProperty(0)

class Scat(FloatLayout):
    Window.size = (600, 600)
    def __init__(self, **kwargs):
        super(Scat, self).__init__(**kwargs)
        p_x = 0
        p_y = 0
        b = 0
        r = 150
        div = 20
        pt = []
        for i in range(div):
            angle = 360.0 / (div - 1) * i
            p_x = Window.size[0] / 2 + math.cos(2 * pi / (div - 1) * i) * r
            p_y = Window.size[1] / 2 + math.sin(2 * pi / (div - 1) * i) * r
            pt.append(p_x)
            pt.append(p_y)
            if i > 0:
                self.add_widget(RotatableTI(text="hi" + str(i), size=(50, 30), pos=(p_x, p_y), angle=angle))

    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

        return super(Scat, 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

class DialApp(App):
    def build(self):
        return Scat()

if __name__ == "__main__":
    DialApp().run()

除了轨道外,环旁边还有其他方向(它的中心点不是永久的,可以通过拖动来改变它),这是它意想不到的!1:https://i.stack.imgur.com/3jhQ8.png 2:https://i.stack.imgur.com/Mrpf7.png

EN

回答 1

Stack Overflow用户

发布于 2022-03-06 16:09:01

你几乎可以让轮值工作了。只需将此添加到您的kv

代码语言:javascript
运行
复制
<Scat>:
    canvas.before:
        PushMatrix
        Rotate:
            angle: self.angle
            origin: self.center
    canvas.after:
        PopMatrix

另外,

代码语言:javascript
运行
复制
class Scat(FloatLayout,Widget):

应公正:

代码语言:javascript
运行
复制
class Scat(FloatLayout):

因为FloatLayoutWidget

如果您打算使用几个Scat小部件,您应该使用点()来确定哪个实例正在被访问。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71369649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档