Python - клавиатурный модуль - проблема с многопоточностью - PullRequest
0 голосов
/ 12 апреля 2020


Привет всем,
Я работаю над приложением и пытаюсь создать корректор и использую модуль клавиатуры для коррекции.
Я создал два класса: один монитор клавиатуры, который считывает нажатые события и отображает их на экране, а другой - подавляет их.
Я хочу добиться того, чтобы приложение исправляло ввод пользователя, каждый набранный текст пользователем подавляется и сохраняется в переменной для дальнейшего использования.
Я борюсь за синхронизацию всего этого.

import keyboard
import threading
import time

lock_for_listening_to_keyboard = threading.Lock()

#########################################################
def delete_and_write(times_to_delete, word_to_write):
    global lock_for_listening_to_keyboard

    time.sleep(2)
    print("OK")
    # for i in range(50):
    #     keyboard.write('*')
    # for i in range(times_to_delete+1):
    #     keyboard.press_and_release('backspace')

    # for i,char in enumerate(word_to_write):
    #     keyboard.write(char.upper())

    # for i in range(40):
    #     keyboard.write('*')

    # keyboard.write(' ')


#########################################################


class keyboard_not_suppressed_monitor(threading.Thread):

    def __init__(self, threadID,  keyboardSupress):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.fstring = ""
        self.counter_for_key_presses = 0
        self.suppressed = False

    def run(self):

        while(True):
            event = keyboard.read_event(suppress=self.suppressed)

            if (event.event_type == keyboard.KEY_DOWN):
                # print("Key pressed = {} + suppress = {}".format(event.name, self.suppressed))

                if (event.name == "space"):

                    suppressed_monitoring = keyboard_suppressed_monitor(2, self.fstring, self.counter_for_key_presses, None)
                    suppressed_monitoring.start()
                    suppressed_monitoring.join()

                    print("RETURNED TO MAIN MONITOR")
                    self.counter_for_key_presses = 0
                    self.fstring = ""
                elif (event.name in "abcdefghijklmnopqrstuvwxyz"):
                    self.fstring = ''.join([self.fstring, event.name])
                    self.counter_for_key_presses += 1



class keyboard_suppressed_monitor(threading.Thread):

    def __init__(self, threadID, fstring, counter_for_key_presses, keyboardSupress):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.fstring = fstring
        self.counter_for_key_presses = counter_for_key_presses
        self.suppressed = True
        self.done = False
        self.temp = ""

    def stop(self):
        self._is_running = False


    def run(self):

        self.temp = self.fstring
        self.fstring = ""
        thread_delete_and_rewrite = threading.Thread(
            target = delete_and_write, args=(self.counter_for_key_presses, self.temp))
        thread_delete_and_rewrite.start()
        # thread_delete_and_rewrite.join() # join is not here
        print("RETURNED FROM THE REWRITER")

        while(True):
            print("STATE OF THREAD IS : {}".format(thread_delete_and_rewrite.is_alive()))          print("IN THE WHILE TRUE")

            event = keyboard.read_event(suppress=self.suppressed)

            if (event.event_type == keyboard.KEY_DOWN):
                print("KEYS PRESSED WHILE SUPPRESSED = {}".format(event.name))
                if (event.name == "space"):
                    print("THE STRING ENTERED ")
                    self.temp = self.fstring
                    self.fstring = ""
                    thread_delete_and_rewrite = threading.Thread(
                            target = delete_and_write, args=(self.counter_for_key_presses, self.temp))
                    thread_delete_and_rewrite.start()

                    self.counter_for_key_presses = 0
                    self.fstring = ""
                elif (event.name in "abcdefghijklmnopqrstuvwxyz"):
                    self.fstring = ''.join([self.fstring, event.name])
                    self.counter_for_key_presses += 1
        # thread_delete_and_rewrite.join() # join is not here
        print("SUPPRESSED ENDED")
        self._is_running = False


if __name__ == "__main__":
    kb = keyboard_not_suppressed_monitor(1, None)
    kb.start()
    kb.join()

Я пытаюсь вернуть управление, когда функция исправления сделано, но не может заставить его работать.
Любая помощь приветствуется.

* ОБНОВЛЕНИЕ 1 * Я сделал один класс для всех и работает почти идеально.
У меня есть одна маленькая проблема: когда второе время l oop заканчивается, для выхода требуется нажатие клавиши. Есть ли решение для этого.

import keyboard
import threading
import time

lock_for_listening_to_keyboard = threading.Lock()
global running_suppressed_monitor 
running_suppressed_monitor = False

#########################################################
def delete_and_write(times_to_delete, word_to_write):
    global running_suppress_monitor
    print("---Deleting & Rewrite Started---")
    time.sleep(2)
    running_suppressed_monitor = False
    print("---Deleting & Rewrite Ended---")
    # for i in range(times_to_delete+1):
    #     keyboard.press_and_release('backspace')

    # for i,char in enumerate(word_to_write):
    #     keyboard.write(char.upper())

    # keyboard.write(' ')   


def write_the_suppressed_string(string):
    keyboard.write(string)
#########################################################

class keyboard_monitor(threading.Thread):
    def __init__(self,thread_name, threadID, word_typed,  keyboard_suppress, counter_for_key_pressed):
        threading.Thread.__init__(self)
        self.name = thread_name
        self.threaID = threadID
        self.fstring = word_typed
        self.counter_for_key_presses = counter_for_key_pressed
        self.suppressed = keyboard_suppress
        self.temp = ""

    def stop(self):
        self._is_running = False

    def run(self):

        if (self.suppressed is False):

            while(True):

                event = keyboard.read_event(suppress = self.suppressed)

                if (event.event_type == keyboard.KEY_DOWN):

                    if (event.name == "space"):

                        suppressed_monitor = keyboard_monitor("suppressed_monitor", 2, self.fstring, True, self.counter_for_key_presses)
                        suppressed_monitor.start()
                        suppressed_monitor.join()

                        print("RETURNED TO MAIN MONITOR")
                        self.counter_for_key_presses = 0
                        self.fstring = ""
                    elif (event.name in "abcdefghijklmnopqrstuvwxyz"):
                        self.fstring = ''.join([self.fstring, event.name])
                        self.counter_for_key_presses += 1

        elif (self.suppressed is True):

            self.temp = self.fstring
            self.fstring = ""
            thread_delete_and_rewrite = threading.Thread(
                target = delete_and_write, args=(self.counter_for_key_presses, self.temp))
            thread_delete_and_rewrite.start()

            running_suppressed_monitor = True
            # while(thread_delete_and_rewrite.is_alive()):
            while(running_suppressed_monitor):

                event = keyboard.read_event(suppress=self.suppressed)

                if (event.event_type == keyboard.KEY_DOWN):
                    print("KEYS PRESSED WHILE SUPPRESSED = {}".format(event.name))
                    if (event.name == "space"):
                        self.temp = self.fstring
                        self.fstring = ""
                        thread_delete_and_rewrite = threading.Thread(
                                target = delete_and_write, args=(self.counter_for_key_presses, self.temp))
                        thread_delete_and_rewrite.start()
                        # thread_delete_and_rewrite.join()
                        self.counter_for_key_presses = 0
                        self.fstring = ""
                    elif (event.name in "abcdefghijklmnopqrstuvwxyz"):
                        self.fstring = ''.join([self.fstring, event.name])
                        self.counter_for_key_presses += 1
                    # NO thread_delete_and_rewrite.join()
                # NO thread_delete_and_rewrite.join()

                if (thread_delete_and_rewrite.is_alive() is False):
                    break


            thread_delete_and_rewrite.join()
            print("SELF.FSTRING = {}".format(self.fstring))

            print("BEFORE END OF SUPPRESSED MONITOR")

            if (self.fstring != ""):
                thread_write = threading.Thread(
                                target = write_the_suppressed_string, args=(self.fstring, ))
                thread_write.start()
                thread_write.join()
            print("SUPPRESSED ENDED")
            self._is_running = False


if __name__ == "__main__":
    kb_not_suppressed = keyboard_monitor("not_suppressed_monitor", 1, "", False, 0)
    kb_not_suppressed.start()
    kb_not_suppressed.join()
...