【问题标题】:Python script not stopping on sys.exit() [duplicate]Python脚本没有在sys.exit()上停止[重复]
【发布时间】:2021-06-24 03:33:54
【问题描述】:

我编写了一个脚本,可以通过相应地移动鼠标从 ScalableVectorGraphics(.svg) 绘制折线 (it over on github)。

当您将鼠标的控制权交给脚本时,killswitch 肯定是必要的,所以我在 Internet 上的某个地方找到了一个键盘侦听器的示例:

def on_press(key):
try:
    sys.exit()
    print('alphanumeric key {0} pressed'.format(key.char))
    print('adsfadfsa')
except AttributeError:
    print('special key {0} pressed'.format(
        key))

def main():
listener = keyboard.Listener( #TODO fix sys.exit()
    on_press=on_press)
listener.start()

if __name__ == '__main__':
main()

它似乎正在工作:如果我在 sys.exit() 之前添加一个打印语句,它会立即正确执行。 但是使用 sys.exit() 它不断移动我的鼠标,python 解释器仍在 Taskmanager 上。我不知道为什么它一直在执行。

提前感谢您的建议。 斯莫尔先生

解决方案是:os._exit(1)

完整源代码:

from pynput import mouse as ms
from pynput import keyboard
from pynput.mouse import Button, Controller
import threading
import time
from xml.dom import minidom
import re

sys.path.append('/Users/MrSmoer/Desktop/linedraw-master')

mouse = ms.Controller()
tlc = None
brc = None
brc_available = threading.Event()

biggestY = 0
biggestX = 0

drwblCnvsX = 0
drwblCnvsY = 0


def on_click(x, y, button, pressed):
    if not pressed:
        # Stop listener
        return False


def on_press(key):
    try:
        sys.exit()
        print('alphanumeric key {0} pressed'.format(key.char))
        print('adsfadfsa')
    except AttributeError:
        print('special key {0} pressed'.format(
            key))


def initialize():
    print("Please select your programm and then click at the two corners of the canvas. Press any key to cancel.")
    with ms.Listener(
            on_click=on_click) as listener:
        listener.join()

    print('please middleclick, when you are on top left corner of canvas')
    with ms.Listener(
            on_click=on_click) as listener:
        listener.join()

    global tlc
    tlc = mouse.position

    print('please middleclick, when you are on bottom left corner of canvas')
    with ms.Listener(
            on_click=on_click) as listener:
        listener.join()
    global brc
    brc = mouse.position
    mouse.position = tlc
    print('thread finished')
    brc_available.set()


def getDrawabableCanvasSize(polylines):
    global biggestX
    global biggestY

    for i in range(len(polylines)):  # goes throug all polylines
        points = hyphen_split(polylines[i])  # Splits polylines to individual points
        for c in range(len(points)):  # goes throug all points on polyline
            cord = points[c].split(',')  # splits points in x and y axis
            if float(cord[0]) > (biggestX - 5):
                biggestX = float(cord[0]) + 5
            if float(cord[1]) > (biggestY - 5):
                biggestY = float(cord[1]) + 5
    print('TLC: ', tlc)
    print('bigX: ', biggestX)
    print('bigY: ', biggestY)

    cnvswidth = tuple(map(lambda i, j: i - j, brc, tlc))[0]
    cnvsheight = tuple(map(lambda i, j: i - j, brc, tlc))[1]
    cnvsapr = cnvswidth / cnvsheight
    print('Canvasaspr: ', cnvsapr)
    drwblcnvaspr = biggestX / biggestY
    print('drwnble aspr: ', drwblcnvaspr)

    if drwblcnvaspr < cnvsapr:  # es mus h vertikal saugend
        print('es mus h vertikal saugend')
        finalheight = cnvsheight
        finalwidth = finalheight * drwblcnvaspr

    else:  # es muss horizontal saugend, oder aspect ratio ist eh gleich
        print('es muss horizontal saugend, oder aspect ratio ist eh gleich')
        finalwidth = cnvswidth
    scalefactor = finalwidth / biggestX
    print(scalefactor)
    return scalefactor


def drawPolyline(polyline, scalefactor):
    points = hyphen_split(polyline)
    #print(points)
    beginpoint = tlc
    for c in range(len(points)):  # goes throug all points on polyline
        beginpoint = formatPoint(points[c], scalefactor)
        if len(points) > c + 1:
            destpoint = formatPoint(points[c + 1], scalefactor)
            mouse.position = beginpoint
            time.sleep(0.001)
            mouse.press(Button.left)
            # time.sleep(0.01)
            mouse.position = destpoint
            # time.sleep(0.01)
            mouse.release(Button.left)
        else:
            destpoint = tlc
            #print("finished line")
    mouse.release(Button.left)


def formatPoint(p, scale):
    strcord = p.split(',')
    #print(scale)
    #print(tlc)
    x = float(strcord[0]) * scale + tlc[0]  # + drwblCnvsX/2
    y = float(strcord[1]) * scale + tlc[1]  # + drwblCnvsY/2
    #print('x: ', x)
    #print('y: ', y)
    thistuple = (int(x), int(y))
    return thistuple


def hyphen_split(a):
    return re.findall("[^,]+\,[^,]+", a)
    # ['id|tag1', 'id|tag2', 'id|tag3', 'id|tag4']


def main():
    listener = keyboard.Listener( #TODO fix sys.exit()
        on_press=on_press)
    listener.start()

    thread = threading.Thread(target=initialize()) #waits for initializing function (two dots)
    thread.start()
    brc_available.wait()

   # print(sys.argv[1])
    doc = minidom.parse('/Users/MrSmoer/Desktop/linedraw-master/output/out.svg')  # parseString also exists
    try:
        if sys.argv[1] == '-ip':
            doc = minidom.parse(sys.argv[2])
    except IndexError:
        print('Somethings incorrect1')

    polylines = NotImplemented

    try:
        doc = minidom.parse('/Users/MrSmoer/Desktop/linedraw-master/output/out.svg')  # parseString also exists
        # /Users/MrSmoer/Desktop/linedraw-master/output/output2.svg
        #doc = minidom.parse('/Users/MrSmoer/Desktop/Test.svg')
        polylines = [path.getAttribute('points') for path
                     in doc.getElementsByTagName('polyline')]
        doc.unlink()
    except:
        print('Somethings incorrect3')

    # print(polylines)

    scalefactor = getDrawabableCanvasSize(polylines)

    for i in range(len(polylines)):
        drawPolyline(polylines[i], scalefactor)


if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python listener exit


    【解决方案1】:

    有时,在编写多线程应用程序时,raise SystemExit 和 sys.exit() 都只会杀死正在运行的线程。另一方面,os._exit() 退出整个进程。

    虽然您通常应该更喜欢 sys.exit 因为它对其他代码更“友好”,但它实际上所做的只是引发异常。

    如果您确定需要立即退出进程,并且您可能处于某个会捕获 SystemExit 的异常处理程序中,那么还有另一个函数 - os._exit - 在 C 级别立即终止并且不执行解释器的任何正常拆卸

    提前终止 Python 脚本的一种简单方法是使用内置的 quit() 函数。无需导入任何库,高效简单。

    例子:

           #do stuff
         if this == that:
          quit()
    

    你可以试试这些选项!! 希望它工作正常!如果不告诉我们,我们会尝试更多的解决方案!

    【讨论】:

    • os._exit(1) 为我工作
    【解决方案2】:

    sys.exit() 最终会杀死正在执行它的线程,但您的程序似乎利用了多个线程。

    如果你想退出,你需要杀死程序的所有线程,包括主线程。

    【讨论】:

      猜你喜欢
      • 2019-04-04
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 2019-03-24
      • 2019-10-14
      • 1970-01-01
      相关资源
      最近更新 更多