Python 脚本不会在 sys.exit() 上停止
Python script not stopping on sys.exit()
我编写了一个脚本,可以通过相应地移动鼠标从 ScalableVectorGraphics(.svg) 绘制多段线 (it over on github)。
当你将鼠标控制权交给脚本时,killswitch 是必不可少的,所以我在网上找到了一个键盘监听器的例子:
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 解释器仍在任务管理器上。不知道为什么一直在执行。
提前感谢您的建议。
MrSmoer
解决方案是: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()
sys.exit()
最终杀死了正在执行它的线程,但您的程序似乎利用了多线程。
如果你想退出,你需要杀死程序的所有线程,包括主线程。
有时,在编写多线程应用程序时,引发 SystemExit 和 sys.exit() 都只会终止 运行 线程。另一方面,os._exit()退出整个过程。
虽然您通常应该更喜欢 sys.exit,因为它对其他代码更“友好”,但它实际上所做的只是引发异常。
如果您确定需要立即退出进程,并且您可能在某个会捕获 SystemExit 的异常处理程序中,还有另一个函数 - os._exit - 它会在 C 级别立即终止并且不执行解释器的任何正常拆卸
提前终止 Python 脚本的一种简单方法是使用内置的 quit() 函数。无需导入任何库,高效简单
示例:
#do stuff
if this == that:
quit()
您可以试试这些选项!!
希望它工作正常!如果不告诉我们,我们会尝试更多的解决方案!
我编写了一个脚本,可以通过相应地移动鼠标从 ScalableVectorGraphics(.svg) 绘制多段线 (it over on github)。
当你将鼠标控制权交给脚本时,killswitch 是必不可少的,所以我在网上找到了一个键盘监听器的例子:
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 解释器仍在任务管理器上。不知道为什么一直在执行。
提前感谢您的建议。 MrSmoer
解决方案是: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()
sys.exit()
最终杀死了正在执行它的线程,但您的程序似乎利用了多线程。
如果你想退出,你需要杀死程序的所有线程,包括主线程。
有时,在编写多线程应用程序时,引发 SystemExit 和 sys.exit() 都只会终止 运行 线程。另一方面,os._exit()退出整个过程。
虽然您通常应该更喜欢 sys.exit,因为它对其他代码更“友好”,但它实际上所做的只是引发异常。
如果您确定需要立即退出进程,并且您可能在某个会捕获 SystemExit 的异常处理程序中,还有另一个函数 - os._exit - 它会在 C 级别立即终止并且不执行解释器的任何正常拆卸
提前终止 Python 脚本的一种简单方法是使用内置的 quit() 函数。无需导入任何库,高效简单
示例:
#do stuff
if this == that:
quit()
您可以试试这些选项!! 希望它工作正常!如果不告诉我们,我们会尝试更多的解决方案!