python - Tkinter 可调整大小的对象 Python Canvas

标签 python class canvas tkinter

我试图拥有它,以便可以使用旋转框调整 Tkinter Canvas 上的多个对象的大小/位置,并将旋转框中的值用作原始坐标的乘数。让事情变得稍微复杂一些的是,旋转框默认情况下不可见,它位于顶级窗口中,按下按钮即可打开该窗口。

总结:
我需要使用旋转框值作为乘数(或其他方式)来更改 Canvas 上对象的坐标,旋转框本身位于顶级窗口中,并将这些更改“实时”显示在 Canvas 上。

对于上下文,我已经包含了负责设置对象等的关键外围代码。

UI模块的基本部分:


import Canvas_1 (module for drawing shapes)

root=Tk()

#root geometry, title set up
#UI then commands set up
canvasBlank=Canvas(root, width... etc) #Blank canvas that is drawn at start
canvasBlank.grid(row... etc)
canvasBlank.bind('Button-3', rightclickcanvas) #Right click function that opens a popup for canvas options
#Other misc commands, I'm using a menubar with drop down options over actual Tk.Buttons
#'New' option in menubar has Command to create objects in UI like:

def createObject():
     Objects=MyObjects(root, width... etc)
     Objects.grid(row... etc) #Same as layout for canvasBlank
     Objects.bind('<Button-3>', rightclickcanvas)
     Objectslist.append(Objects) #Stop garbage disposal and makes sure the canvas displays

-MyObjects 类(在单独的模块中)的形式类似于:

from Coordinate_Generator import * #imports coordinate arrays

class MyObjects(tk.Canvas)
    def __init__(self, master, **kw)
        tk.Canvas.__init__(self, master, **kw)
        self.create_oval(coordinates[0], dimensions[0], fill... etc)
        self.create_oval(coordinates[1], dimensions[1], fill... etc)
#A series of bindings relating to moving objects under mouse clicks

坐标是使用任意值“a”确定的。我尝试乘以: 定标器=[] a=70*缩放器[-1]

这种方法似乎也不起作用,如果起作用,也意味着可能会在彼此之上绘制大量 Canvas ,这是我想避免的。我希望这能更清楚地展示我需要尝试和使用的方法。我已经使用给出的建议编写了一些代码,虽然它可能对我计划的程序的另一部分有用,但它并没有完全实现我所追求的目标。所以我拼凑了这个“演示”,也许是为了说明我正在尝试做的事情。

工作代码(解决方案)

from Tkinter import *
from numpy import *
import Tkinter as tk

scale=1

class Demonstrator:

   def __init__(self, master=None): 
      global full_coordinates, dimensions, scale
      self.master=master
      self.master.title( "Demonstrator 2")
      self.master.grid()
      self.master.rowconfigure(0, weight=1)
      self.master.columnconfigure(0, weight=1)

      self.canvas = Canvas(self.master, width=300, height=300, bg='grey')
      self.canvas.grid(row=0, rowspan=3, column=0)
      self.canvas.create_rectangle(full_coordinates[0],dimensions[0], activefill='blue', fill='red')
      self.canvas.create_rectangle(full_coordinates[1],dimensions[1], activefill='blue', fill='red')
      self.canvas.create_line(full_coordinates[0],full_coordinates[1], fill='red')

      a=9*scale
      Originx=10
      Originy=35
      coordinates1=[]
      coordinates2=[]

      x,y,i=Originx,Originy,1
      x1,y1,i=Originx,Originy,1

      while len(coordinates1)<=25:
       coordinates1.append((x,y))
       coordinates2.append((x1,y1))

       i+=1
       if i % 2 == 0:
            x,y=x+a,y
            x1,y1=x1,y1+a
       else:
            x,y=x,y+a
            x1,y1=x1+a,y1

       full_coordinates=list(set(coordinates1+coordinates2))
       b=array(full_coordinates)
       k=b+10
       dimensions=k.tolist()

class Settings:
    def __init__(self, parent):

        top = self.top = tk.Toplevel(parent)
        self.top.title('Settings')

        self.spinbox_Label= tk.Label(top, text='Change Scale Factor?')
        self.spinbox_Label.grid(row=0, column=0, columnspan=2)

        self.spinbox_Label= tk.Label(top, width=30, text='Scale factor:')
        self.spinbox_Label.grid(row=1, column=0)

        self.spinbox= tk.Spinbox(top, from_=1, to=10, increment=0.1, command=self.change)
        self.spinbox.grid(row=1, column=1)


    def change(self):
        global scale
        scale=float(self.spinbox.get())
        MG=Demonstrator(root) #This just generates a new Demonstrator with original coordinates

def onClick():
    inputDialog = Settings(root)
    root.wait_window(inputDialog.top)

def onClick2():
    print scale

class coords:
    global full_coordinates, dimensions, scale
    print scale
    a=9*scale
    Originx=10
    Originy=35
    coordinates1=[]
    coordinates2=[]

    x,y,i=Originx,Originy,1
    x1,y1,i=Originx,Originy,1

    while len(coordinates1)<=25:
       coordinates1.append((x,y))
       coordinates2.append((x1,y1))

       i+=1
       if i % 2 == 0:
            x,y=x+a,y
            x1,y1=x1,y1+a
       else:
            x,y=x,y+a
            x1,y1=x1+a,y1

       full_coordinates=list(set(coordinates1+coordinates2))
       b=array(full_coordinates)
       k=b+10
       dimensions=k.tolist()    




root=Tk()
root.minsize=(700,700)
root.geometry=('600x600')
MG=Demonstrator(root)
mainButton2 = tk.Button(root, width=20, text='Print "scale"', command=onClick2)
mainButton2.grid(row=1, column=1)
mainButton = tk.Button(root, width=20, text='Settings', command=onClick)
mainButton.grid(row=2, column=1)
root.mainloop()
mainButton2.grid(row=1, column=1)
mainButton = tk.Button(root, width=20, text='Settings', command=onClick)
mainButton.grid(row=2, column=1)
root.mainloop()

问题:
使用旋转框更改 Canvas 上对象的大小(通过更改坐标)的最佳方法是什么?
我希望这足以提供信息,当然如果有必要我可以提供更多信息。我还提前为这个问题的格式道歉,我对此很陌生:)
(已添加解决方案) 任何帮助都是极好的。干杯。
标记

最佳答案

该解决方案没有什么特别之处。您只需为调整 Canvas 项目坐标的旋转框定义一个回调(可以使用 Canvas 的 coords 方法来完成)。

首先,您可能想要创建一个字典来包含每个项目的基本宽度和高度。该字典的键也可以是与 Canvas 项关联的标签。例如:

self.base_dimensions = {
    "obj1": (10,10),
    "obj2": (20,20),
    ...
}

接下来,使用这些键作为标签在 Canvas 上创建项目。例如:

...
self.canvas.create_rectangle(..., tags=("obj1",))
self.canvas.create_rectangle(..., tags=("obj2",))
...

最后,您可以使用相同的键将旋转框小部件保存在字典中(这样您就可以将旋转框与 Canvas 对象相关联),并为旋转框分配一个回调来调整大小。例如:

self.spinbox = {
    "obj1": tk.Spinbox(..., command=lambda self.do_resize("obj1")),
    "obj2": tk.Spinbox(..., command=lambda self.do_resize("obj2")),
    ...
}

给定一个标签,您的回调可以使用它来获取对 spinbox 小部件的引用并获取其值,然后使用该标签告诉 Canvas 对象要调整哪个项目的大小。例如:

def do_scale(self, tag):
    factor = int(self.spinbox[tag].get())
    (width, height) = self.default[tag]
    (x0,y0,x1,y1) = self.canvas.coords(tag)
    width = factor * width
    height = factor * height
    x1 = x0 + width
    y1 = y0 + height
    self.canvas.coords(tag, x0,y0,x1,y1)

当然,组织数据的方法有无数种;我所展示的不是最好的方法也不是唯一的方法。它甚至可能不适用于您组织代码的方式。无论您选择什么,都可以归结为能够从旋转框中获取值并使用它来调整 Canvas 项目的坐标。

关于python - Tkinter 可调整大小的对象 Python Canvas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12254995/

相关文章:

JavaFX:通过点击两次鼠标在 Canvas 上绘制一个矩形

Python 哈希表和链表。如何从 HashTable 类打印列表

python - 理解Python中的父/子类

javascript - HTML 5 Canvas 动画 - 对象闪烁

javascript - 在 Canvas 上创建线条动画

c++ - cin 使用新 C++ 的用户的字符数组

Python Pillow - ValueError : Decompressed Data Too Large

python - 根据模板编号将数字格式化为字符串

python - DataFrame - 来自嵌套字典的表中的表

c++ - 如何使用字符串返回一个指向对象的唯一指针 vector 的迭代器来查找对象?