我试图拥有它,以便可以使用旋转框调整 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/