问题描述
IDE: PyCharm Community Edition 2020.3 / PyCharm Community Edition 2020.2.1
Python Interpreter: Location(venv) + Base interpreter(Python39)
OS: Win10
PyQt5+PySide6 GUI开发,在按下一个QPushButton后同时执行:
from pynput.keyboard import Listener
from time import sleep
import pyautogui as pg
import speech
import threading
class MainWindow(QMainWindow):
def __init__(self):
widgets.btn_startvr.clicked.connect(self.proc_buttonClick(self):)
def proc_buttonClick(self):
# GET BUTTON CLICKED
btn = self.sender()
btnName = btn.objectName()
# StartVR Button CLICK
def startVR():
print('子线程startVR:{}'.format(threading.current_thread().name))
def pgClick(xx, yy):
pg.click(xx, yy, button='left')
def report():
speech.say("请报告")
x = widgets.spinBox_x.value()
y = widgets.spinBox_y.value()
pgClick(x, y) # 开始
sleep(160) # 间隔 160s
pgClick(x, y) # 暂停
report()
pgClick(x, y) # 开始
sleep(127) # 间隔 127s
# Keyboard Listener
def on_release(key):
print('子线程listenKey:{}'.format(threading.current_thread().name))
# print('{0} release'.format(key))
k = '{0}'.format(key)
if k == "Key.up":
print("up")
elif k == "Key.left":
print("left")
elif k == "Key.down":
print("down")
elif k == "Key.right":
print("right")
elif k == "Key.caps_lock":
print('Stop this thread!')
return False
else:
if btnName == "btn_startvr":
task = threading.Thread(target=startVR)
task.start()
k = Listener(on_release=on_release)
k.start()
# task.join() # 加join后会更快挂掉
# k.join() # 加join后会更快挂掉
当只有python界面运行时能跑通,加上Steam+VR游戏界面运行时,会在中途退出,pycharm报错:Process finished with exit code -1073741819 (0xC0000005)。
查了相关的解决方法:方法汇总1,方法汇总2,觉得不对口。因为去掉按键检测线程,能跑通,所以应该是线程有问题。
from pynput.keyboard import Listener
from time import sleep
import pyautogui as pg
import speech
import threading
class MainWindow(QMainWindow):
def __init__(self):
# 去掉GUI控件的焦点,才能检测上下左右键
self.setChildrenFocusPolicy(Qt.NoFocus)
widgets.btn_startvr.clicked.connect(self.startvr_buttonClick(self):)
# startvr Button CLICK
def startvr_buttonClick(self):
self.vr_thread = VRThread()
self.vr_thread.start()
def setChildrenFocusPolicy(self, policy):
def recursiveSetChildFocusPolicy(parentQWidget):
for childQWidget in parentQWidget.findChildren(QWidget):
childQWidget.setFocusPolicy(policy)
recursiveSetChildFocusPolicy(childQWidget)
recursiveSetChildFocusPolicy(self)
def keyPressEvent(self, eventQKeyEvent):
key = eventQKeyEvent.key()
if key == Qt.Key_Up:
print('up')
elif key == Qt.Key_Left:
print('left')
elif key == Qt.Key_Down:
print('down')
elif key == Qt.Key_Right:
print('right')
else:
class VRThread(QThread):
def __init__(self):
super(VRThread, self).__init__()
self.quit_flag = False
def __del__(self):
self.wait()
def run(self):
while True:
if not self.quit_flag:
self.doVR()
self.quit_flag = True
else:
break
# self.quit()
# self.wait()
def doVR(self):
print('子线程doVR:{}'.format(threading.current_thread().name))
def pgClick(xx, yy):
pg.click(xx, yy, button='left')
def report():
#在游戏界面点击后,python窗口不再是最前面的窗口,失去Focus后,将无法检测箭头按键
#实现自动切换窗口(模拟手动alt+tab切换窗口的效果)
g.keyDown('alt')
sleep(.2)
pg.press('tab')
sleep(.2)
pg.keyUp('alt')
speech.say("请报告")
x = widgets.spinBox_x.value()
y = widgets.spinBox_y.value()
pgClick(x, y) # 开始
sleep(160) # 间隔 160s
pgClick(x, y) # 暂停
report()
pgClick(x, y) # 开始
sleep(127) # 间隔 127s
颁发有效信息奖(排名不分先后)