Search code examples
pythontkinterpyhook

Tkinter bind does not call funtion


I am trying to change the text in a tkinter entry widget, to be the key combination entered by the user(example: ShiftL+ShiftR), the python program runs fine, but does not change entry, why and how can i fix it? My GUI:

 # Program by Fares Al Ghazy started 20/5/2017
# Python script to assign key combinations to bash commands, should run in the background at startup
# Since this program is meant to release bash code, it is obviously non-system agnostic and only works linux systems that use BASH
# This is one file which only creates the GUI, another file is needed to use the info taken by this program

FileName  = 'BinderData.txt'
import tkinter as tk
from ComboDetect import ComboDetector

# Create a class to get pressed keys and print them
KeyManager = ComboDetector()


# Class that creates GUI and takes info to save in file

class MainFrame(tk.Tk):
    # variable to store pressed keys
    KeyCombination = ""

    def KeysPressed(self, Entry, KeyCombination):
        KeyCombination = KeyManager.getpressedkeys()
        Entry.delete(0, tk.END)
        Entry.insert(0, KeyCombination)

    # constructor

    def __init__(self, FileName, **kwargs):
        tk.Tk.__init__(self, **kwargs)
        # create GUI to take in key combinations and bash codes, then save them in file
        root = self  # create new window
        root.wm_title("Key binder")  # set title
        #  create labels and text boxes
        KeyComboLabel = tk.Label(root, text="Key combination = ")
        KeyComboEntry = tk.Entry(root)

        # Bind function to entry

        KeyComboEntry.bind('<FocusIn>',self.KeysPressed(KeyComboEntry, self.KeyCombination))

        KeyComboEntry.grid(row=0, column=1)
        ActionEntry.grid(row=1, column=1)
        # create save button
        SaveButton = tk.Button(root, text="save",
                               command=lambda: self.SaveFunction(KeyComboEntry, ActionEntry, FileName))
        SaveButton.grid(row=2, column=2, sticky=tk.E)


app = MainFrame(FileName)
app.mainloop()

and ComboDetect:

   #this program was created by LadonAl (Alaa Youssef) in 25.May.17
    #it detects a combination of pressed key and stores them in a list and prints the list when at least
    # one of the keys is released

import time
import pyxhook

class ComboDetector(object):
    def getpressedkeys(self):
        return self.combo

Edit: I've changed the keyspressed function to test it

 def KeysPressed(self, Entry, KeyCombination):
        Entry.config(state="normal")
        Entry.insert(tk.END, "Test")
        print("test")
        KeyCombination = KeyManager.getpressedkeys()
        Entry.delete(0, tk.END)
        Entry.insert(tk.END, KeyCombination)

This is what I have noticed: When the module is run, "test" is printed to console, nothing else happens. When i try to click outside of the entry widget and click inside it again (exit focus and re-enter it), nothing happens


Solution

  • The problem is that when you attempt to bind to KeyComboEntry, you are calling the procedure KeysPressed, rather than passing bind the method for KeyComboEntry, you can fix this by using KeyComboEntry.bind("<Key>", self.KeysPressed, KeyComboEntry, self.KeyCombination). Bind will then call KeysPressed with the arguments of KeyComboEntry and self.KeyCombination. The other alternative is to use a lambda function, as you have used for SaveButton, accounting for bind passing it an event.