2017-07-25 232 views
0

我有一个Python GUI,我正在创建w/Tkinter。这是我第一次使用GUI和Tkinter工作,所以请耐心等待!Python Tkinter保存点坐标

我想将点位置/坐标保存到变量中。在我到目前为止的代码中,我上传了一个BMP图像,当我点击图像上的某个点时,该点被标记。我想弄清楚如何将前三个点的坐标保存到变量中,我将使用这些变量创建一个与所有3个点相交的最佳拟合椭圆。我会如何去做这件事?

这里是我的代码:

from tkinter import * 
from PIL import Image, ImageTk 

class Window(Frame): 
    # Define settings upon initialization. 
    def __init__(self, master=None): 
     # parameters that you want to send through the Frame class. 
     Frame.__init__(self, master) 

     # reference to the master widget, which is the tk window 
     self.master = master 

     # with that, we want to then run init_window, which doesn't yet 
     exist 
     self.init_window() 

    # Creation of init_window 
    def init_window(self): 
     # changing the title of our master widget 
     self.master.title("GUI") 

     # allowing the widget to take the full space of the root window 
     self.pack(fill=BOTH, expand=1) 

     # creating a menu instance 
     menu = Menu(self.master) 
     self.master.config(menu=menu) 

     # create the file object) 
     file = Menu(menu) 

     # adds a command to the menu option, calling it exit, and the 
     # command it runs on event is client_exit 
     file.add_command(label="Exit", command=self.client_exit) 

     # added "file" to our menu 
     menu.add_cascade(label="File", menu=file) 

     # create the file object) 
     analyze = Menu(menu) 

     # adds a command to the menu option, calling it exit, and the 
     # command it runs on event is client_exit 
     analyze.add_command(label="Region of Interest", 
     command=self.regionOfInterest) 

     # added "file" to our menu 
     menu.add_cascade(label="Analyze", menu=analyze) 
     load = Image.open("ap41.ddr.brf.sdat.bmp") 
     render = ImageTk.PhotoImage(load) 

     # labels can be text or images 
     img = Label(self, image=render) 
     img.image = render 
     img.place(x=0, y=0) 

    def regionOfInterest(self): 
     root.config(cursor="plus") 
     canvas.bind("<Button-1>", self.imgClick) 


    def client_exit(self): 
     exit() 

    def imgClick(self, e): 
     x = canvas.canvasx(e.x) 
     y = canvas.canvasy(e.y) 
     pos.append((x, y)) 
     canvas.create_line(x - 5, y, x + 5, y, fill="red", tags="crosshair") 
     canvas.create_line(x, y - 5, x, y + 5, fill="red", tags="crosshair") 


# root window created. Here, that would be the only window, but 
# you can later have windows within windows. 
root = Tk() 

# loads exact size of image 
imgSize = Image.open("ap41.ddr.brf.sdat.bmp") 
tkimage = ImageTk.PhotoImage(imgSize) 
w, h = imgSize.size 

# creates canvas 
canvas = Canvas(root, width=w, height=h) 
canvas.create_image((w/2,h/2),image=tkimage) 
canvas.pack() 

# loads exact dimentsion from img size 
geometry = "%dx%d" % (w,h) 
root.geometry(geometry) 

# creation of an instance 
app = Window(root) 

# mainloop 
root.mainloop() 

回答

1

要保存的位置让使用列表。我们可以将这些元组存储在一个class属性中。

让我们将imgClick函数移入类中,这样我们就可以更容易地利用类属性。

然后让我们删除init_window方法作为它的冗余。

也可以添加一个计数器,当我们达到3次点击时程序停止标记地图并删除按钮绑定。

新的类属性:

self.pos = [] self.counter = 0

然后我们修改imgClick方法:

def imgClick(self, event): 

    if self.counter < 3: 
     x = canvas.canvasx(event.x) 
     y = canvas.canvasy(event.y) 
     self.pos.append((x, y)) 
     print(self.pos) 
     canvas.create_line(x - 5, y, x + 5, y, fill="red", tags="crosshair") 
     canvas.create_line(x, y - 5, x, y + 5, fill="red", tags="crosshair") 
     self.counter += 1 
    else: 
     canvas.unbind("<Button 1>") 
     root.config(cursor="arrow") 
     self.counter = 0 

你会发现那里是将打印出的self.pos保存的值print语句在分析点击过程中进行每次点击。

看看这段代码,让我知道你在想什么:

from tkinter import * 
from PIL import Image, ImageTk 

class Window(Frame): 

    def __init__(self, master=None): 
     Frame.__init__(self, master) 

     self.master = master 
     self.pos = [] 
     self.master.title("GUI") 
     self.pack(fill=BOTH, expand=1) 

     self.counter = 0 

     menu = Menu(self.master) 
     self.master.config(menu=menu) 

     file = Menu(menu) 
     file.add_command(label="Exit", command=self.client_exit) 
     menu.add_cascade(label="File", menu=file) 
     analyze = Menu(menu) 

     analyze.add_command(label="Region of Interest", 
     command=self.regionOfInterest) 

     menu.add_cascade(label="Analyze", menu=analyze) 
     load = Image.open("ap41.ddr.brf.sdat.bmp") 
     render = ImageTk.PhotoImage(load) 

     img = Label(self, image=render) 
     img.image = render 
     img.place(x=0, y=0) 

    def regionOfInterest(self): 
     root.config(cursor="plus") 
     canvas.bind("<Button-1>", self.imgClick) 


    def client_exit(self): 
     exit() 

    def imgClick(self, event): 

     if self.counter < 3: 
      x = canvas.canvasx(event.x) 
      y = canvas.canvasy(event.y) 
      self.pos.append((x, y)) 
      print(self.pos) 
      canvas.create_line(x - 5, y, x + 5, y, fill="red", tags="crosshair") 
      canvas.create_line(x, y - 5, x, y + 5, fill="red", tags="crosshair") 
      self.counter += 1 
     else: 
      canvas.unbind("<Button 1>") 
      root.config(cursor="arrow") 
      self.counter = 0 


root = Tk() 
imgSize = Image.open("ap41.ddr.brf.sdat.bmp") 
tkimage = ImageTk.PhotoImage(imgSize) 
w, h = imgSize.size 

canvas = Canvas(root, width=w, height=h) 
canvas.create_image((w/2,h/2),image=tkimage) 
canvas.pack() 

root.geometry("%dx%d"%(w,h)) 
app = Window(root) 
root.mainloop() 
+0

的代码,你提供的伟大工程!也感谢你一步一步的过程和你每一步的理由,这是相当有帮助 – FLCL

+0

@FLCL:欢迎您:)很高兴帮助。 –

+0

嘿!所以我想要做4分。我试着将它改为self.counter <4,但它仍然只让我绘制3分。我可以忽略一些东西吗 – FLCL