如何同时运行Tkinter GUI和Python命令行?

时间:2018-03-21 21:06:53

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

所以我有一个Chessboard GUI,它显示一个带棋子的棋盘和一个允许用户输入要移动的棋子的UI。目前我的GUI和UI都在工作,但是当我运行程序时,UI在没有GUI的情况下运行。有没有办法可以同时运行GUI和UI?

我的主要班级:

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

我的用户界面:

    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运行的唯一时间是UI中出现错误。有没有办法可以同时运行GUI和UI?谢谢!

1 个答案:

答案 0 :(得分:1)

在这种情况下,您可能使用root.after()错误,但如果没有您使用的代码,我们无法判断。

after()方法中,您需要传递一个数字和一个命令。该数字代表毫秒,因此1000将是1秒。该命令可以是lambda或指向方法/函数的链接。所以这样的事情。 root.after(1000, some_function_name)

当您致电input()时,您的应用程序将冻结,因为程序必须等待回复,从而暂停mainloop()。这使事情变得比他们需要的更复杂,并且可能不会像你想要的那样工作。您可能希望将用户输入移动到GUI而不是使用控制台输入。

您可以为用户提供Entry字段,也可以提供用于提交信息的按钮。您还可以绑定用户只需按Enter键的<Return>键。

我修改了你的代码,给出了一个基本的例子,说明如何使用输入字段,标签和绑定为用户输入提供一个不会像使用控制台input()那样冻结程序的地方。 / p>

我将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()