如何在Kivy中使用等距/正交视图?

时间:2019-02-25 21:56:57

标签: python-3.x button kivy orthogonal

下图是带有按钮的GridLayout 10 x 10。

https://i.stack.imgur.com/yZsJI.png

我想在等轴测/正交二维视图中创建相同的网格。

这意味着每个按钮而不是正方形,可能像菱形,如下图所示:

enter image description here

我该怎么做?

1 个答案:

答案 0 :(得分:5)

我认为您实际上不能对kivy UIX小部件进行3D旋转,但是可以进行2D旋转和缩放。这是一个Appbuild()方法执行的示例:

from kivy.app import App
from kivy.graphics.context_instructions import PushMatrix, Rotate, Scale, PopMatrix
from kivy.properties import BooleanProperty
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
import numpy as np


def matrixToNumpy(mat):
    a = []
    for i in range(4):
        b = []
        for j in range(4):
            b.append(mat[i*4+j])
        a.append(b)
    npmat = np.mat(a)
    return npmat


class MyButton(Button):

    def on_touch_down(self, touch):
        if not self.parent.touched:
            self.parent.touched = True
            if self.parent.mat is None:
                scale = matrixToNumpy(self.parent.sca.matrix)
                rotate = matrixToNumpy(self.parent.rot.matrix)
                self.parent.mat = np.matmul(rotate, scale)
                self.parent.inv_mat = self.parent.mat.I
            npTouch = np.mat([touch.x, touch.y, 0, 1.0])
            convTouch = np.matmul(npTouch, self.parent.inv_mat)
            touch.x = convTouch[0,0]
            touch.y = convTouch[0,1]
        return super(MyButton, self).on_touch_down(touch)

    def on_touch_up(self, touch):
        self.parent.touched = False
        return super(MyButton, self).on_touch_up(touch)


class MyGridLayout(GridLayout):
    touched = BooleanProperty(False)

    def __init__(self, **kwargs):
        super(MyGridLayout, self).__init__(**kwargs)
        self.mat = None
        self.inv_mat = None


class MyApp(App):
    def build(self):
        layout = MyGridLayout(cols=10)
        with layout.canvas.before:
            PushMatrix()
            layout.sca = Scale(1.0, 0.5, 1.0)
            layout.rot = Rotate(angle=45, axis=(0,0,1), origin=(400,300,0))
        with layout.canvas.after:
            PopMatrix()
        for i in range (1, 101):
            layout.add_widget(MyButton(text=str(i)))
        return layout

MyApp().run()

我怀疑通过巧妙地应用这两个kivy.graphics.context_instructions,您可以模拟所需的内容。 PushMatrix()PopMatrix()ScaleRotate的作用限制为MyGridLayout。您应该能够使用layout.scalayout.rot引用来调整这些值。

最初回答后,我注意到Buttons看起来不错,但不再起作用。我添加了一些代码来解决该问题。所有numpy矩阵填充只是为了使鼠标按下位置与MyGridLayout处于相同坐标。不幸的是,Kivy事件不会自动考虑应用Canvas缩放和旋转,因此需要附加代码。

这是它的样子: This is the resulting button array