如何同时 运行 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()