【问题标题】:How to call two functions separately on condition using tkinter buttons?如何使用 tkinter 按钮在条件下分别调用两个函数?
【发布时间】:2018-10-09 06:24:02
【问题描述】:

我正在尝试在 tkinter 中创建一个基本游戏,以熟悉使用 Python 进行 GUI 编程。我不想让它变得高效,因此多次复制和粘贴同一条语句。我正在尝试做到这一点,因此当用户单击按钮时,它会将按钮的文本更改为“X”或“O”,具体取决于轮到它的人。在我的按钮中,我有 command = 后跟我的函数,可以将文本更改为两个选项中的任何一个。但是,当我单击一个按钮时,整个按钮网格都会更改为该文本。所以我试图找出是否有这样的东西我可以使用:

command =  lambda:[placeX() or placeO()] 

我的代码如下:

import tkinter as tk, sys as s

Startwindow = tk.Tk()
Startwindow.title("Tic-Tac-Toe")
Startwindow.resizable(0,0)
Startwindow.geometry("1200x600")
image = tk.PhotoImage(file="C:\\Users\\Joshua Brown\\Desktop\\tic tac toe\\download.gif")
renderImage = tk.Label(image=image)
renderImage.grid()

def exe():
    print("Game has exited.")
    Startwindow.destroy()
    s.exit("Requested to close.")

def start():
    print("Game window opening...")
    gameWindow = tk.Tk()
    gameWindow.title("Tic-Tac-Toe: Game Window")
    gameWindow.geometry("450x483")
    gameWindow.resizable(0,0)
    Startwindow.iconbitmap(r'C:\Users\Joshua Brown\Desktop\tic tac toe\tictactoe_H4a_icon.ico')

    board1 = tk.Button(gameWindow, text = "1", command = lambda:[placeX(), placeO()], height = 10, width = 20)
    board1.grid(row=0, column=0)
    board2 = tk.Button(gameWindow, text = "2", command = lambda:[placeX(),placeO()], height = 10, width = 20)
    board2.grid(row=1, column=0)
    board3 = tk.Button(gameWindow, text = "3", command = lambda:[placeX(),placeO()], height = 10, width = 20)
    board3.grid(row=2, column=0)
    board4 = tk.Button(gameWindow, text = "4", command = lambda:[placeX(),placeO()], height = 10, width = 20)
    board4.grid(row=0, column=1)
    board5 = tk.Button(gameWindow, text = "5", command = lambda:[placeX(),placeO()], height = 10, width = 20)
    board5.grid(row=1, column=1)
    board6 = tk.Button(gameWindow, text = "6", command = lambda:[placeX(),placeO()], height = 10, width = 20)
    board6.grid(row=2, column=1)
    board7 = tk.Button(gameWindow, text = "7", command = lambda:[placeX(),placeO()], height = 10, width = 20)
    board7.grid(row=0, column=2)
    board8 = tk.Button(gameWindow, text = "8", command = lambda:[placeX(),placeO()], height = 10, width = 20)
    board8.grid(row=1, column=2)
    board9 = tk.Button(gameWindow, text = "9", command = lambda:[placeX(),placeO()], height = 10, width = 20)
    board9.grid(row=2, column=2)

    def placeX():
        board1.config(text='X')
        board2.config(text='X')
        board3.config(text='X')
        board4.config(text='X')
        board5.config(text='X')
        board6.config(text='X')
        board7.config(text='X')
        board8.config(text='X')
        board9.config(text='X')


    def placeO():
        board1.config(text='O')
        board2.config(text='O')
        board3.config(text='O')
        board4.config(text='O')
        board5.config(text='O')
        board6.config(text='O')
        board7.config(text='O')
        board8.config(text='O')
        board9.config(text='O')
    gameWindow.mainloop()

    if board1 and board2 and board3 == 'X':
        print("YEAH")


Startwindow.iconbitmap(r'C:\Users\Joshua Brown\Desktop\tic tac toe\tictactoe_H4a_icon.ico')
startButton = tk.Button(Startwindow, text = "Start Game", command = start, height = 1, width = 20, bg = '#ff3333')
startButton.config(font =("helvectia", 20))
startButton.grid()
exitButton = tk.Button(Startwindow, text = "Exit Game", command = exe, height = 1, width = 20, bg = '#ff3333')
exitButton.config(font =("helvectia", 20))
exitButton.grid()
Startwindow.configure(background = "white")

Startwindow.mainloop()

【问题讨论】:

  • 您的代码如何跟踪轮到谁(或如何确定)?
  • 这是一个很好的观点,我认为我正在向后做这件事,我知道这没有多大意义。我在想也许最简单的方法是使用随机库并将它们放入列表中以确定第一次去。从那里我希望在命令部分有一种方法可以在两者之间切换,所以如果可能的话,调用一次函数 A 和下一次函数 B?
  • 我建议将其存储在变量(或类实例属性)中以便于访问。您可以随意初始化变量的值(例如使用random 模块)。如果存在这样的变量,您可以轻松地为 command= 参数创建一个 lambda 函数来做正确的事情。
  • 啊,我明白你的意思了。现在想起来似乎很容易,我觉得有点傻哈哈。感谢您的宝贵时间。
  • 不要使用lambda。让按钮调用命令。将您想要的任何逻辑放入该命令中。

标签: python function user-interface button tkinter


【解决方案1】:

像这样使用带有 lambda 的示例方式:

test_button = Button(text="your_text_button", command=lambda:[placeX(),placeO()])

【讨论】:

    【解决方案2】:

    问题在于placeX 和placeO 函数。你看,你所有的按钮都指向一个函数(changeX/changeY),它将所有按钮更改为 X 或 Y。

    def placeX():
        board1.config(text='X') #changes 1st button to x
        board2.config(text='X')
        board3.config(text='X')
        board4.config(text='X')
        board5.config(text='X')
        board6.config(text='X')
        board7.config(text='X')
        board8.config(text='X')
        board9.config(text='X') #and all the rest above it non-selectively, one click = change all
    

    相反,您应该为每个按钮提供单独的功能

    board1_placeX():
        board1.config(text='X') #changes only one of them
    
    board2_placeX():
        board2.config(text='Y')
    
    ...and so on, define 9 of these, and another nine for placeO(), like board1_placeO() and so on
    

    当您定义板按钮时,请使用特定功能,例如,如果我定义板一,我将使用 board1_placeX()/board1_placeO()

    board1 = tk.Button(gameWindow, text = "1", command = lambda:[board1_placeX(), board1_placeO()], height = 10, width = 20)
    board1.grid(row=0, column=0)
    

    对于板 2...

    board2 = tk.Button(gameWindow, text = "1", command = lambda:[board2_placeX(), board2_placeO()], height = 10, width = 20)
    board2.grid(row=0, column=0)
    

    ...等等。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2019-06-23
      • 2013-08-21
      • 1970-01-01
      • 1970-01-01
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      相关资源
      最近更新 更多