Функция для запуска и остановкиThread? - PullRequest
0 голосов
/ 07 июля 2019

У меня проблема с моей программой. Когда я запускаю свою программу и нажимаю любую клавишу, она печатает «Успешно». Если я нажму кнопку «Пуск» еще раз и нажму любую клавишу, будет напечатано «Успешно» 2 раза, и так далее. 3x 4x 5x .. как я могу решить эту проблему? если я использую join (), моя программа вылетит.

и как я могу остановить прослушиватель, поскольку нет опции stop () ..?

from pynput.keyboard import Listener
from tkinter import *
import threading
from functools import partial

app = Tk()
def press(key):
    keyd = str(key)
    keyd = keyd.replace("Key.space", " ")
    keyd = keyd.replace("'", "")
    with open("doc.docx", "a") as o:
        o.write(keyd)
        print("Succefuly")
def startListener(arg):
    if arg == btStart:
        def subLis():
            with Listener(on_press=press) as l:
                l.join()
        thr = threading.Thread(target=subLis)
        thr.start()

btStart = Button(app, text="Start")
btStart.pack(side=TOP, fill=X)
btStart["command"] = partial(startListener, btStart)

btStop = Button(app, text="Stop")
btStop.pack(side=TOP, fill=X)
btStop["command"] = partial(startListener, btStop)

app.geometry("300x100+900+400")
app.mainloop()

1 Ответ

0 голосов
/ 08 июля 2019

если вы сохраните поток в глобальной переменной, тогда вы можете проверить, существует ли он, и не создавать второй поток.

На данный момент я знаю только один способ остановить поток - использовать некоторую комбинацию клавиш для выполнения return False в press.Это остановит Listener, и это закончит поток.В кодовом ключе ESC останавливает поток.

from pynput.keyboard import Listener, Key
from tkinter import *
import threading
from functools import partial

def press(key):
    keyd = str(key)
    keyd = keyd.replace("Key.space", " ")
    keyd = keyd.replace("'", "")

    with open("doc.docx", "a") as o:
        o.write(keyd)
        print("Succefuly", keyd)

    # stop Listener (and end thread)
    if key == Key.esc:
        return False

def subLis():
    with Listener(on_press=press) as l:
        l.join()

def startListener(arg):
    global thr # inform function to use external variable

    if arg == btStart:
        if thr is None:
            thr = threading.Thread(target=subLis)
            thr.start()
        else:
            print('already running')

    if arg == btStop:
        if thr is None:
            print('not running')
        else:
            print('TODO: stop thread')
            #thr = None

# ---------------------------------------------------------

thr = None

app = Tk()
app.geometry("300x100+900+400")

btStart = Button(app, text="Start")
btStart.pack(side=TOP, fill=X)
btStart["command"] = partial(startListener, btStart)

btStop = Button(app, text="Stop")
btStop.pack(side=TOP, fill=X)
btStop["command"] = partial(startListener, btStop)

app.mainloop()

РЕДАКТИРОВАТЬ: Я нашел в документации, что Listener наследует от Thread, так что вы можете использовать его в том жекак Thread

thr = Listener(...)
thr.start()

Есть функция Listener.stop(), чтобы остановить слушателя.Для этого кода это будет

thr.stop()

Новый код

from pynput.keyboard import Listener, Key
from tkinter import *
from functools import partial


def press(key):
    keyd = str(key)
    keyd = keyd.replace("Key.space", " ")
    keyd = keyd.replace("'", "")

    with open("doc.docx", "a") as o:
        o.write(keyd)
        print("key:", keyd)

    # key combination to stop listener (and end thread)
    #if key == Key.esc:
    #    return False


def startListener(arg):
    global thr # inform function to use external variable

    if arg == btStart:
        if thr is None:
            print('[+] starting listener')
            thr = Listener(on_press=press)
            thr.start()
        else:
            print('[!] already running')

    if arg == btStop:
        if thr is None:
            print('[!] not running')
        else:
            print('[+] stoping thread')
            thr.stop()
            thr.join()
            thr = None

# ---------------------------------------------------------

thr = None

app = Tk()
app.geometry("300x100+900+400")

btStart = Button(app, text="Start")
btStart.pack(side=TOP, fill=X)
btStart["command"] = partial(startListener, btStart)

btStop = Button(app, text="Stop")
btStop.pack(side=TOP, fill=X)
btStop["command"] = partial(startListener, btStop)

app.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...