2016-09-01 5 views
1

私は問題を正しく説明したいと思う。 以下の例では、キャンバスに定義された2つのイメージを移動できます。問題は、画像の上にキャンバスでも定義された矩形が欲しいということです。 .tag_raiseを使用してそれを行うと、マウスドラッグによってトリガーされるイベントは、画像ではなく長方形によってトリガーされます。マウスイベントの長方形ウィジェットの下のTkinterバインドウィジェット

私はbing_classを使ってみましたが、うまくいきませんでした。私は矩形のための別のキャンバスを定義しようとしましたが、それはメインキャンバスをオーバーレイする必要があり、私は固まってしまいました。

矩形を一番上に置いてマウスのドラッグイベントにバインドする方法を教えてください。

import Tkinter as tk # for Python2 
import PIL.Image, PIL.ImageTk 

win = tk.Tk() 
canvas = tk.Canvas(win, height = 500, width = 500) 

#Create a rectangle with stipples on top of the images 
rectangle = canvas.create_rectangle(0, 0, 400, 300, fill = "gray", stipple = "gray12") 

#Create two images 
SPRITE = PIL.Image.open("image.jpg") 
imagePIL = SPRITE.resize((100, 100)) 
imagePI = PIL.ImageTk.PhotoImage(imagePIL) 
image1 = canvas.create_image(100, 100, image = imagePI, tags = "image") 
image2 = canvas.create_image(200, 200, image = imagePI, tags = "image") 

#Callback 
# Here I select image1 or image2 depending on where I click, and 
# drag them on the canvas. The problem is when I put the rectangle 
# on top using tag_raise (see below). 
def callback(event): 
    id = canvas.find_withtag(tk.CURRENT) 
    canvas.coords(id, (event.x, event.y)) 

#Binding 
canvas.bind("<B1-Motion>", callback) 
#Place the rectangle on top of all 
canvas.pack() 

# This is the problem. I want to have the rectangle on top and be able to use the callback 
#canvas.tag_raise(rectangle) 

canvas.mainloop() 

SOLUTION:私は次のコードでNehalの答えを強化。彼の答えには不具合があり、画像を切り替えることができた。私の拡張では、キャンバス上でイメージをドラッグしている間に、同じイメージがドラッグされるように、イメージごとにロックを格納することで解決します。たとえば移動したときimage1 over image2私はimage1がimage2上で完全に動かないことに気付きました。私はこれを行うにはtkinter特定の方法を知らない

import Tkinter as tk # for Python2 
import PIL.Image, PIL.ImageTk 

win = tk.Tk() 
canvas = tk.Canvas(win, height = 500, width = 500) 

#Create a rectangle with stipples on top of the images 
rectangle = canvas.create_rectangle(0, 0, 400, 300, fill = "gray", stipple = "gray12") 

#Create two images 
SPRITE = PIL.Image.open("image.jpg") 
imagePIL = SPRITE.resize((100, 100)) 
imagePI = PIL.ImageTk.PhotoImage(imagePIL) 
image1 = canvas.create_image(100, 100, image = imagePI, tags = "image") 
image2 = canvas.create_image(200, 200, image = imagePI, tags = "image") 
images = [image1, image2] 
locks = [True, True] 

def getImage(x, y): 
    for image in images: 
     curr_x, curr_y = canvas.coords(image) 
     x1 = curr_x - imagePI.width()/2 
     x2 = curr_x + imagePI.width()/2 
     y1 = curr_y - imagePI.height()/2 
     y2 = curr_y + imagePI.height()/2 
     if (x1 <= x <= x2) and (y1 <= y <= y2): 
      return image 
#Callback 
# Here I select image1 or image2 depending on where I click, and 
# drag them on the canvas. 
def callback(event): 
    id = getImage(event.x, event.y) 
    if id: 
     if locks[images.index(id)] is False: #Hold on to the image on which I originally clicked 
      canvas.coords(id, (event.x, event.y)) 

def mouseClick(event): 
    id = getImage(event.x, event.y) 
    if id: 
     locks[images.index(id)] = False 
    print(locks) 

def mouseRelease(event): 
    id = getImage(event.x, event.y) 
    if id: 
     locks[images.index(id)] = True 
    print(locks) 
#Binding 
canvas.bind("<ButtonPress-1>", mouseClick)  #unlock the image to move it 
canvas.bind("<ButtonRelease-1>", mouseRelease) #lock the image 
canvas.bind("<B1-Motion>", callback) 
#Place the rectangle on top of all 
canvas.pack() 

# This was the original problem 
canvas.tag_raise(rectangle) 

canvas.mainloop() 

答えて

2

、しかし、あなたは最も近い画像の座標を取得し、一緒にプレイしようとすることができます。このように:良いアイデアだ

import Tkinter as tk # for Python2 
import PIL.Image, PIL.ImageTk 

win = tk.Tk() 
canvas = tk.Canvas(win, height = 500, width = 500) 

#Create a rectangle with stipples on top of the images 
rectangle = canvas.create_rectangle(0, 0, 400, 300, fill = "gray", stipple = "gray12") 

#Create two images 
SPRITE = PIL.Image.open("image.jpg") 
imagePIL = SPRITE.resize((100, 100)) 
imagePI = PIL.ImageTk.PhotoImage(imagePIL) 
image1 = canvas.create_image(100, 100, image = imagePI, tags = "image") 
image2 = canvas.create_image(200, 200, image = imagePI, tags = "image") 
images = [image1, image2] 

def getImage(x, y): 
    for image in images: 
     curr_x, curr_y = canvas.coords(image) 
     x1 = curr_x - imagePI.width()/2 
     x2 = curr_x + imagePI.width()/2 
     y1 = curr_y - imagePI.height()/2 
     y2 = curr_y + imagePI.height()/2 
     if (x1 <= x <= x2) and (y1 <= y <= y2): 
      return image 
#Callback 
# Here I select image1 or image2 depending on where I click, and 
# drag them on the canvas. The problem is when I put the rectangle 
# on top using tag_raise (see below). 
def callback(event): 
    id = getImage(event.x, event.y) 
    if id: 
     canvas.coords(id, (event.x, event.y)) 

#Binding 
canvas.bind("<B1-Motion>", callback) 
#Place the rectangle on top of all 
canvas.pack() 

# This is the problem. I want to have the rectangle on top and be able to use the callback 
canvas.tag_raise(rectangle) 

canvas.mainloop() 

enter image description here

+0

はあなたに感謝します!しかし、1つの問題があります。一方の画像を他方の画像に近づけてドラッグすると、もう一方の画像も一緒に移動することができます。現在の画像のIDを保存し、マウスボタンを離したときにキャンセルすると、この不具合を回避することができます。 – aless80

+0

提案を強化して投稿に追加しました。ありがとうございました! – aless80

+0

@ aless80あなたはそれを素敵に修正! :) –

関連する問題