如何同时 运行 Tkinter GUI 和 Python 命令行?
How to run Tkinter GUI and Python command line at the same time?
所以我有一个棋盘 GUI,它显示一个带有棋子的棋盘和一个 UI,它允许用户输入一个棋子来移动。目前我的 GUI 和 UI 都在工作,但是当我 运行 程序 UI 运行 没有 GUI 时。有什么办法可以同时 运行 GUI 和 UI 吗?
我的主要Class:
class ChessBoard(tk.Frame):
def __init__(self, parent, rows=8, columns=8, size=70, color1="white", color2="lightgrey"):
self.rows = rows
self.columns = columns
self.size = size
self.color1 = color1
self.color2 = color2
self.pieces = {}
canvas_width = columns * size
canvas_height = rows * size
tk.Frame.__init__(self, parent)
self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0,width=canvas_width, height=canvas_height, background="white")
self.canvas.pack(side="top", fill="both", expand=True, padx=2, pady=2)
color = self.color2
for row in range(self.rows):
color = self.color1 if color == self.color2 else self.color2
for col in range(self.columns):
x1 = (col * self.size)
y1 = (row * self.size)
x2 = x1 + self.size
y2 = y1 + self.size
self.canvas.create_rectangle(x1, y1, x2, y2, outline="black", fill=color, tags="square")
color = self.color1 if color == self.color2 else self.color2
我的UI:
def UserInput(self):
KingRow = int(input("Choose Row: "))
KingColumn = int(input("Choose Column: "))
#Not Complete UI
这就是一切都被调用的地方:
if __name__ == "__main__":
root = tk.Tk()
board = ChessBoard(root)
board.pack(side="top", fill="both", expand="true", padx=4, pady=4)
board.UserInput()
root.mainloop()
到目前为止我试过的是 Root.after() 但似乎什么也没发生(我可能用错了)
唯一一次 GUI 运行s 是在 UI.Is 中出现错误时我可以 运行 GUI 和 UI 同时?谢谢!
在这种情况下,您使用的 root.after()
可能有误,但如果没有您使用的代码,我们无法判断。
在 after()
方法中,您需要传递一个数字和一个命令。该数字代表毫秒,因此 1000 将是 1 秒。命令可以是 lambda 或 link 到 method/function。所以像这样。 root.after(1000, some_function_name)
.
只要您调用 input()
,您的应用程序就会冻结,因为程序必须等待回复,从而暂停 mainloop()
。这让事情变得比他们需要的更复杂,并且可能永远不会像你想要的那样工作。您可能希望将用户输入移至 GUI 而不是使用控制台输入。
您可以为用户提供一个 Entry
字段和一个用于提交信息的按钮。您还可以绑定 <Return>
键,用户只需按 Enter 即可。
我已经修改了您的代码,以提供一个基本示例,说明您如何使用输入字段、标签和绑定来为用户输入提供一个位置,而不会像使用控制台 input()
那样冻结程序.
我将 pack()
更改为 grid()
,因为我发现在设置 GUI 时更容易处理。我已经使用 .bind()
为 UserInput()
方法设置了一个命令。
此示例只是更新标签,但应该向您展示如何使用 get()
用户输入,然后将其应用到某些东西。
import tkinter as tk
class ChessBoard(tk.Frame):
def __init__(self, parent, rows=8, columns=8, size=70, color1="white", color2="lightgrey"):
tk.Frame.__init__(self, parent)
self.rows = rows
self.columns = columns
self.size = size
self.color1 = color1
self.color2 = color2
self.pieces = {}
canvas_width = columns * size
canvas_height = rows * size
self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0,width=canvas_width, height=canvas_height, background="white")
self.canvas.grid(row=0, column=0, columnspan=5, padx=2, pady=2, sticky="nsew")
self.UI_lbl = tk.Label(self, text="Choose Row: ")
self.UI_lbl.grid(row=1, column=0, sticky="e")
self.UI_entry1 = tk.Entry(self)
self.UI_entry1.grid(row=1, column=1, sticky="w")
self.UI_lbl2 = tk.Label(self, text="Choose Column: ")
self.UI_lbl2.grid(row=2, column=0, sticky="e")
self.UI_entry2 = tk.Entry(self)
self.UI_entry2.grid(row=2, column=1, sticky="w")
self.UI_entry1.bind("<Return>", self.UserInput)
self.UI_entry2.bind("<Return>", self.UserInput)
self.game_lbl = tk.Label(self, text="Player moves: ")
self.game_lbl.grid(row=1, column=2, rowspan=2, columnspan=3, sticky="w")
color = self.color2
for row in range(self.rows):
color = self.color1 if color == self.color2 else self.color2
for col in range(self.columns):
x1 = (col * self.size)
y1 = (row * self.size)
x2 = x1 + self.size
y2 = y1 + self.size
self.canvas.create_rectangle(x1, y1, x2, y2, outline="black", fill=color, tags="square")
color = self.color1 if color == self.color2 else self.color2
def UserInput(self, Event):
KingRow = self.UI_entry1.get()
KingColumn = self.UI_entry2.get()
self.game_lbl.config(text="Player moves Game Piece to Row: {}, Column: {}".format(KingRow, KingColumn))
if __name__ == "__main__":
root = tk.Tk()
board = ChessBoard(root)
board.grid(row=0, column=0,sticky="nsew")
root.mainloop()
所以我有一个棋盘 GUI,它显示一个带有棋子的棋盘和一个 UI,它允许用户输入一个棋子来移动。目前我的 GUI 和 UI 都在工作,但是当我 运行 程序 UI 运行 没有 GUI 时。有什么办法可以同时 运行 GUI 和 UI 吗?
我的主要Class:
class ChessBoard(tk.Frame):
def __init__(self, parent, rows=8, columns=8, size=70, color1="white", color2="lightgrey"):
self.rows = rows
self.columns = columns
self.size = size
self.color1 = color1
self.color2 = color2
self.pieces = {}
canvas_width = columns * size
canvas_height = rows * size
tk.Frame.__init__(self, parent)
self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0,width=canvas_width, height=canvas_height, background="white")
self.canvas.pack(side="top", fill="both", expand=True, padx=2, pady=2)
color = self.color2
for row in range(self.rows):
color = self.color1 if color == self.color2 else self.color2
for col in range(self.columns):
x1 = (col * self.size)
y1 = (row * self.size)
x2 = x1 + self.size
y2 = y1 + self.size
self.canvas.create_rectangle(x1, y1, x2, y2, outline="black", fill=color, tags="square")
color = self.color1 if color == self.color2 else self.color2
我的UI:
def UserInput(self):
KingRow = int(input("Choose Row: "))
KingColumn = int(input("Choose Column: "))
#Not Complete UI
这就是一切都被调用的地方:
if __name__ == "__main__":
root = tk.Tk()
board = ChessBoard(root)
board.pack(side="top", fill="both", expand="true", padx=4, pady=4)
board.UserInput()
root.mainloop()
到目前为止我试过的是 Root.after() 但似乎什么也没发生(我可能用错了)
唯一一次 GUI 运行s 是在 UI.Is 中出现错误时我可以 运行 GUI 和 UI 同时?谢谢!
在这种情况下,您使用的 root.after()
可能有误,但如果没有您使用的代码,我们无法判断。
在 after()
方法中,您需要传递一个数字和一个命令。该数字代表毫秒,因此 1000 将是 1 秒。命令可以是 lambda 或 link 到 method/function。所以像这样。 root.after(1000, some_function_name)
.
只要您调用 input()
,您的应用程序就会冻结,因为程序必须等待回复,从而暂停 mainloop()
。这让事情变得比他们需要的更复杂,并且可能永远不会像你想要的那样工作。您可能希望将用户输入移至 GUI 而不是使用控制台输入。
您可以为用户提供一个 Entry
字段和一个用于提交信息的按钮。您还可以绑定 <Return>
键,用户只需按 Enter 即可。
我已经修改了您的代码,以提供一个基本示例,说明您如何使用输入字段、标签和绑定来为用户输入提供一个位置,而不会像使用控制台 input()
那样冻结程序.
我将 pack()
更改为 grid()
,因为我发现在设置 GUI 时更容易处理。我已经使用 .bind()
为 UserInput()
方法设置了一个命令。
此示例只是更新标签,但应该向您展示如何使用 get()
用户输入,然后将其应用到某些东西。
import tkinter as tk
class ChessBoard(tk.Frame):
def __init__(self, parent, rows=8, columns=8, size=70, color1="white", color2="lightgrey"):
tk.Frame.__init__(self, parent)
self.rows = rows
self.columns = columns
self.size = size
self.color1 = color1
self.color2 = color2
self.pieces = {}
canvas_width = columns * size
canvas_height = rows * size
self.canvas = tk.Canvas(self, borderwidth=0, highlightthickness=0,width=canvas_width, height=canvas_height, background="white")
self.canvas.grid(row=0, column=0, columnspan=5, padx=2, pady=2, sticky="nsew")
self.UI_lbl = tk.Label(self, text="Choose Row: ")
self.UI_lbl.grid(row=1, column=0, sticky="e")
self.UI_entry1 = tk.Entry(self)
self.UI_entry1.grid(row=1, column=1, sticky="w")
self.UI_lbl2 = tk.Label(self, text="Choose Column: ")
self.UI_lbl2.grid(row=2, column=0, sticky="e")
self.UI_entry2 = tk.Entry(self)
self.UI_entry2.grid(row=2, column=1, sticky="w")
self.UI_entry1.bind("<Return>", self.UserInput)
self.UI_entry2.bind("<Return>", self.UserInput)
self.game_lbl = tk.Label(self, text="Player moves: ")
self.game_lbl.grid(row=1, column=2, rowspan=2, columnspan=3, sticky="w")
color = self.color2
for row in range(self.rows):
color = self.color1 if color == self.color2 else self.color2
for col in range(self.columns):
x1 = (col * self.size)
y1 = (row * self.size)
x2 = x1 + self.size
y2 = y1 + self.size
self.canvas.create_rectangle(x1, y1, x2, y2, outline="black", fill=color, tags="square")
color = self.color1 if color == self.color2 else self.color2
def UserInput(self, Event):
KingRow = self.UI_entry1.get()
KingColumn = self.UI_entry2.get()
self.game_lbl.config(text="Player moves Game Piece to Row: {}, Column: {}".format(KingRow, KingColumn))
if __name__ == "__main__":
root = tk.Tk()
board = ChessBoard(root)
board.grid(row=0, column=0,sticky="nsew")
root.mainloop()