简体   繁体   中英

Stop Tkinter from opening a second window when importing drawing function

I am having an issue that I am having trouble resolving. I am making a Python interface with Tkinter that allows the user to draw a predefined figure with some parameters (number and length). The predefined figure function "tree" is in a second python file. The app runs fine if the "tree" function is in the main python file ie everything draws in one window. If I put the figure "tree" in a second python file (figures.py) and try to import it the app will create a second window and the tree figure will draw there instead of the intended main window. How can I reference and import the function so that it draws in the main app window. Thanks!

main python file

import turtle
import tkinter
from tkinter.ttk import *
import figures

# Main function is defined.
def main():
    # Set root and create canvas
    root = tkinter.Tk()
    root.title("Draw")
    canvas = tkinter.Canvas(root, width=800, height=700)
    canvas.pack(side=tkinter.RIGHT)

    # create a turtle to draw on the canvas 
    pen = turtle.RawTurtle(canvas)
    screen = pen.getscreen()

    # Set screen co-ordinates.
    screen.setworldcoordinates(-200, -700, 800, 700)
    screen.bgcolor("grey")

    # Draw frame  
    frame = tkinter.Frame(root, bg="white")
    frame.pack(side=tkinter.LEFT, fill=tkinter.BOTH)

    pointLabel = tkinter.Label(frame, text="Fractal", bg="white", )
    pointLabel.pack()

    # make the dropdown for fractal  list
    turtleNames = ["Tree", "Dandelion"]
    turtleStr = tkinter.StringVar()
    turtleList = OptionMenu(frame, turtleStr, turtleNames[0], *turtleNames)
    turtleList.pack()

    numberLabel = tkinter.Label(frame, text="Number")
    numberLabel.pack()

    # the entry widget must be given a string.
    number = tkinter.StringVar()
    numberEntry = tkinter.Entry(frame, textvariable=number)
    numberEntry.pack()
    number.set(str(3))

    lengthLabel = tkinter.Label(frame, text="Length")
    lengthLabel.pack()

    # User sets length
    length = tkinter.StringVar()
    lengthEntry = tkinter.Entry(frame, textvariable=length)
    lengthEntry.pack()
    length.set(str(200))

    def drawHandler():
        # get the value from orderStr and make int
        num = int(number.get())

        # get the value from lengthStr and make int
        len = int(length.get())

        figures.tree(num, len)

    # Event handler to clear canvas for a new drawing
    def clearHandler():
        pen.clear()

    # This is an event handler. Handling the quit button press results in quitting the application.
    def quitHandler():
        root.destroy()
        root.quit()

    # Draw Buttons

    # presses of the "Draw" button.
    drawButton = tkinter.Button(frame, text="Draw", command=drawHandler)
    drawButton.pack()

    # presses of the "Clear" button.
    clearButton = tkinter.Button(frame, text="Clear", command=clearHandler)
    clearButton.pack()

    # presses of the "Quit" button.
    quitButton = tkinter.Button(frame, text="Quit", command=quitHandler)
    quitButton.pack()

    # tells the application to enter its event processing loop
    tkinter.mainloop()

# Python jumps right here after executing the def main() line. These two lines tell
if __name__ == "__main__":
    main()

figures.py for storing predefined designs

from turtle import *

pen = Pen()

screen = Screen()


# 1st figure Tree
def tree(n, l):
    if n == 0 or l < 2:
        return
    # endif
    pen.forward(l)
    pen.left(45)
    tree(n - 1, l / 2)
    pen.right(90)
    tree(n - 1, l / 2)
    pen.left(45)
    pen.backward(l)

The app runs fine if the "tree" function is in the main python file ie everything draws in one window. If I put the figure "tree" in a second python file (figures.py) and try to import it the app will create a second window and the tree figure will draw there instead of the intended main window.

The problem is that figures.py is setting up a turtle environment independent of the main program -- don't let it. Pass in to the figures.py functions whatever they need to operate in the main program's turtle environment:

figures.py

# 1st figure Tree
def tree(pen, number, length):
    if number == 0 or length < 2:
        return

    pen.forward(length)
    pen.left(45)
    tree(pen, number - 1, length / 2)
    pen.right(90)
    tree(pen, number - 1, length / 2)
    pen.left(45)
    pen.backward(length)

# test this code standalone
if __name__ == "__main__":
    import turtle

    tree(turtle.getpen(), 5, 100)  # test using default turtle

    turtle.exitonclick()

The code at the bottom of the file is so you can test this file independently. When imported into the main program, it will be ignored. Now we just need a small change to the main program:

main python file

def drawHandler():
    # get the value from orderStr and make int
    number_int = int(number.get())

    # get the value from lengthStr and make int
    length_int = int(length.get())

    figures.tree(pen, number_int, length_int)

I changed the variable names as you were redefining Python's built-in len function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM