我有一个简单的ModalView并且它的size(640,426)。我的窗口的大小是(1366,732)。我的屏幕分辨率是(1366,768)。当我单击ModalView的左上角时,我得到了一些东西就像363,690。这是我从窗口本身获取的触摸坐标。但是我想以某种方式将此值转换为本地小部件空间,以便触摸左上角可以获得坐标(0,0)而不是(363,690)。我想尝试的是,对于那些感兴趣的人,是使用用户绘制的框来裁剪图像。绘制框不是问题,问题在于获取这些边界并将其转移到图像的坐标。

注意:我读到有关to_local(),to_parent(),to_window()的信息,但这些功能根本无法正常工作...出于某种原因,也许我错过了那里的事情,非常感谢您的帮助

这是类似于我的用例的代码,但已剥离

from kivy.app import App
from kivy.uix.modalview import ModalView
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.uix.label import Label

class CropBounds(ModalView):

    def __init__(self, **kwargs):
        super(CropBounds, self).__init__(**kwargs)
        self.to_crop = True
        self.size = (400,400)
        print('Center: ',self.center)
        print('Size: ',self.size)
        print('Window Center: ',Window.center)
        print('Window Size:(',Window.width,',',Window.height,')')

    def on_touch_down(self, touch):
        self.canvas.clear()

        if self.collide_point(*touch.pos) and self.to_crop:
            with self.canvas:

                    self.start_x = touch.x
                    self.start_y = touch.y
                    touch.ud['area'] = Line(points=(touch.x, touch.y, touch.x, 400,touch.x, touch.y,touch.x, touch.y, touch.x, touch.y))
                    print("Pos: ",touch.pos)
                    print(touch.x,touch.y)
        return True
    return MainWindow().on_touch_down(touch)

class GalleryWindow(BoxLayout):
    def __init__(self, **kwargs):
        super(GalleryWindow, self).__init__(**kwargs)

        self.add_widget(Button(text='crop',size_hint=(1,None),size=(None,40),on_release=self.crop_img))
    def crop_img(self):
        bounds = CropBounds()
        bounds.open()

class GalleryApp(App):
    def build(self):
        return GalleryWindow()

if __name__=='__main__':
    GalleryApp().run()

最佳答案

ModalView坐标中减去touch位置确实有效。我认为您对ModalView的大小和位置感到困惑。编写代码的方式,ModalView的大小和位置与GalleryWindow相同(请注意,默认的size_hint为(1.0,1.0))。因此,要使ModalViewGalleryWindow中的坐标之间没有任何区别,您需要将size_hint更改为ModalView

更正代码中的许多错误之后(使其运行)。我进行了一些更改以演示ModalView的位置和触摸的位置。

这是代码:

from kivy.app import App
from kivy.core.window import Window
from kivy.graphics.vertex_instructions import Line
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.modalview import ModalView
from kivy.uix.button import Button

class CropBounds(ModalView):

    def __init__(self, **kwargs):
        super(CropBounds, self).__init__(**kwargs)
        self.to_crop = True
        self.size_hint = (None, None)  # without this, the size below has no effect
        self.size = (400,400)
        print('Center: ',self.center)
        print('Size: ',self.size)
        print('Window Center: ',Window.center)
        print('Window Size:(',Window.width,',',Window.height,')')

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos) and self.to_crop:
            self.canvas.clear()
            with self.canvas:
                # plot the boundary of the ModalView
                Line(points=[self.pos[0], self.pos[1],
                                        self.pos[0], self.pos[1] + self.height,
                                        self.pos[0] + self.width, self.pos[1] + self.height,
                                        self.pos[0] + self.width, self.pos[1],
                                        self.pos[0], self.pos[1]])
                # plot a line from the touch point to the pos of the ModalView
                Line(points=[self.pos[0], self.pos[1], touch.x, touch.y])

            # calculate touch minus position of ModalView
            touch_in_modal = (touch.x - self.pos[0], touch.y - self.pos[1])
            print('touch : ' + str(touch.pos) + ', touch in modal: ' + str(touch_in_modal))
            return True
        #return MainWindow().on_touch_down(touch)

class GalleryWindow(BoxLayout):
    def __init__(self, **kwargs):
        super(GalleryWindow, self).__init__(**kwargs)
        self.add_widget(Button(text='crop',size_hint=(1,None),size=(40,40),on_release=self.crop_img))
    def crop_img(self, *args):
        bounds = CropBounds()
        bounds.open()


class GalleryApp(App):
    def build(self):
        return GalleryWindow()

if __name__=='__main__':
    GalleryApp().run()


如果要查看代码中发生了什么,只需注释size_hint行。

另外,当我们要求您发布MCV示例时,请尝试运行您发布的内容。如果必须先调试您的示例,然后才能了解问题所在,那么您将不会得到很多答复。

关于python - 如何将Kivy触摸坐标转换为小部件空间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52917706/

10-12 22:37