使用tk框架合并两个应用程序

时间:2019-05-21 14:39:19

标签: python-3.x tkinter tkinter-canvas

我有一个用python和tkinter制作的记忆游戏。我还制作了一个使用tk.Frame来显示不同框架的简单GUI的应用程序。我的问题是将记忆游戏放在GUI应用程序的框架之一中。

我有一个用于游戏的.py文件和一个用于GUI的文件。 GUI具有多个类和框架。我想将记忆游戏放在这些框架之一中,以便您可以通过菜单导航到游戏中。游戏仅在导航至时显示。

我尝试过:

  • 在GUI文件顶部导入memorygame文件
  • 将memorygame文件导入GUI文件的类中
  • 将整个内存游戏代码复制到GUI文件的类中

导入文件使两个应用程序都尝试在启动时在不同的窗口中运行。将游戏代码复制到GUI类中会产生很多错误。

我有python 3.7和tkinter 8.6

记忆游戏首先创建一个绘制画布:

win = tk.Tk()
canvas = tk.Canvas(win, width = 600, height = 480)
canvas.pack()
class Tile(object):
    def __init__(self, x, y, text):
        self.y = y
        self.x = x
        self.text = text
    def drawFaceDown(self):
        canvas.create_rectangle(self.x, self.y, self.x + 100, self.y + 100, fill = "green")
...

这是我使用类创建显示不同内容的框架的方式:

class PageMG(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        # memory game goes here

如果有人想看,我可以显示整个文件

我希望游戏仅在单击将我带到想要游戏的框架的按钮之前显示。

编辑:整个内存游戏文件

import tkinter as tk
import time
from random import randint
from random import shuffle
win = tk.Tk()
canvas = tk.Canvas(win, width = 500, height = 500)
canvas.pack()
class Tile(object):
    def __init__(self, x, y, text):
        self.y = y
        self.x = x
        self.text = text
    def drawFaceDown(self):
        canvas.create_rectangle(self.x, self.y, self.x + 70, self.y + 70, fill = "blue")
        self.isFaceUp = False
    def drawFaceUp(self):
        canvas.create_rectangle(self.x, self.y, self.x + 70, self.y + 70, fill = "blue")
        canvas.create_text(self.x + 35, self.y + 35, text = self.text, width = 70, fill = "white", font='Helvetica 12 bold')
        self.isFaceUp = True
    def isUnderMouse(self, event):
        if(event.x > self.x and event.x < self.x + 70):
            if(event.y > self.y and event.y < self.y + 70):
                return True

tiles = []
colors = [
    "Eple",
    "Appelsin",
    "Banan",
    "Agurk",
    "Brokkoli",
    "Tomat",
    "Sitron",
    "Melon",
    "Hvitløk",
    "Erter",
    "Jordbær",
    "Blåbær"
]

selected = []
for i in range(10):
    randomInd = randint(0, len(colors) - 1)
    color = colors[randomInd]
    selected.append(color)
    selected.append(color)
    del colors[randomInd]
shuffle(selected)

flippedTiles = []

def mouseClicked(self):
    global numFlipped
    global flippedTiles
    for i in range(len(tiles)):
        if tiles[i].isUnderMouse(self):
            if (len(flippedTiles) < 2 and not(tiles[i].isFaceUp)) :
                tiles[i].drawFaceUp()
                flippedTiles.append(tiles[i])
            if (len(flippedTiles) == 2):
                if not(flippedTiles[0].text == flippedTiles[1].text):
                    time.sleep(1)
                    flippedTiles[0].drawFaceDown()
                    flippedTiles[1].drawFaceDown()

NUM_COLS = 5
NUM_ROWS = 4

for x in range(0,NUM_COLS):
    for y in range(0,NUM_ROWS):
            tiles.append(Tile(x * 78 + 10, y * 78 + 40, selected.pop()))

for i in range(len(tiles)):
    tiles[i].drawFaceDown()

flippedThisTurn = 0
def mouseClicked(event):
    global flippedTiles
    global flippedThisTurn
    for tile in tiles:
        if tile.isUnderMouse(event):
            if (not(tile.isFaceUp)) :
                tile.drawFaceUp()
                flippedTiles.append(tile)
                flippedThisTurn += 1

            if (flippedThisTurn == 2):
                win.after(1000, checkTiles)
                flippedThisTurn = 0

def checkTiles():
    if not(flippedTiles[-1].text == flippedTiles[-2].text): #check last two elements
        flippedTiles[-1].drawFaceDown() #facedown last two elements
        flippedTiles[-2].drawFaceDown()
        del flippedTiles[-2:] #remove last two elements

win.bind("<Button-1>", mouseClicked)


win.mainloop()

1 个答案:

答案 0 :(得分:0)

  
      
  1. 在GUI文件顶部导入memorygame文件
  2.   
  3. 将memorygame文件导入GUI文件的类中
  4.   

这两种方式都会使“这两个应用程序都尝试在不同的窗口中启动运行”,这是因为memorygame文件创建了一个新的tk.Tk()窗口,您的GUI处理程序也是如此。

  

将整个内存游戏代码复制到GUI文件的类中

这可能会导致很多问题,具体取决于您将文件复制到的位置,因为这些文件具有自己的导入依赖性,并且导入路径可能会根据您将文件复制到的位置而改变。

我建议做的是以下操作,我将更改记忆游戏的代码以使记忆游戏成为class(tk.Frame)(框架类),然后您应该能够导入记忆游戏并将其粘贴嵌入到GUI PageMk(tk.Frame)中,我不知道您的代码具有依赖项,但这应该可以工作。

  

使用提供的代码进行更改的示例

class MemGame(tk.Frame):
    def __init__(self, parent):
        super(MemGame, self).__init__(parent)
        self.configure(width=600, height=480)
        canvas = tk.Canvas(self, width=600, height=480, bg="red")
        canvas.pack()

class Tile:
    def __init__(self, parent, x, y, text):
        self.parent = parent
        self.y = y
        self.x = x
        self.text = text
    def drawFaceDown(self):
        self.parent.create_rectangle(self.x, self.y, self.x + 100, self.y + 100, fill="green")

class PageMG(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        x = MemGame(self)
        x.pack()
  

我的编辑为完整代码:

import tkinter as tk
import time
from random import randint
from random import shuffle


class Controller(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        # the container is where we'll stack a bunch of frames
        # on top of each other, then the one we want visible
        # will be raised above the others
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        if True:
            self.frames = {}
            for F in (PageMG,):
                page_name = F.__name__
                frame = F(parent=container, controller=self)
                self.frames[page_name] = frame

                # put all of the pages in the same location;
                # the one on the top of the stacking order
                # will be the one that is visible.
                frame.grid(row=0, column=0, sticky="nsew")

            self.show_frame("PageMG")
        self.geometry("500x400")

    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()


class PageMG(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        x = MemGame(self)
        x.pack()


class Tile(object):
    def __init__(self, canvas, x, y, text):
        self.canvas = canvas
        self.y = y
        self.x = x
        self.text = text

    def drawFaceDown(self):
        self.canvas.create_rectangle(self.x, self.y, self.x + 70, self.y + 70, fill = "blue")
        self.isFaceUp = False

    def drawFaceUp(self):
        self.canvas.create_rectangle(self.x, self.y, self.x + 70, self.y + 70, fill = "blue")
        self.canvas.create_text(self.x + 35, self.y + 35, text = self.text, width = 70, fill = "white", font='Helvetica 12 bold')
        self.isFaceUp = True

    def isUnderMouse(self, event):
        if(event.x > self.x and event.x < self.x + 70):
            if(event.y > self.y and event.y < self.y + 70):
                return True


class MemGame(tk.Frame):
    def __init__(self, master):
        super(MemGame, self).__init__(master)
        self.configure(width=500, height=500)
        self.canvas = tk.Canvas(self, width=500, height=500)
        self.canvas.pack()
        self.tiles = []
        self.colors = [
            "Eple",
            "Appelsin",
            "Banan",
            "Agurk",
            "Brokkoli",
            "Tomat",
            "Sitron",
            "Melon",
            "Hvitløk",
            "Erter",
            "Jordbær",
            "Blåbær"
        ]

        selected = []
        for i in range(10):
            randomInd = randint(0, len(self.colors) - 1)
            color = self.colors[randomInd]
            selected.append(color)
            selected.append(color)
            del self.colors[randomInd]
        shuffle(selected)
        self.flippedTiles = []
        NUM_COLS = 5
        NUM_ROWS = 4

        for x in range(0, NUM_COLS):
            for y in range(0, NUM_ROWS):
                self.tiles.append(Tile(self.canvas, x * 78 + 10, y * 78 + 40, selected.pop()))

        for i in range(len(self.tiles)):
            self.tiles[i].drawFaceDown()
        self.flippedThisTurn = 0
        self.bind("<Button-1>", self.mouseClicked)

    # def mouseClicked(self):
    #     for i in range(len(self.tiles)):
    #         if self.tiles[i].isUnderMouse(self):
    #             if (len(self.flippedTiles) < 2 and not(self.tiles[i].isFaceUp)) :
    #                 self.tiles[i].drawFaceUp()
    #                 self.flippedTiles.append(self.tiles[i])
    #             if (len(self.flippedTiles) == 2):
    #                 if not(self.flippedTiles[0].text == self.flippedTiles[1].text):
    #                     time.sleep(1)
    #                     self.flippedTiles[0].drawFaceDown()
    #                     self.flippedTiles[1].drawFaceDown()

    def mouseClicked(self, event):
        for tile in self.tiles:
            if tile.isUnderMouse(event):
                if (not(tile.isFaceUp)) :
                    tile.drawFaceUp()
                    self.flippedTiles.append(tile)
                    self.flippedThisTurn += 1

                if (self.flippedThisTurn == 2):
                    self.after(1000, self.checkTiles)
                    self.flippedThisTurn = 0

    def checkTiles(self):
        if not(self.flippedTiles[-1].text == self.flippedTiles[-2].text): #check last two elements
            self.flippedTiles[-1].drawFaceDown()
            self.flippedTiles[-2].drawFaceDown()
            del self.flippedTiles[-2:]


if __name__ == '__main__':
    c = Controller()
    c.mainloop()

好运:)