Home > database >  How to not allow clicks on a specifc area in Tkinter?
How to not allow clicks on a specifc area in Tkinter?

Time:04-17

Hi guys i'm new to Python, could you please teach me how to not allow clicks in a specific area in Tkinter? I created this window and is a calculator with buttons that i made, how to ignore the clicks only in the grey zone? I want that if the users clicks the grey area nothing happens because now if i click the grey area the strings become underlined ecc, how to ignore the clicks? The grey zone is a simple Listbox which contains the history of my calculations written in strings.

This is the code, i created Listbox in the cronologia variable in the last lines of code:

    from tkinter import *
total = ""
def button_press(num):
    global  equation_text
    equation_text = equation_text   str(num)
    equation_lable.set(equation_text)
    if equation_text.count("  ") or equation_text.count(" -") or equation_text.count(" *") or equation_text.count(" /") or equation_text.count("- ") or equation_text.count("--") or equation_text.count("-*") or equation_text.count("-/") or equation_text.count("* ")  or equation_text.count("**") or equation_text.count("*/") or equation_text.count("/ ") or equation_text.count("/*") or equation_text.count("//"):
        equation_lable.set("Errore")
        equation_text=""
def elimina_cronologia(*args):
   cronologia.delete(0,END)
def cancella(*args):
    global equation_text
    equation_text = equation_text[:-1]
    equation_lable.set(equation_text)
def equals(*args):
    global equation_text
    global total
    try:
        total = total   equation_text
        total = eval(total)
        total = float(total)
        total = round(total,3)
        equation_lable.set(total)
        total = str (total)
        cronologia.insert(0," "  equation_text   " = "   total)
        equation_text = ""
    except ZeroDivisionError:
        equation_lable.set("Errore")
        equation_text = ""
    except SyntaxError:
        equation_lable.set("Errore")
        equation_text = ""
def clear(*args):
    global  equation_text
    global  total
    equation_lable.set("")
    equation_text=""
    total = ""
window = Tk()
window.resizable(width=False, height=False)
window.title("Calcolatrice")
window.geometry("643x390")
equation_text = ""
equation_lable = StringVar()
label = Label(window, textvariable=equation_lable, font=("consolas", 20), bg="#1C7B00", fg="white", width=22, height=2)
label.place(x=-45, y=0)
bottone01= Button(window, text= "7", font= ('Helvetica 20 '),width=5,height=1,bg="#008BC7", command=lambda:button_press("7"))
bottone01.configure(activebackground="#00A1E6")
bottone01.place(x=-11, y=80)
bottone02= Button(window, text= "8", font= ('Helvetica 20 '),width=4,height=1,bg="#008BC7", command=lambda:button_press("8"))
bottone02.configure(activebackground="#00A1E6")
bottone02.place(x=80, y=80)
bottone03= Button(window, text= "9", font= ('Helvetica 20 '),width=4,height=1,bg="#008BC7", command=lambda:button_press("9"))
bottone03.configure(activebackground="#00A1E6")
bottone03.place(x=165, y=80)
bottone04= Button(window, text= "-", font= ('Helvetica 20 '),width=3,height=1,bg="#FF9D12", command=lambda:button_press("-"))
bottone04.configure(activebackground="#FFB245")
bottone04.place(x=250, y=80)
bottone05= Button(window, text= "4", font= ('Helvetica 20 '),width=5,height=1,bg="#008BC7", command=lambda:button_press("4"))
bottone05.configure(activebackground="#00A1E6")
bottone05.place(x=-11, y=140)
bottone06= Button(window, text= "5", font= ('Helvetica 20 '),width=4,height=1,bg="#008BC7", command=lambda:button_press("5"))
bottone06.configure(activebackground="#00A1E6")
bottone06.place(x=80, y=140)
bottone07= Button(window, text= "6", font= ('Helvetica 20 '),width=4,height=1,bg="#008BC7", command=lambda:button_press("6"))
bottone07.configure(activebackground="#00A1E6")
bottone07.place(x=165, y=140)
bottone08= Button(window, text= " ", font= ('Helvetica 20 '),width=3,height=1,bg="#FF9D12", command=lambda:button_press(" "))
bottone08.configure(activebackground="#FFB245")
bottone08.place(x=250, y=140)
bottone09= Button(window, text= "1", font= ('Helvetica 20 '),width=5,height=1,bg="#008BC7", command=lambda:button_press("1"))
bottone09.configure(activebackground="#00A1E6")
bottone09.place(x=-11, y=200)
bottone10= Button(window, text= "2", font= ('Helvetica 20 '),width=4,height=1,bg="#008BC7", command=lambda:button_press("2"))
bottone10.configure(activebackground="#00A1E6")
bottone10.place(x=80, y=200)
bottone11= Button(window, text= "3", font= ('Helvetica 20 '),width=4,height=1,bg="#008BC7", command=lambda:button_press("3"))
bottone11.configure(activebackground="#00A1E6")
bottone11.place(x=165, y=200)
bottone12= Button(window, text= "x", font= ('Helvetica 20 '),width=3,height=1,bg="#FF9D12", command=lambda:button_press("x"))
bottone12.configure(activebackground="#FFB245")
bottone12.place(x=250, y=200)
bottone13= Button(window, text= ",", font= ('Helvetica 20 '),width=5,height=1,bg="#008BC7", command=lambda:button_press("."))
bottone13.configure(activebackground="#00A1E6")
bottone13.place(x=-11, y=260)
bottone14= Button(window, text= "0", font= ('Helvetica 20 '),width=4,height=1,bg="#008BC7", command=lambda:button_press("0"))
bottone14.configure(activebackground="#00A1E6")
bottone14.place(x=80, y=260)
bottone15= Button(window, text= "=", font= ('Helvetica 20 '),width=4,height=1,bg="#008BC7", command=equals)
bottone15.configure(activebackground="#00A1E6")
bottone15.place(x=165, y=260)
bottone16= Button(window, text= "/", font= ('Helvetica 20 '),width=3,height=1,bg="#FF9D12", command=lambda:button_press("/"))
bottone16.configure(activebackground="#FFB245")
bottone16.place(x=250, y=260)
bottone17= Button(window, text= "Cancella", font= ('Helvetica 23 '),width=10,height=1,bg="#008BC7", command=clear)
bottone17.configure(activebackground="#00A1E6")
bottone17.place(x=-20, y=320)
bottone18= Button(window,width=60,height=69, font= ('Helvetica 20 '),bg="#008BC7", command=elimina_cronologia)
bottone18.configure(activebackground="#00A1E6")
bottone18.place(x=250, y=320)
bottone19= Button(window,width=54,height=69, font= ('Helvetica 20 '),bg="#008BC7", command=cancella)
bottone19.configure(activebackground="#FFB245")
bottone19.place(x=190, y=320 )
window.bind("0", lambda _: button_press(0))
window.bind("1", lambda _: button_press(1))
window.bind("2", lambda _: button_press(2))
window.bind("3", lambda _: button_press(3))
window.bind("4", lambda _: button_press(4))
window.bind("5", lambda _: button_press(5))
window.bind("6", lambda _: button_press(6))
window.bind("7", lambda _: button_press(7))
window.bind("8", lambda _: button_press(8))
window.bind("9", lambda _: button_press(9))
window.bind(" ", lambda _: button_press(" "))
window.bind("-", lambda _: button_press("-"))
window.bind("*", lambda _: button_press("*"))
window.bind("/", lambda _: button_press("/"))
window.bind(".", lambda _: button_press("."))
window.bind("<Down>", elimina_cronologia)
window.bind("<Return>", equals)
window.bind("<BackSpace>", clear)
window.bind("<Left>", cancella)
scrollbar = Scrollbar(window)
scrollbar.pack(side=RIGHT, fill=Y)
cronologia = Listbox(window)
cronologia.pack()
cronologia.place(x=315,y=0)
cronologia.configure(font=('Helvetica 20 '),width=17,height=10,bg="#4a4a4a", fg="#dedede")
cronologia.config(yscrollcommand=scrollbar.set)
scrollbar.config(command=cronologia.yview)
window.mainloop()

Thanksenter image description here

CodePudding user response:

To prevent the text in a Listbox from getting underlined and highlighted, you must disable the default functionality when an item in a listbox is clicked (<Button-1>) or when the user drags (<Motion>) the mouse over an item or when the pointer is moved out of the listbox (<Leave>).

Therefore, you must bind the listbox to a function (onCronologiaSelect) which returns "break" for all the events - <Button-1>, <Motion> and <Leave>.


Why do we return "break"?

In tkinter, an event can be bound to multiple event handlers (functions). These event handlers have an order of execution. To stop tkinter from executing the next handler in the queue, the current handler must return "break". Note that this is not equivalent to break which is used to exit a loop.

As onCronologiaSelect returns "break", the default handler which underlines/highlightes an item is not executed.


Solution:

def onCronologiaSelect(event):
    return "break"

cronologia = Listbox(window)
cronologia.place(x=315,y=0)
cronologia.configure(font=('Helvetica 20 '),width=17,height=10,bg="#4a4a4a", fg="#dedede",yscrollcommand=scrollbar.set)
cronologia.bind('<Button-1>', onCronologiaSelect)
cronologia.bind('<Motion>', onCronologiaSelect)
cronologia.bind('<Leave>', onCronologiaSelect)

Alternatively, lambda can be used as follows:

cronologia.bind('<Button-1>', lambda e: "break")
cronologia.bind('<Motion>', lambda e: "break")
cronologia.bind('<Leave>', lambda e: "break")


Alternative Approach:

Instead of individually disabling the default class bindings, you can directly remove the class tag ('Listbox') from the binding tags as shown below:

bind_tags = list(cronologia.bindtags())
bind_tags.remove('Listbox')
cronologia.bindtags(bind_tags)

From https://tkdocs.com/shipman/universal.html :

w.bindtags(tagList=None)

If you call this method, it will return the “binding tags” for the widget as a sequence of strings. A binding tag is the name of a window (starting with '.') or the name of a class (e.g., 'Listbox').

You can change the order in which binding levels are called by passing as an argument the sequence of binding tags you want the widget to use.

  • Related