Make Python keyboard library not block the current thread? - python

I'm trying to create a keylogger using the Python keyboard library. Currently I have a start function like this:
def start(self):
# record the start datetime
self.start_dt = datetime.now()
# start the keylogger
keyboard.on_release(callback=self.callback)
# make a simple message
print(f"{datetime.now()} - Started keylogger")
# block the current thread, wait until CTRL+C is pressed
keyboard.wait("esc")
self.report()
In my application when I click a button it creates a KeyLogging object and calls this start function. However, when I click the button it freezes my application because this keyboard.wait method blocks the main thread until this keyboard thread finishes executing. Is there a way to not block the main thread and have this work in the background like an actual keylogger? I'd still like it to exit when "esc" is pressed. Thanks!

Related

keyboard module thread cant be closed at application exit

I am creating a hotkey as follows:
import keyboard
keyboard.add_hotkey ('win+esc', close_application)
The close_application function is what the hotkey calls is:
def close_application ():
keyboard.unhook_all_hotkeys()
sys.exit()
Problem:
Application never exist, as a sub thread creating automatically by keybard.hotkey function, never closes:
I tried all different ways to exit from the application as well as some other methods of keyboard module to release the hotkey, but none was successful.
May I ask if you have any idea how can i force to close the thread opened by the keyboard module ?

Does an event loop keep running the program's code in PyQt/PySide?

I know that when creating a QApplication, an evet loop is created.
Does this mean that application will keep running the codes for ever untill it's terminated?
I was trying to call a slot in my Main class constructor and i wondered if that slot would keep executing since there is an event loop thus the Main class would be instantialized for ever.
How am i wrong? Why is the consructor method run only once?
The event loop is just an infinite loop that pulls events off of a queue and processes them.
def exec_():
while True:
event = event_queue.get()
process_event(event)
The event loop is run when you call the "exec_()" method. When you click or interact with the GUI you are putting an event on the event queue. Qt internally processes that event.
You will also notice that a long running button click will halt the GUI. Everything is running synchronously. When a button is clicked that event is being processed. No other events are processed while that event is running.
import time
from PySide2 import QtWidgets
app = QtWidgets.QApplication([])
def halt_10_sec():
time.sleep(10) # Stay here for 10 seconds
btn = QtWidgets.QPushButton('Halt')
btn.clicked.connect(halt_10_sec)
btn.show()
app.exec_() # Run forever until app.quit()
# You will not get here until all windows are closed and the application is exiting.
print('Here')
Once you click the button you will not be able to resize the window, move the window, highlight the button on hover, or any other events while the button event is running.
A slot is just a function. You should be able to call a slot in the constructor.

Backgroundworker in python

I'm an inexperienced python programmer.
Is there a way to use the backgroundworker so that it starts at program startup and closes when program close?
I want it to watch a button, the button returns 1 when pressed. So while the program in running whenever button = 1 button has to do "this".
Can anyone help me with this?
Would make sense to start a separate thread within your main program and do anything in the background. As an example check the fairly simple code below:
import threading
import time
#Routine that processes whatever you want as background
def YourLedRoutine():
while 1:
print 'tick'
time.sleep(1)
t1 = threading.Thread(target=YourLedRoutine)
#Background thread will finish with the main program
t1.setDaemon(True)
#Start YourLedRoutine() in a separate thread
t1.start()
#You main program imitated by sleep
time.sleep(5)
As of Python 3.3, the Thread constructor has a daemon argument. Konstantin's answer works, but I like the brevity of needing only one line to start a thread:
import threading, time
MAINTENANCE_INTERVAL = 60
def maintenance():
""" Background thread doing various maintenance tasks """
while True:
# do things...
time.sleep(MAINTENANCE_INTERVAL)
threading.Thread(target=maintenance, daemon=True).start()
As the documentation mentions, daemon threads exit as soon as the main thread exit, so you still need to keep your main thread busy while the background worker does its thing. In my case, I start a web server after starting the thread.

How to stop a running python script

I created a GUI with PyQt which implements the buttons "Start" and "Stop".
When I click on "Start" a huge python Script is started. The function of "Stop" has to end this python script, but when I start the script it runs and I can't stop it. I even can't activate anything else on the GUI and I get no reaction from it. So i have to wait the long time until the python script ends.
How can I implement the methods so that I can interrupt the script with the "Stop" button even when I want?
Since you do everything in the QButton.clicked signal, your GUI locks up until you exit that function.
My solution i used in a small project was to seperate it into a GUI and worker process.
Use multiprocessing.Process to do your processing and have it send the results over a multiprocessing.Pipe.
The worker also has a second Pipe to recieve commands (my project just uses one command - exit)
In the GUI, you create 2 Pipes: one for results, one for commands.
Initialize the worker with both pipes and start the process.
The next step would be to have a QTimer poll the pipe for results and display them.
By doing so, your UI stays responsive while the calculations happen in the background.

How to make a event run immediately after a GUI program starts in wxpython?

I'm working on a GUI program in which I already bind a start button with one event, and when I click the start button, the event runs as I like. My question is, if I want my program to start the event immediately after the GUI program starts, which means the start button is immediately being "clicked" once the program starts, how do I do it?
In the main frame constructor set a one-shot timer with interval 0 that fires the event.
In the __init__( ) for your main frame put this:
wx.CallAfter( func_name )

Categories

Resources