【问题标题】:How to run Tkinter GUI and Python command line at the same time?如何同时运行 Tkinter GUI 和 Python 命令行?
【发布时间】:2018-03-21 21:06:53
【问题描述】:

所以我有一个棋盘 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?谢谢!

【问题讨论】:

  • 你永远不会创建画布,所以你的程序应该会抛出错误。
  • 请提供Minimal, Complete, and Verifiable example。这将使我们能够帮助您解决问题。您的代码不足以重现问题。如果没有 MCVE,您将不可能得到您正在寻找的答案。
  • 为什么不用弹出对话框输入行/列信息,而不必从命令行输入?
  • @Mike-SMT 正在创建画布,我的代码中当前没有错误。
  • 不是来自您提供的代码。从我所见,您从未创建过画布,并且确实遇到了错误。 AttributeError: 'ChessBoard' object has no attribute 'canvas'。如果您没有在示例中提供代码,您不能指望人们认为您已经创建了画布。无法解决不存在的问题。

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


【解决方案1】:

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

after() 方法中,您需要传递一个数字和一个命令。该数字代表毫秒,因此 1000 为 1 秒。该命令可以是 lambda 或指向方法/函数的链接。所以像这样。 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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 2019-12-15
    相关资源
    最近更新 更多