Найти - Пользователи
Полная версия: Одновременное движение объектов в разных направлениях
Начало » Python для новичков » Одновременное движение объектов в разных направлениях
1
Konstantin1984+
Необходимо, чтобы несколько объектов посредством одной функции, а не нескольких функций соответствующих количеству объектов, независимо друг от друга двигались по направлению к курсору (в разные точки). В данный момент они движутся в одном направлении. Прошу просветить, как сделать правильно.
 from tkinter import*
root=Tk()
root.title ('Проверка')
c = Canvas(width=2250, height=2250,bg='green')
c.pack()
c.create_polygon(110, 110, 110, 160, 150, 135,tag='треугольник')
c.create_rectangle(180,10,280,80, fill='black',tag='прямоугольник')
def opred(event):
    c=event.widget
    coord_x=c.canvasx(event.x)
    coord_y=c.canvasy(event.y)
    item=c.find_closest(coord_x,coord_y)
    predmet_kortezh=c.gettags(item)
    global predmet
    predmet=' '.join(predmet_kortezh[:-1])
coord_x = None
coord_y = None
def sdvig(event):
    global coord_x
    global coord_y
    x = root.winfo_pointerx()
    y = root.winfo_pointery()
    c=event.widget
    coord_x=c.canvasx(event.x)
    coord_y=c.canvasy(event.y)
    def sdvig2():
        if c.bbox(predmet)[2]<coord_x and c.bbox(predmet)[3]<coord_y:
            c.move(predmet,1,1)
            c.update()
        c.after(10,sdvig2)        
    c.after(10,sdvig2)
c.bind("<ButtonPress-1>", opred)
c.bind('<Button-3>',sdvig)
root.mainloop()
Alex.Pro.
Konstantin1984+
по направлению к курсору (в разные точки)
Непонятно. У вас курсор находится в одной точке? Или у вас несколько курсоров в разных точках? Об'екты должны двигаться к одному курсору или к нескольким разным точкам?
Konstantin1984+
Видимо, несовсем правильно выразился. Для объектов задаются разные точки назначения, но в настоящий момент получается так, что двигаются они в одном направлении (к одной и той же точке, последней из заданных).
Alex.Pro.
Konstantin1984+
Для объектов задаются разные точки назначения, но в настоящий момент двигаются они в одном направлении (к точке последней из заданных).
Так стало немножко понятнее. Теперь об'ясните, как задаются точки для каждого об'екта?
xam1816
 import tkinter as tk
class DraggableCanvas(tk.Canvas):
    def __init__(self, master, **kwargs):
        super().__init__(master, **kwargs)
        self.bind("<ButtonPress-1>", self.on_press_1)
        self.bind("<ButtonPress-3>", self.on_press_3)
        self._drag_data = {"x": 0, "y": 0, "item": None}
        # Пример объектов
        self.create_oval(50, 50, 100, 100, fill="red", tags="draggable")
        self.create_rectangle(150, 150, 200, 200, fill="blue", tags="draggable")
    def on_press_1(self, event):
        # Найти объект под курсором
        items = self.find_overlapping(event.x, event.y, event.x, event.y)
        item = None
        for obj in items[::-1]:  # в обратном порядке — верхние объекты первыми
            if "draggable" in self.gettags(obj):
                item = obj
                break
        # Проверить, можно ли перетаскивать
        if item:
            self._drag_data["item"] = item
            self._drag_data["x"] = event.x
            self._drag_data["y"] = event.y
    def on_press_3(self, event):
        item = self._drag_data["item"]
        if item:
            dx = event.x - self._drag_data["x"]
            dy = event.y - self._drag_data["y"]
            self.move(item, dx, dy)
            self._drag_data["x"] = event.x
            self._drag_data["y"] = event.y
        self._drag_data["item"] = None
if __name__ == "__main__":
    root = tk.Tk()
    root.title("Перетаскивание объектов")
    canvas = DraggableCanvas(root, width=400, height=300, bg="white")
    canvas.pack(fill="both", expand=True)
    root.mainloop()
Konstantin1984+
Программа xam1816 предполагает одиночное молниеносное смещение выделенного объекта в назначенную мышью точку, при этом для последующего смещения нужно снова нажимать на объект. Я предполагаю более сложную задачу, сначала левой кнопкой мыши выделяется объект, потом ему задается правой кнопкой точка, к которой двигаться, и объект постепенно смещается, в процессе можно задавать новые точки (правой кнопкой мыши) и объект будет продолжать движение. Проблема в том, чтобы два (или более объектов, в примере их два, но программа должна работать при любом количестве объектов) объекта двигались одновременно и независимо друг от друга (выделяем один объект левой кнопкой мыши и задаем направление правой, повторяем тоже со вторым, и они двигаются одновременно).
xam1816
  
import tkinter as tk
import math
class DraggableCanvas(tk.Canvas):
    def __init__(self, master, **kwargs):
        super().__init__(master, **kwargs)
        self.bind("<ButtonPress-1>", self.on_left_press)
        self.bind("<ButtonPress-3>", self.on_right_press)
        self.bind("<ButtonRelease-3>", self.on_right_release)
        self.selected_item = None
        self.move_targets = {}     # item_id -> (target_x, target_y)
        self.moving_items = set()  # item_id -> currently animating
        # Пример объектов
        self.create_oval(50, 50, 100, 100, fill="red", tags="draggable")
        self.create_rectangle(150, 150, 200, 200, fill="blue", tags="draggable")
    def on_left_press(self, event):
        items = self.find_overlapping(event.x, event.y, event.x, event.y)
        for item in reversed(items):
            if "draggable" in self.gettags(item):
                self.selected_item = item
                break
    def on_right_press(self, event):
        if self.selected_item:
            self.move_targets[self.selected_item] = (event.x, event.y)
    def on_right_release(self, event):
        if self.selected_item and self.selected_item in self.move_targets:
            if self.selected_item not in self.moving_items:
                self.moving_items.add(self.selected_item)
                self.animate_move(self.selected_item)
    def animate_move(self, item_id, speed=1):
        if item_id not in self.move_targets:
            self.moving_items.discard(item_id)
            return
        target_x, target_y = self.move_targets[item_id]
        coords = self.bbox(item_id)
        if coords is None:
            self.moving_items.discard(item_id)
            return
        x0 = (coords[0] + coords[2]) / 2
        y0 = (coords[1] + coords[3]) / 2
        dx = target_x - x0
        dy = target_y - y0
        distance = math.hypot(dx, dy)
        if distance < 5:
            self.moving_items.discard(item_id)
            return
        step_x = dx / distance * speed
        step_y = dy / distance * speed
        self.move(item_id, step_x, step_y)
        self.after(20, lambda: self.animate_move(item_id, speed))
if __name__ == "__main__":
    root = tk.Tk()
    root.title("Плавное перемещение объектов")
    canvas = DraggableCanvas(root, width=500, height=400, bg="white")
    canvas.pack(fill="both", expand=True)
    root.mainloop()

исправил ускорение при повторном нажатии
Konstantin1984+
Интересный вариант. Буду осмыслять. Спасибо.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB