如何在python窗口应用程序中实现拖动功能(或缩放)?

2024-04-30 05:06:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用python中的turtle图形绘制一些简单的分形图形,并且遇到了turtle绘制超出应用程序框架的情况。我希望能够在窗口中拖动视图,以便将其居中放置在我正在绘制的分形的不同部分上,或者放大或缩小以操作视图。

Python有这个模块吗?我对python比较陌生,因为我主要是用Java编程,可以想到很多方法来处理Java和JFrames等。我对一个简单的python实现的研究是徒劳的:(如果有一个简单的解决方案可用,我不想重新发明轮子~尽管所有的方法都很受欢迎。如果我错过了这个网站上回答我问题的另一条线索,请评论。

这是我给任何感兴趣的人的分形代码。。

import turtle

t = turtle.Turtle()
t.color("white")
t.backward(450)
t.color("red")

def f2(length, depth):
    if depth == 0:
        t.forward(length)
    else:
        f2(length/2, depth -1)
        t.left(135)
        f2(length/8, depth -1)
        t.right(90)
        f2(length/8, depth -1)
        t.right(90)
        f2(length/8, depth -1)
        t.right(90)
        f2(length/8, depth -1)
        t.left(135)
        f2(length/2, depth -1)


f2(400, 4)

Tags: 方法right框架视图应用程序图形绘制java
2条回答

这在我的编程课上出现过很多次。我的解决方案也有点复杂,但它为我正确地添加了滚动条(不幸的是,随着屏幕大小的增长,滚动条似乎不会自动为我添加),而且我不需要自己跟踪边界框。

设置如下:

import turtle
import Tkinter

root = Tkinter.Tk()
START_WIDTH = 700 
START_HEIGHT = 700 

frame = Tkinter.Frame(root, width=START_WIDTH, height=START_HEIGHT)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)

xscrollbar = Tkinter.Scrollbar(frame, orient=Tkinter.HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=Tkinter.E+Tkinter.W)

yscrollbar = Tkinter.Scrollbar(frame, orient=Tkinter.VERTICAL)
yscrollbar.grid(row=0, column=1, sticky=Tkinter.N+Tkinter.S)

canvas = Tkinter.Canvas(frame, width=START_WIDTH, height=START_HEIGHT,
                        scrollregion=(0, 0, START_WIDTH, START_HEIGHT),
                        xscrollcommand=xscrollbar.set,
                        yscrollcommand=yscrollbar.set)

canvas.grid(row=0, column=0, sticky=Tkinter.N+Tkinter.S+Tkinter.E+Tkinter.W)

xscrollbar.config(command=canvas.xview)
yscrollbar.config(command=canvas.yview)

frame.pack()

turt = turtle.RawTurtle(canvas)

现在您可以像使用其他创建的海龟对象一样使用turt。每次你想确保你可以滚动到所有已绘制的内容时,运行

canvas.config(scrollregion=canvas.bbox(Tkinter.ALL))

有关自定义画布和滚动条的文档,请参见http://effbot.org/zone/tkinter-scrollbar-patterns.htmhttp://effbot.org/tkinterbook/canvas.htm

有几种方法可以做到这一点,我有需要前一段时间,不幸的是,我不认为有一个非常简单的方法。但是,可以使用以下命令显式设置画布的大小(如果画布大于所示大小,则会添加滚动条):

screen.screensize(width, height)

这通常作用于海龟屏幕而不是海龟本身,因此要获得屏幕,您需要调用:

t.getscreen()

有一种更复杂但更有效的方法,你可以将海龟分为子类来跟踪它的边界框(在每个轴上移动到的最远点),然后根据它更新屏幕大小,但它的投资更多,如果有人问我,我会发布详细信息。

编辑:添加子类化方法的详细信息 首先我们对海龟进行子类化,这样它就有一个名为bbox的属性,这是一个列表,每次我们移动海龟时都会更新它。

class MyTurtle(turtle.RawTurtle): # here we subclass the turtle to allow us to call statusbar updates after each movement
    def __init__(self, canvas):
        turtle.RawTurtle.__init__(self, canvas)
        self.bbox = [0,0,0,0]

    def _update_bbox(self): # keep a record of the furthers points visited
        pos = self.position()
        if pos[0] < self.bbox[0]:
            self.bbox[0] = pos[0]
        elif pos[0] > self.bbox[2]:
            self.bbox[2] = pos[0]
        if pos[1] < self.bbox[1]:
            self.bbox[1] = pos[1]
        elif pos[1] > self.bbox[3]:
            self.bbox[3] = pos[1]

    def forward(self, *args):
        turtle.RawTurtle.forward(self, *args)
        self._update_bbox()

    def backward(self, *args):
        turtle.RawTurtle.backward(self, *args)
        self._update_bbox()

    def right(self, *args):
        turtle.RawTurtle.right(self, *args)
        self._update_bbox()

    def left(self, *args):
        turtle.RawTurtle.left(self, *args)
        self._update_bbox()

    def goto(self, *args):
        turtle.RawTurtle.goto(self, *args)
        self._update_bbox()

    def setx(self, *args):
        turtle.RawTurtle.setx(self, *args)
        self._update_bbox()

    def sety(self, *args):
        turtle.RawTurtle.sety(self, *args)
        self._update_bbox()

    def setheading(self, *args):
        turtle.RawTurtle.setheading(self, *args)
        self._update_bbox()

    def home(self, *args):
        turtle.RawTurtle.home(self, *args)
        self._update_bbox()

然后我们为海龟制作一张画布:

cv = turtle.ScrolledCanvas(root)

然后我们把画布变成一个高领毛衣:

screen = turtle.TurtleScreen(cv)

我们在屏幕上创建一个海龟:

turt = MyTurtle(screen)

现在乌龟可以作为普通乌龟使用(移动、颜色、形状、速度等) 如果乌龟超出了屏幕的界限,你可以调用:

min_x, min_y, max_x, max_y = turt.bbox # get the furthest points the turtle has been
width = max((0-min_x),(max_x)) * 2 + 100 # work out what the maximum distance from 0,0 is for each axis
height = max((0-min_y),(max_y)) * 2 + 100 # the 100 here gives us some padding between the edge and whats drawn
screen.screensize(width, height)

请注意,上面的代码对源代码的重新调整大小与screen方法所允许的大小相同,但是,如果深入研究并将bbox应用于画布本身,则可以使其仅围绕画布上的项重新调整大小。

相关问题 更多 >