Как преобразовать сенсорные координаты Kivy в пространство виджетов - PullRequest
0 голосов
/ 21 октября 2018

у меня есть простое ModalView, а size равно (640,426). Размер моего окна (1366,732). Разрешение моего экрана (1366,768). Когда я нажимаю в верхнем левом углу ModalView,я получаю что-то вроде 363,690. Какие мои сенсорные координаты взяты из самого окна. Однако я хотел бы как-то преобразовать это значение в локальное пространство виджета, чтобы при касании верхнего левого угла я получил координату (0,0) вместо (363,690). Это возможно с помощью kivy или любым другим способом. Что я пытаюсь сделать, для тех, кто заинтересован, это обрезать изображение, используя нарисованную пользователем рамку. Рисовать рамку не проблема, проблема в том, чтобы получить эти границы иперенося их в координаты изображения.

Примечание: я читал о 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()

1 Ответ

0 голосов
/ 24 октября 2018

Вычитание позиции ModalView из координат touch работает.Я думаю, вы запутались в размерах и положении вашего ModalView.При написании вашего кода ModalView имеет тот же размер и положение, что и ваш GalleryWindow (напомним, что по умолчанию size_hint (1.0, 1.0)).Таким образом, для того, чтобы между координатами в ModalView и GalleryWindow была какая-либо разница, вам нужно изменить 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, попробуйте выполнить то, что вы публикуете.Если нам придется отладить ваш пример, прежде чем мы увидим, в чем ваша проблема, вы не получите много ответов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...