我正在尝试编写一个程序,该程序应该在定义的帧中移动X。为此,while循环应该以KeyPress开始,以KeyRelease结束。
我只在互联网上找到了多线程或多处理方法来同时做到这一点。多线程本身工作一段时间(总是不同(,然后我会收到各种错误消息,或者程序完全冻结。
它经常被信号11 sigsegov中断。
代码为:
# GLOBAL
import faulthandler; faulthandler.enable()
import sys
import time
import requests
from pynput import keyboard
from pynput.keyboard import Key
from qtpy import QtWidgets
from PyQt5 import QtCore
from ui.mainwindow import Ui_MainWindow
# Globale Variablen:
PAN = 250
TILT = 150
SPEED = 1
TIME = 0.01
KEYS = []
THREADS = 0
DIRECTION = []
# HTTP SECTION
payload = {"name": "MK"}
r = requests.get("https://httpbin.org/get", params=payload)
print(r.status_code)
# BUILD GUI
app = QtWidgets.QApplication(sys.argv)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_MainWindow() # Laden des Style Frames
self.ui.setupUi(self) # Funktion aus Ui_MainWindow ausführen (Fenster zeichnen)
self.ui.tilt.setText(str(TILT))
self.ui.pan.setText(str(PAN))
self.ui.speed.setText(str(SPEED))
## Button Funktionsaufrufe:
self.thread = {}
self.ui.btnUp.clicked.connect(self.moveUP)
self.ui.btnDown.clicked.connect(self.moveDOWN)
self.ui.btnLeft.clicked.connect(self.moveLEFT)
self.ui.btnRight.clicked.connect(self.moveRIGHT)
self.ui.btnCenter.clicked.connect(self.stop_worker)
self.ui.speed.textChanged.connect(self.setSpeed)
# Funktion zum bewegen über die Buttons
def startUp(self):
self.thread[1] = ThreadClass(parent=None, index=1)
self.thread[1].start()
self.thread[1].any_signal.connect(self.my_function)
time.sleep(0.5)
self.thread[1].stop()
print('init thread 1 on startup')
self.thread[2] = ThreadClass(parent=None, index=2)
self.thread[2].start()
time.sleep(0.5)
self.thread[2].stop()
print('init thread 2 on startup')
self.thread[3] = ThreadClass(parent=None, index=3)
self.thread[3].start()
time.sleep(0.5)
self.thread[3].stop()
print('init thread 3 on startup')
self.thread[4] = ThreadClass(parent=None, index=4)
self.thread[4].start()
time.sleep(0.5)
self.thread[4].stop()
print('init thread 4 on startup')
print('... n n n')
print('Status = Ready:')
print('Keys = ', KEYS)
def moveUP(self):
if bool(self.thread[2].isRunning()):
self.stopDOWN()
self.thread[1] = ThreadClass(parent=None, index=1)
self.thread[1].start()
self.thread[1].any_signal.connect(self.my_function)
#self.ui.btnUp.setEnabled(False)
def moveDOWN(self):
# global DIRECTION
# DIRECTION.append('Down')
self.thread[2] = ThreadClass(parent=None, index=2)
self.thread[2].start()
self.thread[2].any_signal.connect(self.my_function)
#self.ui.btnDown.setEnabled(False)
def moveLEFT(self):
# global DIRECTION
# DIRECTION.append('Left')
if bool(self.thread[4].isRunning()):
self.stopRIGHT()
self.thread[3] = ThreadClass(parent=None, index=3)
self.thread[3].start()
self.thread[3].any_signal.connect(self.my_function)
#self.ui.btnLeft.setEnabled(False)
def moveRIGHT(self):
# global DIRECTION
# DIRECTION.append('Right')
self.thread[4] = ThreadClass(parent=None, index=4)
self.thread[4].start()
self.thread[4].any_signal.connect(self.my_function)
#self.ui.btnRight.setEnabled(False)
def stopUP(self):
global KEYS
if bool(self.thread[1].isRunning()):
self.thread[1].stop()
#self.ui.btnUp.setEnabled(True)
KEYS.remove(Key.up)
# DIRECTION.remove('Up')
def stopDOWN(self):
global KEYS
if bool(self.thread[2].isRunning()):
self.thread[2].stop()
#self.ui.btnDown.setEnabled(True)
KEYS.remove(Key.down)
# DIRECTION.remove('Down')
def stopLEFT(self):
global KEYS
if bool(self.thread[3].isRunning()):
self.thread[3].stop()
#self.ui.btnLeft.setEnabled(True)
KEYS.remove(Key.left)
# DIRECTION.remove('Left')
def stopRIGHT(self):
global KEYS
if bool(self.thread[4].isRunning()):
self.thread[4].stop()
#self.ui.btnRight.setEnabled(True)
KEYS.remove(Key.right)
# DIRECTION.remove('Right')
def stop_worker(self):
global DIRECTION
if 'Up' in DIRECTION:
self.thread[1].stop()
#self.ui.btnUp.setEnabled(True)
DIRECTION.remove('Up')
if 'Down' in DIRECTION:
self.thread[2].stop()
#self.ui.btnDown.setEnabled(True)
DIRECTION.remove('Down')
if 'Left' in DIRECTION:
self.thread[3].stop()
#self.ui.btnLeft.setEnabled(True)
if 'Right' in DIRECTION:
self.thread[4].stop()
#self.ui.btnRight.setEnabled(True)
DIRECTION.remove('Right')
def my_function(self, counter):
global KEYS
cnt = counter
index = self.sender().index
if index == 1:
print(cnt)
def setSpeed(self):
global SPEED
if self.ui.speed.text():
SPEED = int(self.ui.speed.text())
# Funktion zum bewegen über die Tasten
def on_press(key):
global KEYS
if key not in KEYS:
if key == Key.up:
MainWindow.moveUP(window)
KEYS.append(key)
print('added: ' + str(key))
if key == Key.down:
if Key.up in KEYS:
pass
else:
MainWindow.moveDOWN(window)
KEYS.append(key)
print('added: ' + str(key))
if key == Key.left:
MainWindow.moveLEFT(window)
KEYS.append(key)
print('added: ' + str(key))
if key == Key.right:
if Key.left in KEYS:
pass
else:
MainWindow.moveRIGHT(window)
KEYS.append(key)
print('added: ' + str(key))
def on_release(key):
global KEYS
if key in KEYS:
if key == Key.up and Key.up in KEYS:
MainWindow.stopUP(window)
if key == Key.down and Key.down in KEYS:
MainWindow.stopDOWN(window)
if key == Key.left and Key.left in KEYS:
MainWindow.stopLEFT(window)
if key == Key.right and Key.right in KEYS:
MainWindow.stopRIGHT(window)
print(KEYS)
if key == Key.esc:
MainWindow.stop_worker(window)
# Collect events until released
listener = keyboard.Listener(
on_press=on_press,
on_release=on_release)
listener.start()
class ThreadClass(QtCore.QThread):
any_signal = QtCore.pyqtSignal(int)
def __init__(self, parent=None, index=0):
super(ThreadClass, self).__init__(parent)
self.index = index
self.is_running = True
def run(self):
global TILT
global PAN
global TIME
global SPEED
print('Starting thread...', self.index)
i = self.index
while (True):
if i == 1:
if TILT <= 0:
pass
else:
TILT -= SPEED
window.ui.tilt.setText(str(TILT))
window.ui.target.setGeometry(PAN, TILT, 10, 16)
# print("T", TILT)
time.sleep(TIME)
if i == 2:
if TILT >= 301:
pass
else:
TILT += SPEED
window.ui.tilt.setText(str(TILT))
window.ui.target.setGeometry(PAN, TILT, 10, 16)
# print('T', TILT)
time.sleep(TIME)
if i == 3:
if PAN <= 0:
pass
else:
PAN -= SPEED
window.ui.pan.setText(str(PAN))
window.ui.target.setGeometry(PAN, TILT, 10, 16)
# print("P", PAN)
time.sleep(TIME)
if i == 4:
if PAN >= 500:
pass
else:
PAN += SPEED
window.ui.pan.setText(str(PAN))
window.ui.target.setGeometry(PAN, TILT, 10, 16)
# print("P", PAN)
time.sleep(TIME)
def stop(self):
self.is_running = False
print('Stopping thread...', self.index)
self.terminate()
window = MainWindow()
window.show()
window.startUp()
sys.exit(app.exec_())
我目前正在操作系统为12.6的MacBook上使用PyCharm进行编程。
我没有阅读您的所有代码,但您正试图从一个不是主线程的线程访问GUI。这是非法的,迟早会导致崩溃。