如何停止在键盘 + PyQt5 的单独线程模块中等待按键?
How to stop waiting for a keypress in a separate thread module in keyboard + 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()
我正在编写一个 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()