如何停止在键盘+PyQt5中的单独线程模块中等待按键



我正在编写一个PyQt5 GUI程序来控制无人机,我需要跟踪击键。我在用QThread创建的一个单独的线程中跟踪它们。当我第一次按下按钮时,按键跟踪应该开始,但第二次按下按钮,流程应该停止,按键跟踪也应该停止。这是我的代码:

class Keybord_Recognition(QtCore.QObject):
def __init__(self):
super(Keybord_Recognition, self).__init__()
def key_recog(self, k):
if k.event_type == 'down':
if k.name == 'w':
print('forward')
elif k.name == 's':
print('back')
elif k.name == 'a':
print('left')
elif k.name == 'd':
print('right')
elif k.name == 'z':
print('up')
elif k.name == 'x':
print('down')
def run(self):
keyboard.hook(self.key_recog)
keyboard.wait('p')
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
self.control_btn = QtWidgets.QPushButton(self.centralwidget)
self.control_btn.setGeometry(QtCore.QRect(480, 60, 160, 150))
self.control_btn.setObjectName("control_btn")
self.control_btn.setCheckable(True)
self.control_btn.clicked.connect(self.kboard_recognition)
self.control_btn.setStyleSheet("QPushButton{background-color: #aae053;n"
"border-radius: 60%;nbackground-image: url('images/pult.png');n"
"background-repeat: no-repeat;nbackground-position: center;}n"
"QPushButton:hover{background-color: #81eb3b;}")
def kboard_recognition(self):
if self.control_btn.isChecked():
self.control_btn.setStyleSheet("QPushButton{background-color: red;n"
"border-radius: 60%;nbackground-image: url('images/pause.png');n"
"background-repeat: no-repeat;nbackground-position: center;}n")
self.thread_kboard = QtCore.QThread()
self.k_recog = Keybord_Recognition()
self.k_recog.moveToThread(self.thread_kboard)
self.thread_kboard.started.connect(self.k_recog.run)
self.thread_kboard.start()
else:
self.control_btn.setStyleSheet("QPushButton{background-color: #aae053;n"
"border-radius: 60%;nbackground-image: url('images/pult.png');n"
"background-repeat: no-repeat;nbackground-position: center;}n"
"QPushButton:hover{background-color: #81eb3b;}")
keyboard.send('q')
self.thread_kboard.terminate()

但当我第二次按下按钮时,键盘并没有停止跟踪。如何修复?

不需要使用线程将键盘与Qt一起使用,另一方面,您必须删除回调,以便不再解析事件。

import keyboard
from PyQt5 import QtCore, QtWidgets

class QKeyBoard:
def _hook_callback(self, k):
if k.event_type == "down":
if k.name == "w":
print("forward")
elif k.name == "s":
print("back")
elif k.name == "a":
print("left")
elif k.name == "d":
print("right")
elif k.name == "z":
print("up")
elif k.name == "x":
print("down")
def start(self):
keyboard.hook(self._hook_callback)
def stop(self):
keyboard.unhook(self._hook_callback)

class Ui_MainWindow(object):
def setupUi(self, MainWindow):
self.centralwidget = QtWidgets.QWidget()
self.setCentralWidget(self.centralwidget)
self.control_btn = QtWidgets.QPushButton(self.centralwidget)
self.control_btn.setGeometry(QtCore.QRect(480, 60, 160, 150))
self.control_btn.setObjectName("control_btn")
self.control_btn.setCheckable(True)
self.control_btn.setStyleSheet(
"QPushButton{n"
"background-color: #aae053;n"
"border-radius: 60%;n"
"background-image: url('images/pult.png');n"
"background-repeat: no-repeat;n"
"background-position: center;}n"
"QPushButton:hover{n"
"background-color: #81eb3b;n"
"}"
"QPushButton:checked{n"
"background-color: red;n"
"border-radius: 60%;n"
"background-image: url('images/pause.png');n"
"background-repeat: no-repeat;n"
"background-position: center;n"
"}"
)

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.qkeyboard = QKeyBoard()
self.control_btn.toggled.connect(self.handle_toggled)
def handle_toggled(self, state):
if state:
self.qkeyboard.start()
else:
self.qkeyboard.stop()

def main():
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())

if __name__ == "__main__":
main()

最新更新