在我的tkinter应用程序代码中放置mainloop调用的位置?

时间:2015-11-15 17:11:11

标签: python tkinter python-imaging-library tkinter-canvas

我一直试图弄清楚如何使用如何在我的GUI中放置一个mainloop(),这样我就不再需要一段时间(True)了。

我的代码底部是我如何使用此代码的示例。我知道这需要经过很多代码,所以感谢任何帮助

# Imports
import os
import os.path
import sys

import tkinter
tk = tkinter
from tkinter import font

#----- Set flag for JPEG support ---
noJPEG = False
try:
    from PIL import Image
    Pimg = Image
    from PIL import ImageTk
    Pimgtk = ImageTk
    from PIL import ImageDraw
except ImportError:
    noJPEG = True
#-----------------------------------

#
# Create an invisible global parent window to hold all children.
# Allows for easy closing of all windows by mouse click. If not
# closed programmatically, program exits if all windows are
# manually closed.
_root = tk.Tk()
_root.withdraw()
###

class ImageView(tk.Canvas):

    def __init__(self, image, title, lotDiogram):

        is_Diogram = lotDiogram

        master = tk.Toplevel(_root) #sets master as a subwindow of _root

        master.protocol("WM_DELETE_WINDOW", self.close)

        if(is_Diogram == True):

            """When 'is_Diogram' is True, it means image is a
               parking lot diogram, and does need scrollbars
               added to its Toplevel"""

            tk.Canvas.__init__(self, master,
                               width = 650, height = 525,
                               scrollregion=(0,0,image.getWidth(),
                                             image.getHeight()))
            self.master.title(title)

            # Scrollbar added to master 
            vsb = tk.Scrollbar(master, orient="vertical", command=self.yview)
            hsb = tk.Scrollbar(master, orient="horizontal", command=self.xview)
            self.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
            self.grid(row=0, column=0, sticky="nswe")
            vsb.grid(row=0, column=1, sticky="ns")
            hsb.grid(row=1, column=0, sticky="ew")
            master.grid_rowconfigure(0, weight=1)
            master.grid_columnconfigure(0, weight=1)

            master.minsize(width=600, height=500)
            master.maxsize(width = image.getWidth(),
                           height = image.getHeight() )

            self.foreground = "black"
            self.image = image
            self.height = image.getHeight()
            self.width = image.getWidth()
            self.mouseX = None
            self.mouseY = None
            self.bind("<Button-1>", self.onClick)

            self.tags = None

            _root.update()  #redraw global window

        else:   
            """When 'is_Diogram' is False, it means image is a
               lot sign, and does not need scrollbars
               added to its Toplevel"""

            tk.Canvas.__init__(self, master, width = image.getWidth(),
                               height = image.getHeight() )

            self.master.title(title)
            self.pack()

            master.resizable(0,0)
            self.foreground = "black"
            self.image = image
            self.height = image.getHeight()
            self.width = image.getWidth()
            self.mouseX = None
            self.mouseY = None
            self.bind("<Button-1>", self.onClick)
            self.tags = None
            _root.update()  #redraw global window        

    def close(self):
        """Close a window."""
        self.master.destroy()
        self.quit()
        _root.update()

    def getMouseXY(self):
        """Return a tuple with x,y position in the image of the
           mouse click."""
        self.mouseX = None
        self.mouseY = None
        while (self.mouseX == None) or (self.mouseY == None) :
            self.update()
        return ((self.mouseX,self.mouseY))

    def onClick(self, event):
        """Perform various functions when mouse is clicked."""
        self.mouseX = int(self.canvasx(event.x))
        self.mouseY = int(self.canvasy(event.y))

    def drawShape(self, shape, tagz=None, txt=None, tfont="TkDefaultFont",
                  color1=None, color2=None, coords=None, w=None, OL=None):
        """Draws a shape, assigns it a tag, and binds the tag to a
           mouse click."""

        self.tags = tagz

        if shape == 'rectangle':
            """Only will accept 2 pairs of XY coordinates, X0, Y0, X1, Y1)"""
            self.create_rectangle(coords, fill = color1,
                                  activefill = color2, tags = tagz)

        elif shape == 'polygon':
            """Polygon will accept a minimum of 4 XY coordinate pairs"""
            self.create_polygon(coords, fill = color1,
                                activefill = color2, outline = OL,
                                tags = tagz)

        else:  #should never get here since shape is required
            print("No shape specified!")          

        _root.update()  #redraw global window


    def getTags(self):
        self.getMouseXY()
        obj = self.find_closest(self.mouseX, self.mouseY)
        return self.gettags(obj)

    def getHeight(self):
        """Return the height of the window."""
        return self.height

    def getWidth(self):
        """Return the width of the window."""
        return self.width


class imagesMSUError(Exception):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value) 

#------------------------------------------------------

class Image(object):

    def __init__(self, file_or_type, *args):

        global noJPEG

        try:
            if type(file_or_type) != str:
                raise imagesMSUError(str(file_or_type))
        except imagesMSUError as e:
            print('imagesMSU_Error: "' + e.value + '" is not a '
                  + 'valid image type or a valid GIF/JPG filename.')
            sys.exit(1)

        # If an image type was passed in, create a blank image
        # of that type.
        self.type = file_or_type.upper()

        if self.type == 'GIF' or self.type == 'JPG':

            # Create blank image; *args are width, height.
            self.width, self.height = args
            self.filename = 'blank'  #default filename for saving

            if self.type == 'GIF':  #create blank gif
                self.image = tk.PhotoImage(master =_root,
                                           width = self.width,
                                           height = self.height)

            if self.type == 'JPG':  #create blank jpg
                try:
                    if noJPEG:  #libjpeg not installed
                        raise imagesMSUError(noJPEG)
                except imagesMSUError as e:
                    print('imagesMSU_Error: Support library for JPEGs '
                          + 'not found. Use GIFs instead.')
                    sys.exit(1)

                else:
                    self.image = Pimg.new(mode = "RGB",
                                      size = (self.width, self.height))

        else:  #A filename was passed in. Validate then load into an image.

            # Check for valid image type
            self.type = file_or_type[-3:].upper()  #file's 3 char extension
            try:
                if self.type != 'GIF' and self.type != 'JPG': #wrong extension
                    raise imagesMSUError(self.type)
            except imagesMSUError as e:
                print('imagesMSUError: "' + e.value
                      + '" is not a valid image type.')
                sys.exit(1)

            # Check for a valid file
            filename = file_or_type
            try:
                if not os.path.isfile(filename):  #not a file or not found
                        raise imagesMSUError(filename)
            except imagesMSUError as e:
                print('imagesMSU_Error: File "' + e.value + '" not found.')
                sys.exit(1)

            if self.type == 'GIF':
                self.image = tk.PhotoImage(file = filename, master = _root)
                self.width = self.image.width()
                self.height = self.image.height()

            if self.type == 'JPG':
                try:
                    if noJPEG:  #libjpeg not installed
                        raise imagesMSUError(noJPEG)
                except imagesMSUError as e:
                    print('imagesMSU_Error: Support library for JPEGs '
                          + 'not found. Use GIFs instead.')
                    sys.exit(1)

                else:
                    self.image = Pimg.open(filename)
                    box = self.image.getbbox()
                    self.width = box[2]
                    self.height = box[3]


    def getType(self):
        """Returns the image type."""
        return self.type

    def getWidth(self):
        """Returns the width of the image in pixels."""
        return self.width

    def getHeight(self):
        """Returns the height of the image in pixels."""
        return self.height

    def draw(self, win):
        """Creates and opens a window on an image. The user must close
           the window to return control to the caller."""

        self.canvas = win

        if self.type == 'GIF':
            self.canvas.create_image(self.width // 2,
                                 self.height // 2,
                                 image = self.image)
        if self.type == 'JPG':
            self.photoImage = Pimgtk.PhotoImage(self.image)
            self.canvas.create_image(self.width // 2,
                                     self.height // 2,
                                     image = self.photoImage)

        # Update the hidden root window to draw the image.
        _root.update()


#-------------Example program----------------------------#

def main():

        # Load an image
        img1 = Image('BURG.jpg')

        # Draw the image in a window.
        window1 = ImageView(img1, "Burg Lot", True)
        img1.draw(window1)

        window1.drawShape('rectangle', tagz="Handicap", coords=[391, 214, 429, 235],
                      color1=None, color2='red')
        window1.drawShape('rectangle', tagz="Lot_Sign", coords=[486, 375, 509, 389],
                      color1=None, color2='red')

        # Loop to click parking spots and display parking sign
        while(True):
            tags = window1.getTags()
            for tag in tags:
                if tag != 'current':

                    if tag == 'Handicap':
                        img2 = Image('BUR HC.jpg')
                        window2 = ImageView(img2, "Handicap", False)
                        img2.draw(window2)


                    if tag == 'Lot_Sign':
                        img2 = Image('Lot Sign.jpg')
                        window2 = ImageView(img2, "Lot Info", False)
                        img2.draw(window2)

if __name__ == '__main__':

    main()

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题,我会做主循环: https://docs.python.org/3/library/tkinter.html#a-simple-hello-world-program 然后重构一下。

您在tags-loop中的当前标记可以在drawShape中完成,无论如何您都可以在其中设置标记。这会将您的程序转换为事件驱动。