![](/img/trans.png)
[英]Terminating client connection to server using keyboard shortcut in python
[英]Python Timer Threading not Terminating using Desktop Shortcut
当我从终端运行以下代码并退出 window 后,使用 Ctrl+C 或 Ctrl+Z 取消脚本时,脚本完全终止。 使用 Ctrl+CI 得到这个错误:
Exception ignored in: <module 'threading' from '/usr/lib/python3.6/threading.py'>
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 1294, in _shutdown
t.join()
File "/usr/lib/python3.6/threading.py", line 1056, in join
self._wait_for_tstate_lock()
File "/usr/lib/python3.6/threading.py", line 1072, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
KeyboardInterrupt
如果我使用桌面链接:
#!/usr/bin/env xdg-open
[Desktop Entry]
Type=Application
Name=MyProblem
Exec=/home/USER/myProblem.py
Terminal=false
Name[en_CA]=myProblem
并退出 window,线程似乎仍在运行(通过尝试注销我的桌面和出现的通知程序表明 MyProblem 正忙)。
线程代码没有终止,我知道在等待期后线程被触发后,很难终止。 我看过很多帖子,包括: Python threading.timer - 每“n”秒重复 function Python 线程,线程不关闭
由于这是一个 threading.Timer,因此似乎没有使用 daemon=True 的方法。
我不确定如何在离开 window 之前在 closeEvent 中实现线程的完全关闭。每个人都保持安全。 谢谢你。
#!/usr/bin/python3
from datetime import datetime, timedelta
from PyQt5.QtWidgets import (QAction, QApplication, QCheckBox, QGridLayout, QMainWindow, QMenuBar, QWidget)
import os; import subprocess; import sys; import threading; import time
class MyProblem(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
########################################
def closeEvent(self, event):
# what do I place here - thr is a NoneType
None
########################################
def recordTimedAudio(self, tL, tfn):
# record audio
self.rec_args =['arecord', '--device=hw', '-d', str(tL), '-f', 'cd', '-t', 'wav', tfn +'.wav']
self.rec = subprocess.Popen(self.rec_args, shell=False)
########################################
def timedRecording(self):
dateData =['2020-04-13 13:06:00','2020-04-13 13:07:00'] # this should be changed for future dates/times
# My code uses a for loop to create a number of threads, but the end go through a series
for d in dateData:
# Create Start Time in Seconds
t = time.strptime(d, '%Y-%m-%d %H:%M:%S')
t = time.mktime(t)
thr = threading.Timer(int(t-time.time()), self.recordTimedAudio, ['10','File1']).start() #/27190809/
print(thr) # This comes back None
self.timerAction.setEnabled(False)
########################################
def initUI(self):
self.setGeometry(5,5,100,100); self.mainWidget = QWidget()
self.layout = QGridLayout(); self.mainWidget.setLayout(self.layout)
self.setCentralWidget(self.mainWidget)
# Menu
self.mainMenu = self.menuBar()
self.optionsMenu = self.mainMenu.addMenu('Options')
self.timerAction = QAction('Set Timer', checkable=True)
self.timerAction.triggered.connect(self.timedRecording)
self.optionsMenu.addAction(self.timerAction)
self.show()
########################################
if __name__ =='__main__':
app = QApplication(sys.argv)
ex = MyProblem()
sys.exit(app.exec_())
################################################################################################END
我无法让线程停止,也许线程对于这样的计时问题来说太过分了。 我创建了一个可能在将来帮助某人的解决方法。 用这些例程替换上面的代码:
def timedRecording(self):
dateData =['2020-04-13 13:06:00','2020-04-13 13:07:00'] # this should be changed for future dates/times
for d in dateData:
# Create Start Time in Seconds
t = time.strptime(d, '%Y-%m-%d %H:%M:%S')
t = time.mktime(t)
self.timerData.append([t, trecLength, urlText, tfilename]) # start time recording length, url, filename
self.timerData.sort(key = lambda x: x[0]) # /4174941/
self.treclen = len(self.timerData)
if self.treclen>0:
self.rtime.setText('Timer Set')
self.timerAction.setEnabled(False)
self.startTRecTimer()
########################################
def recordTimedAudio(self, tL, urlText, tfn):
self.rec_args =['arecord', '--device=hw', '-d', str(tL), '-f', 'cd', '-t', 'wav', os.path.join(os.path.sep,self.audioDir, tfn +'.wav')]
self.rec = subprocess.Popen(self.rec_args, shell=False) #https://docs.python.org/2/library/subprocess.html#popen-constructor
# Learning a trick from: https://stackoverflow.com/questions/27190809/
if self.trecNum < self.treclen-1:
self.trecNum+=1
self.startTRecTimer()
########################################
def startTRecTimer(self):
if time.time() < self.timerData[self.trecNum][0]: # time has not elapsed /415511/
# Start QTimer delay then Start Recording
delayTime = int(self.timerData[self.trecNum][0]-time.time())*1000 # QTimer uses milliseconds
self.trecTimer = QTimer()
self.trecTimer.setSingleShot(True)
self.trecTimer.timeout.connect(lambda: self.recordTimedAudio(self.timerData[self.trecNum][1], self.timerData[self.trecNum][2], self.timerData[self.trecNum][3]))
self.trecTimer.start(delayTime)
也添加到 initUI:
self.rec = None
以及 window 的 closeEvent:
if self.rec != None:
self.rec.terminate() # /16866602/
所以子进程停止了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.