[FIXED] Hallo zusammen,

Ausgabe

Ich versuche, ein Programm zu schreiben, das ein X in einem definierten Frame bewegen soll. Zu diesem Zweck sollte eine While-Schleife mit einem KeyPress beginnen und mit einem KeyReleases enden.

Ich habe im Internet nur die Multithreading- oder Multiprocessing-Methoden gefunden, um dies gleichzeitig zu tun. Das Multithreading selbst funktioniert eine gewisse Zeit (immer anders) und dann bekomme ich diverse Fehlermeldungen oder das Programm friert komplett ein.

Oft wird es durch das Signal 11 sigsegv unterbrochen.

Der Code lautet:

# 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_())

Ich programmiere derzeit in PyCharm auf einem MacBook mit OS 12.6.

Lösung

Ich habe nicht Ihren gesamten Code gelesen, aber Sie versuchen, von einem Thread aus auf die GUI zuzugreifen, der nicht der Hauptthread ist. Dies ist illegal und wird früher oder später zu Abstürzen führen.


Beantwortet von –
Jens


Antwort geprüft von –
Dawn Plyler (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like