Disable mouse double click event in tkinter - python-3.x

I am thinking about disabling the mouse double click event after one event. If i double click on an item from the list box the event disables until i press the Enable Double click button. How to archive this?
from tkinter import *
def go(event):
cs = Lb.curselection()
# Updating label text to selected option
w.config(text=Lb.get(cs))
# Setting Background Colour
for list in cs:
if list == 0:
top.configure(background='red')
elif list == 1:
top.configure(background='green')
elif list == 2:
top.configure(background='yellow')
elif list == 3:
top.configure(background='white')
top = Tk()
top.geometry('250x275')
top.title('Double Click')
# Creating Listbox
Lb = Listbox(top, height=6)
# Inserting items in Listbox
Lb.insert(0, 'Red')
Lb.insert(1, 'Green')
Lb.insert(2, 'Yellow')
Lb.insert(3, 'White')
# Binding double click with left mouse
# button with go function
Lb.bind('<Double-1>', go)
Lb.pack()
# Creating Edit box to show selected option
w = Label(top, text='Default')
w.pack()
# Creating Enable button to enable double clicking
enable_btn = Button(top, text = 'Enable Double Click')
enable_btn.pack(pady = 10)
top.mainloop()

To disable double-click, bind to that event and then have your function return the string "break". You can use a variable to trigger that behavior.
Start by defining a flag, and then a function that can set the flag:
double_click_enabled = False
def enable_double_clicking(enable):
global double_click_enabled
double_click_enabled = enabled
Next, define your button to call this function. In this example I'll show two buttons for enabling and disabling:
enable_btn = Button(top, text = 'Enable Double Click', command=lambda: enable_double_clicking(True))
disable_btn = Button(top, text = 'Disable Double Click', command=lambda: enable_double_clicking(False))
Finally, check for the flag at the top of your go function. If double-clicking is disabled, return the string "break" which prevents the result of the function from executing and also disables any default behavior.
def go(event):
if not double_click_enabled:
return "break"
...

Related

tkinter radiobutton event when variable change

I am a beginner in tkinter, and I reach a trouble.
I would like to have a radio button group which enable or disable some buttons, scales, ..., in function of which radio button is selected. Those button group are connected to a variable. To disable/enable widgets, I use button group command. Everything works when I click on radio buttons. But if the variable changed, the radio button changed without calling the radio command, so other widgets are not updated.
Here is a very simple code of what I want to do
from tkinter import ttk
import tkinter as tk
root = tk.Tk()
frame = ttk.LabelFrame(root, text='choice your futur')
frame.pack(fill="both", expand="yes", padx=5, pady=5)
selection = tk.IntVar()
def onButtonClic():
selection.set(1)
bt = tk.Button(frame, text='continue', command=onButtonClic)
bt.grid(column=0, row=1, columnspan=2, sticky='ew')
def onRadioButtonChange():
if selection.get() != 0:
bt.configure(state = tk.DISABLED)
else:
bt.configure(state = tk.NORMAL)
tk.Radiobutton(frame, command=onRadioButtonChange, text = "blue pill", variable = selection, value = 0).grid(column=0, row=0, sticky='nw')
tk.Radiobutton(frame, command=onRadioButtonChange, text = "red pill", variable = selection, value = 1).grid(column=1, row=0, sticky='nw')
root.mainloop()
If I select the red pill, button is disabled. When blue pill is selected, and click on button (which set radio variable to 1: the red pill value), the red pill is selected, but button is still enable.
I would like when the variable changed, then the radio command be called.
Best regards
JM
You can use tkinter variable .trace_add() function instead:
...
def onRadioButtonChange(*args):
if selection.get() != 0:
bt.configure(state = tk.DISABLED)
else:
bt.configure(state = tk.NORMAL)
# call onRadioButtonChange() when the variable is updated
selection.trace_add('write', onRadioButtonChange)
tk.Radiobutton(frame, text = "blue pill", variable = selection, value = 0).grid(column=0, row=0, sticky='nw')
tk.Radiobutton(frame, text = "red pill", variable = selection, value = 1).grid(column=1, row=0, sticky='nw')
...

tkinter, print text when hovering over OptionMenu objects

So I got to change the colors as well as change colors while hovering over menu objects created using the OptionMenu in tkinter.
I even have text printing when I hover over the button, but the second I drop down the menu, it won't print anymore.
What am I doing wrong? How can I print when you click to open the OptionMenu and and move around through the selections?
from tkinter import *
import tkinter as tk
OZoneIzotopeSemiWhite = "#c0c4ca"
buttonBackground = "#303336"
buttonforeground = "#cdd0d7"
BACKGROUND2 = "#1e1f21"
class DropDownButton():
def __init__(self, parent, placement, opTions, **kw):
self.parent = parent
self.options = opTions
self.om_variable = tk.StringVar(self.parent)
self.om_variable.set(self.options[0])
self.om_variable.trace('w', self.option_select)
self.om = tk.OptionMenu(self.parent, self.om_variable, *self.options)
self.om["menu"].config(fg=buttonforeground, bg=buttonBackground, activebackground=OZoneIzotopeSemiWhite, activeforeground=BACKGROUND2, borderwidth = 0)
self.om.config(fg=buttonforeground, bg=buttonBackground, activebackground=OZoneIzotopeSemiWhite, activeforeground=BACKGROUND2, bd =0)
self.om.place(x = placement, y = 2)
self.om.bind("<Enter>", self.on_enter)
self.om.bind("<Leave>", self.on_leave)
def on_enter(self, event):
if self.om == self.options[0]:
print ("Hello")
elif self.om_variable.get() == self.options[1]:
print ("Hello 2!")
else:
print("Hell0 3!")
def on_leave(self, enter):
print ("leave")
def option_select(self, *args):
print (self.om_variable.get())
root = tk.Tk()
DropDownButton(root, 55, ['one', 'two', 'three'])
root.mainloop()
You're not doing anything wrong as such, but you might need to alter what you do or your expectations. When a menu is popped up by clicking on a menubutton widget — as created by the option menu code — the mouse pointer is grabbed by the menu that has popped up, and this state continues until you do an action that selects something (or you click or release outside the menu, which cancels). Your styling, which depends on the state of the menubutton, might be noticing this and going into something slightly unexpected to you.
By the way, if you pop up the menu using key bindings, the differing look is actually useful as the focus will also be on the actual popup menu.

Problems with Focus

I'm trying to return the focus to the first entry. If you move the focus to the next entry or the button and the you click on the button, the focus returns fine to first entry. When I try doing the same thing by using the tab key, the focus_set method fails. I've tried many different ways, but the result is always the same. Anyone knows why? And might be so kind as to showing me how to do it right? Thanks in advance.
This is what I got so far:
from tkinter import *
w = Tk()
def focus():
box1.focus_set()
def check(event):
if str(event.widget) == '.!entry2':
print('focus back to box1')
focus()
box1 = Entry(w, width=15)
box2 = Entry(w, width=15)
box1.focus_set()
box2.bind('<Tab>', check)
box1.pack()
box2.pack()
btn = Button(w, text='Box 1 Focus', command=focus)
btn.pack()
w.mainloop()
If I run your code, str(event.widget) is something like ".36580648", not ".!entry2". You can give your widget a custom name like
box2 = Entry(w, width=15, name='second')
You can then check if str(event.widget) == '.second'.
Alternatively, you can just check if event.widget == box2: which is easier and less prone to error.
If you do one of these things, you will see that 'focus back to box1' is printed, but the focus is still transferred to the button instead of the label. This is because your custom event is triggered before the default event for <Tab>, which is to move focus to the next widget. You can stop the default event handling by returning 'break' in your function.
The complete example would become:
from tkinter import *
w = Tk()
def focus():
box1.focus_set()
def check(event):
if event.widget == box2:
print('focus back to box1')
focus()
return 'break'
box1 = Entry(w, width=15)
box2 = Entry(w, width=15)
box1.focus_set()
box2.bind('<Tab>', check)
box1.pack()
box2.pack()
btn = Button(w, text='Box 1 Focus', command=focus)
btn.pack()
w.mainloop()

Disable making another TopLevel if it already exists

I have an Instructions Window asTopLevel in my app. For now it looks like:
def instructions(self):
window = Toplevel(takefocus = True)
window.geometry("200x200")
window.resizable(0, 0)
Label(window, text = "WIP").grid()
So it's part of the main class and I define a command to call when the user presses a button in the top menu or presses F3 a shortcut I defined.
What I need is when that window is once there I want it to take focus rather that opening a new one.
It could look like:
if window == exists:
window.takefocus
else:
do the upper and create it ....
also upon destruction in need to know that it hasbeen destoyed, otherwise I'll be able to open it only once
This seems to work:
def instructions(self):
if self.window == None:
self.window = Toplevel(takefocus = True)
self.window.focus()
self.window.geometry("200x200")
self.window.resizable(0, 0)
Label(self.window, text = "WIP").grid()
self.window.protocol("WM_DELETE_WINDOW", self.windowclosed)
else:
self.window.focus()
def windowclosed(self):
self.window.destroy()
self.window = None

Juxtapose a GtkMenuBar with other widgets?

Is it possible to place a GtkMenuBar with other widgets together , instead of showing at the top of that window ?
Or i could use buttons , but when you hover your mouse over those buttons , the menu on the buttons won't just behave like a menu , which is , when you are close to one menu item , the menu pops down directly , without click , and other menu hide automatically. Can i make buttons like that ? Or other widgets that could have: label , image , and pop down menu item is cool.
Any ideas is appreciated.
Maybe the "enter-notify-event" and "leave-notify-event", connected to buttons, may help you do the thing, with for example, a popup menu show and hide respectively.
EDIT
I finally forgot those "enter" and "leave" events whose behaviour was a little complex, and just used the "motion-notify-event"...
Now I hope it is what you want !
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk
class MenuExample:
def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_size_request(200, 100)
self.window.set_title("GTK Menu Test")
self.window.connect("delete_event", lambda w,e: gtk.main_quit())
# A vbox to put a button in:
vbox = gtk.VBox(False, 0)
self.window.add(vbox)
vbox.show()
self.popped = False
# Create a button to simulate a menu
button = gtk.Button("press me")
vbox.pack_start(button, False, False, 2)
self.window.add_events(gtk.gdk.POINTER_MOTION_MASK)
self.window.connect("motion-notify-event", self.wakeup)
self.window.show_all()
self.bmenu = gtk.Button("A single entry menu")
self.bmenu.connect("clicked", self. menuitem_response, "Click on the magic menu !")
vbox.pack_start(self.bmenu, False, False, 2)
def wakeup(self, widget, event):
#print "Event number %d woke me up" % event.type
(x, y) = self.window.get_pointer()
if y < 30:
if self.popped == False:
self.popped = True
self.bmenu.show()
elif y > 60:
if self.popped == True:
self.popped = False
self.bmenu.hide()
# Print a string when a menu item is selected
def menuitem_response(self, widget, string):
print "%s" % string
def main():
gtk.main()
return 0
if __name__ == "__main__":
MenuExample()
main()

Resources