使用 tk 框架合并两个应用程序
Merging two applications using tk frames
我有一个用 python 和 tkinter 制作的记忆游戏。我还制作了一个带有简单 GUI 的应用程序,该 GUI 使用 tk.Frame 来显示不同的帧。我的问题是将记忆游戏放在 GUI 应用程序的框架之一中。
我有一个用于记忆游戏的 .py 文件和一个用于 GUI 的 .py 文件。 GUI 有多个 classes 和框架。我想将记忆游戏放在其中一个框架内,以便您可以通过菜单导航进入游戏。游戏应该只在导航到时显示。
我试过:
- 在 GUI 文件的顶部导入 memorygame 文件
- 正在 GUI 文件的 class 中导入 memorygame 文件
- 将整个记忆游戏代码复制到 class GUI 文件
导入文件使两个应用程序在启动时尝试 运行 不同的 windows。将游戏代码复制到 GUI class 出现了很多错误。
我有 python 3.7 和 tkinter 8.6
记忆游戏首先创建一个 canvas,它利用了:
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 创建一个显示不同内容的框架:
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()
- importing the memorygame file at the top of the GUI file
- importing the memorygame file inside a class of the GUI file
这两种方式都会 "both the applications try to run on startup in different windows" 这是因为 memorygame 文件会生成一个新的 tk.Tk()
window,您的 GUI 处理程序也是如此。
copying the whole memorygame code into a class of the GUI file
这可能会导致很多问题,具体取决于您将文件复制到的位置,因为这些文件有自己的导入依赖项,并且导入路径可能会根据您将文件复制到的位置而改变。
我建议您执行以下操作,我会更改您的记忆游戏代码,使记忆游戏成为 class(tk.Frame)
(帧 class),然后您应该可以导入记忆游戏并将该框架粘贴到 GUI PageMk(tk.Frame)
,我不知道您的代码具有依赖性,但这应该可以。
Example of change using the provided code
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()
My Edits to the full code:
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()
祝你好运:)
我有一个用 python 和 tkinter 制作的记忆游戏。我还制作了一个带有简单 GUI 的应用程序,该 GUI 使用 tk.Frame 来显示不同的帧。我的问题是将记忆游戏放在 GUI 应用程序的框架之一中。
我有一个用于记忆游戏的 .py 文件和一个用于 GUI 的 .py 文件。 GUI 有多个 classes 和框架。我想将记忆游戏放在其中一个框架内,以便您可以通过菜单导航进入游戏。游戏应该只在导航到时显示。
我试过:
- 在 GUI 文件的顶部导入 memorygame 文件
- 正在 GUI 文件的 class 中导入 memorygame 文件
- 将整个记忆游戏代码复制到 class GUI 文件
导入文件使两个应用程序在启动时尝试 运行 不同的 windows。将游戏代码复制到 GUI class 出现了很多错误。
我有 python 3.7 和 tkinter 8.6
记忆游戏首先创建一个 canvas,它利用了:
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 创建一个显示不同内容的框架:
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()
- importing the memorygame file at the top of the GUI file
- importing the memorygame file inside a class of the GUI file
这两种方式都会 "both the applications try to run on startup in different windows" 这是因为 memorygame 文件会生成一个新的 tk.Tk()
window,您的 GUI 处理程序也是如此。
copying the whole memorygame code into a class of the GUI file
这可能会导致很多问题,具体取决于您将文件复制到的位置,因为这些文件有自己的导入依赖项,并且导入路径可能会根据您将文件复制到的位置而改变。
我建议您执行以下操作,我会更改您的记忆游戏代码,使记忆游戏成为 class(tk.Frame)
(帧 class),然后您应该可以导入记忆游戏并将该框架粘贴到 GUI PageMk(tk.Frame)
,我不知道您的代码具有依赖性,但这应该可以。
Example of change using the provided code
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()
My Edits to the full code:
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()
祝你好运:)