简体   繁体   中英

How to get a label to appear on button press in python 3's tkinter

I'm attempting to write a noughts and crosses program and want it to be that when a button is pressed the button disappears and a label appears in its place, however, when i run the code as seen below the buttons disappear but the labels do not appear, any help will be appreciated and i apologize if this is a duplicate question but while searching for and answer i couldn't find an appropriate thread.

import sys

from tkinter import *

def hide_me(event):
    event.widget.place_forget()

def play(row, column):
    holdx = int()
    holdy = int()
    if row == 'A':
        holdx = 100
    elif row == 'B':
        holdx = 200
    elif row == 'C':
        holdx = 300
    else:
        print('FATAL ERROR')
    if column == 1:
        holdy = 100
    elif column == 2:
        holdy = 200
    elif column == 3:
        holdy = 300
    else:
        print('FATAL ERROR')
    placement = Label(text='HI').place(x=holdx,y=holdy)

mGui = Tk()

mGui.geometry('400x400')

mGui.configure(bg='#FFFFFF')

mGui.title('Noughts and Crosses')

mLabel= Label(text='Noughts and Crosses', bg='#FFFFFF').place(x=160,y = 50)

A1 = Button(mGui, text='A1', command = lambda: play('A', 2))

A1.bind('<Button-1>', hide_me)

A1.place(x=100,y=100)

A2 = Button(mGui, text='A2', command = lambda: play('A', 2))

A2.bind('<Button-1>', hide_me)

A2.place(x=200,y=100)

A3 = Button(mGui, text='A3', command = lambda: play('A', 3))

A3.bind('<Button-1>', hide_me)

A3.place(x=300,y=100)

B1 = Button(mGui, text='B1', command = lambda: play('B', 1))

B1.bind('<Button-1>', hide_me)

B1.place(x=100,y=200)

B2 = Button(mGui, text='B2', command = lambda: play('B', 2))

B2.bind('<Button-1>', hide_me)

B2.place(x=200,y=200)

B3 = Button(mGui, text='B3', command = lambda: play('B', 3))

B3.bind('<Button-1>', hide_me)

B3.place(x=300,y=200)

C1 = Button(mGui, text='C1', command = lambda: play('C', 1))

C1.bind('<Button-1>', hide_me)

C1.place(x=100,y=300)

C2 = Button(mGui, text='C2', command = lambda: play('C', 2))

C2.bind('<Button-1>', hide_me)

C2.place(x=200,y=300)

C3 = Button(mGui, text='C3', command = lambda: play('C', 3))

C3.bind('<Button-1>', hide_me)

C3.place(x=300,y=300)

mGui.mainloop()

Thanks in advance to anyone who answers my question.

Problem is because you use bind('<Button-1>', ...) which catch click and button doesn't execute function assigned with command=

Use only command= and send widget to play()

import tkinter as tk

# --- functions ---

def play(x, y, widget):

    widget.place_forget()

    l = tk.Label(root, text='HI')
    l.place(x=x,y=y)

# --- main ---

root = tk.Tk()
root.geometry('400x400')
root.configure(bg='#FFFFFF')
root.title('Noughts and Crosses')

l = tk.Label(text='Noughts and Crosses', bg='#FFFFFF')
l.place(x=160,y = 50)

for r, row in enumerate(('A', 'B', 'C'), 1):
    for c, col in enumerate(('1', '2', '3'), 1):
        name = row + col
        x = c*100
        y = r*100
        b = Button(root, text=name)
        b['command'] = lambda x0=x,y0=y,b0=b: play(x0, y0, b0)
        b.place(x=x, y=y)

root.mainloop()

I use for loop to make it simpler but lambda used in for need x0=x,y0=y,b0=b to send correctly arguments to play

lambda x0=x,y0=y,b0=b: play(x0, y0, b0)

BTW: if you use

var = Widget(...).place(...)
var = Widget(...).grid(...)
var = Widget(...).pack(...)

then you assign None to var because place()/grid()/pack() returns None .

You have to do it in two steps

var = Widget(...)
var.place(...)

var = Widget(...)
var.grid(...)

var = Widget(...)
var.pack(...)

or if you don't need var

Widget(...).place(...)
Widget(...).grid(...)
Widget(...).pack(...)

Replacing a single button with a label is easy. Slightly harder is replacing any of several buttons with a label. This requires packaging together information required to access a particular button with the generic replacement function.

import tkinter as tk
root = tk.Tk()

def replace_at(i,j):
    items[i][j].grid_forget()
    label = tk.Label(root, text='Label {}, {}'.format(i,j))
    label.grid(row=i, column=j)
    items[i][j] = label

items = []
for i in range(3):
    row = []
    for j in range(3):
        button = tk.Button(root, text='Button {}, {}'.format(i,j),
                           command=lambda i=i, j=j: replace_at(i,j))
        button.grid(row=i, column=j)
        row.append(button)
    items.append(row)

root.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM