ich hoffe, dass ich mein Anliegen verständlich in Worte fassen kann.
Erst einmal zum Aufbau:
Ich habe zwei Klassen geschrieben, eine für die GUI mit PyQt5 und die zweite Klasse beinhaltet eine relativ simple Zeitscheibe.
Das ganze läuft auf einem Raspberry Pi 3 und ist über die SPI-Schnittstelle mit einem Port-Expander(MCP23S17) verknüpft.
Folgendes Problem:
Wenn ich den Code starte, läuft ausschließlich die Zeitscheibe und die GUI wird augenscheinlich ignoriert.
Was mich verwirrt ist, dass wenn ich während der Ausführung des Codes [ENTER] drücke, wird die GUI ausgeführt
jedoch bleibt die Zeitscheibe stehen.
Mein Ziel:
Das die GUI ausgeführt wird und währenddessen die Zeitscheibe durchläuft, im folgenden
möchte ich nämlich, dass unter Port B die schwarzen Kästchen grün aufleuchten, wenn ich
ein Signal an einem Eingang anlege.
Würde mich sehr freuen, wenn jemand versteht was ich meine
und vielleicht sogar meinen Fehler erkennt
Gruß Falcon
Code: Alles auswählen
from PyQt5.QtWidgets import (QWidget, QPushButton,QFrame, QApplication, QDialog)
import mcp23s17 as PortExpander
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import threading
import time
import sys
class Form(QDialog):
def __init__(self, parent = None):
super(Form, self).__init__(parent)
pingg = False
self.initUI()
def initUI(self):
self.col = QColor(0, 0, 0)
"""
Hier wird die Button-bezeichnung für Port-A festgelegt, seine Koordinaten und dass er immer True liefert,
Wenn der Button geklickt wird, löst es die Funktion setColor aus.
"""
#Port-A
pin1_A = QPushButton('Pin 1A', self)
pin1_A.setCheckable(True)
pin1_A.move(10, 10)
pin1_A.clicked.connect(self.setColor)
pin2_A = QPushButton('Pin 2A', self)
pin2_A.setCheckable(True)
pin2_A.move(10, 60)
pin2_A.clicked.connect(self.setColor)
pin3_A = QPushButton('Pin 3A', self)
pin3_A.setCheckable(True)
pin3_A.move(10, 110)
pin3_A.clicked.connect(self.setColor)
pin4_A = QPushButton('Pin 4A', self)
pin4_A.setCheckable(True)
pin4_A.move(10, 160)
pin4_A.clicked.connect(self.setColor)
pin5_A = QPushButton('Pin 5A', self)
pin5_A.setCheckable(True)
pin5_A.move(10, 210)
pin5_A.clicked.connect(self.setColor)
pin6_A = QPushButton('Pin 6A', self)
pin6_A.setCheckable(True)
pin6_A.move(10, 260)
pin6_A.clicked.connect(self.setColor)
pin7_A = QPushButton('Pin 7A', self)
pin7_A.setCheckable(True)
pin7_A.move(10, 310)
pin7_A.clicked.connect(self.setColor)
pin8_A = QPushButton('Pin 8A', self)
pin8_A.setCheckable(True)
pin8_A.move(10, 360)
pin8_A.clicked.connect(self.setColor)
"""
Hier wird ein Rechteck erzeugt mit koordinaten und größenangebe,
mit setStyleSheet() wird dessen Farbe geändert
"""
#LED- Anzeige Port-A
self.square1_A = QFrame(self)
self.square1_A.setGeometry(150, 15, 20, 20)
self.square1_A.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square2_A = QFrame(self)
self.square2_A.setGeometry(150, 65, 20, 20)
self.square2_A.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square3_A = QFrame(self)
self.square3_A.setGeometry(150, 115, 20, 20)
self.square3_A.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square4_A = QFrame(self)
self.square4_A.setGeometry(150, 165, 20, 20)
self.square4_A.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square5_A = QFrame(self)
self.square5_A.setGeometry(150, 215, 20, 20)
self.square5_A.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square6_A = QFrame(self)
self.square6_A.setGeometry(150, 265, 20, 20)
self.square6_A.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square7_A = QFrame(self)
self.square7_A.setGeometry(150, 315, 20, 20)
self.square7_A.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square8_A = QFrame(self)
self.square8_A.setGeometry(150, 365, 20, 20)
self.square8_A.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
"""
Hier wird die Button-bezeichnung für Port-B festgelegt,
seine Koordinaten und dass er immer True liefert,
wenn er abgefragt wird.
"""
#Port-B
pin1_B = QPushButton('Pin 1B', self)
pin1_B.setCheckable(True)
pin1_B.move(210, 10)
pin1_B.setEnabled(False)
pin1_B.clicked.connect(self.setColor)
pin2_B = QPushButton('Pin 2B', self)
pin2_B.setCheckable(True)
pin2_B.move(210, 60)
pin2_B.setEnabled(False)
pin2_B.clicked.connect(self.setColor)
pin3_B = QPushButton('Pin 3B', self)
pin3_B.setCheckable(True)
pin3_B.move(210, 110)
pin3_B.setEnabled(False)
pin3_B.clicked.connect(self.setColor)
pin4_B = QPushButton('Pin 4B', self)
pin4_B.setCheckable(True)
pin4_B.move(210, 160)
pin4_B.setEnabled(False)
pin4_B.clicked.connect(self.setColor)
pin5_B = QPushButton('Pin 5B', self)
pin5_B.setCheckable(True)
pin5_B.move(210, 210)
pin5_B.setEnabled(False)
pin5_B.clicked.connect(self.setColor)
pin6_B = QPushButton('Pin 6B', self)
pin6_B.setCheckable(True)
pin6_B.move(210, 260)
pin6_B.setEnabled(False)
pin6_B.clicked.connect(self.setColor)
pin7_B = QPushButton('Pin 7B', self)
pin7_B.setCheckable(True)
pin7_B.move(210, 310)
pin7_B.setEnabled(False)
pin7_B.clicked.connect(self.setColor)
pin8_B = QPushButton('Pin 8B', self)
pin8_B.setCheckable(True)
pin8_B.move(210, 360)
pin8_B.setEnabled(False)
pin8_B.clicked.connect(self.setColor)
"""
Hier wird ein Rechteck erzeugt mit koordinaten und größenangebe,
mit setStyleSheet() wird dessen Farbe geändert
"""
# LED- Anzeige Port-B
self.square1_B = QFrame(self)
self.square1_B.setGeometry(350, 15, 20, 20)
self.square1_B.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square2_B = QFrame(self)
self.square2_B.setGeometry(350, 65, 20, 20)
self.square2_B.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square3_B = QFrame(self)
self.square3_B.setGeometry(350, 115, 20, 20)
self.square3_B.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square4_B = QFrame(self)
self.square4_B.setGeometry(350, 165, 20, 20)
self.square4_B.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square5_B = QFrame(self)
self.square5_B.setGeometry(350, 215, 20, 20)
self.square5_B.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square6_B = QFrame(self)
self.square6_B.setGeometry(350, 265, 20, 20)
self.square6_B.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square7_B = QFrame(self)
self.square7_B.setGeometry(350, 315, 20, 20)
self.square7_B.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.square8_B = QFrame(self)
self.square8_B.setGeometry(350, 365, 20, 20)
self.square8_B.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.liste_square = [self.square1_B,self.square2_B,self.square3_B,self.square4_B,self.square5_B,self.square6_B,self.square7_B,self.square8_B]
self.setGeometry(300, 300, 400, 400)
self.setWindowTitle('Toggle button Port-A/Port-B')
self.show()
# Eingaenge negiert ausgeben
def update(self, eingang):
#self.textEdit.append('(<font color=blue><b>' + dec2bin(eingang) + '</b></font>)' + ' - ' )
print("Update wurde aufgerufen",dec2bin(~eingang))
zahl= dec2bin(eingang)
for i in range(0,len(zahl)):
if zahl[i]=='1':
self.liste_square[i].setStyleSheet("background-color:black;")
else:
self.liste_square[i].setStyleSheet("background-color:green;")
def buttonClicked(self):
""" Button angeklickt """
sender = self.sender()
self.performAction(sender.id)
"""
Bei klicken eines Button wird diese Funktion abgerufen und setzt die Farbe in
einem neben dem Butten stehenden rechteck von schwarz auf rot
"""
def setColor(self):
source = self.sender()
#Port-A
if source.text() == "Pin 1A":
if source.isChecked()==True:
self.square1_A.setStyleSheet("background-color:red;")
# pin1_gedrueckt=True
else:
self.square1_A.setStyleSheet("background-color:black;")
# pin1_gedrueckt=False
if source.text() == "Pin 2A":
if source.isChecked()==True:
self.square2_A.setStyleSheet("background-color:red;")
else:
self.square2_A.setStyleSheet("background-color:black;")
if source.text() == "Pin 3A":
if source.isChecked()==True:
self.square3_A.setStyleSheet("background-color:red;")
else:
self.square3_A.setStyleSheet("background-color:black;")
if source.text() == "Pin 4A":
if source.isChecked()==True:
self.square4_A.setStyleSheet("background-color:red;")
else:
self.square4_A.setStyleSheet("background-color:black;")
if source.text() == "Pin 5A":
if source.isChecked()==True:
self.square5_A.setStyleSheet("background-color:red;")
else:
self.square5_A.setStyleSheet("background-color:black;")
if source.text() == "Pin 6A":
if source.isChecked()==True:
self.square6_A.setStyleSheet("background-color:red;")
else:
self.square6_A.setStyleSheet("background-color:black;")
if source.text() == "Pin 7A":
if source.isChecked()==True:
self.square7_A.setStyleSheet("background-color:red;")
else:
self.square7_A.setStyleSheet("background-color:black;")
if source.text() == "Pin 8A":
if source.isChecked()==True:
self.square8_A.setStyleSheet("background-color:red;")
else:
self.square8_A.setStyleSheet("background-color:black;")
#Port-B
if source.text() == "Pin 1B":
if source.isChecked()==True:
self.square1_B.setStyleSheet("background-color:green;")
else:
self.square1_B.setStyleSheet("background-color:black;")
if source.text() == "Pin 2B":
if source.isChecked()==True:
self.square2_B.setStyleSheet("background-color:green;")
else:
self.square2_B.setStyleSheet("background-color:black;")
if source.text() == "Pin 3B":
if source.isChecked()==True:
self.square3_B.setStyleSheet("background-color:green;")
else:
self.square3_B.setStyleSheet("background-color:black;")
if source.text() == "Pin 4B":
if source.isChecked()==True:
self.square4_B.setStyleSheet("background-color:green;")
else:
self.square4_B.setStyleSheet("background-color:black;")
if source.text() == "Pin 5B":
if source.isChecked()==True:
self.square5_B.setStyleSheet("background-color:green;")
else:
self.square5_B.setStyleSheet("background-color:black;")
if source.text() == "Pin 6B":
if source.isChecked()==True:
self.square6_B.setStyleSheet("background-color:green;")
else:
self.square6_B.setStyleSheet("background-color:black;")
if source.text() == "Pin 7B":
if source.isChecked()==True:
self.square7_B.setStyleSheet("background-color:green;")
else:
self.square7_B.setStyleSheet("background-color:black;")
def performAction(self, cmd):
print("perfomAction")
# Port, Pin, Action (Wenn Pin=0 -> Alle Pins)
port = cmd[0]
pin = int(cmd[1])
action = cmd[2:]
if source.text() == "Pin 8B":
if port == 'A':
if source.isChecked()==True:
self.square8_B.setStyleSheet("background-color:green;")
self.sendPortA |= (1 << (pin - 1))
else:
self.square8_B.setStyleSheet("background-color:black;")
self.sendPortA &= ~(1 << (pin - 1))
self.mcp23s17Control.sendSPI(PortExpander.mcp23s17.SPI_GPIOA, self.sendPortA)
def dec2bin(value):
""" Dezimal nach Binaer (8-Bit) konvertieren """
result = ''
for i in range(8):
result = str((value >> i) & 1) + result
return result
print(result)
class Slicer:
# initialize timeframe, slice list, and running
def __init__(self, timeframe):
self.running = False
self.timeframe = timeframe
self.slices = []
self.running = False
# add a slice function with arguments to execute in the loop later
def add_slice(self, fun, args = ()):
self.slices.append((fun, args))
# start the loop in a new thread if not running
def start(self):
if self.running:
return
threading.Thread(target = self.loop).start()
# stop the loop at the next possible clean exit point
def stop(self):
self.running = False
# execute all the slice functions in fixed timeframes until stopped
def loop(self):
self.running = True
while self.running:
for s in self.slices:
tdiff = self.exec_slice(s[0], s[1])
if tdiff <= 0:
#TODO: Blinkende LED hinzufügen
print("Achtung: " + s[0].__name__ + " takes too long (" + str(tdiff) + ")")
if len(self.slices) == 0:
time.sleep(self.timeframe)
self.running = False
# execute a slice function and extend its runtime to the timeframe value
def exec_slice(self, fun, args = ()):
now = time.time() # get timestamp
fun(*args) # pass the arguments and execute the function
delta = time.time() - now # calculate how long the function took to run
if delta < self.timeframe: # if there is time left, sleep to reach the target time
time.sleep(self.timeframe - delta)
return self.timeframe - delta
pingg = False
self.initUI()
self.sendPortA = 0x00
#self.readPortB = 0x00
# MCP23S17-Parameter: ID, SCLK, MOSI, MISO, CS
self.mcp23s17Control = PortExpander.mcp23s17(0, 18, 24, 23, 25)
self.mcp23s17Control.sendSPI(PortExpander.mcp23s17.SPI_IODIRA, 0x00) # PPIOA als Ausgaenge programmieren
self.mcp23s17Control.sendSPI(PortExpander.mcp23s17.SPI_IODIRB, 0xFF) # PPIOB als Eingaenge programmieren
# Funktionen zur Ausfuehrung
def toggle_led():
# led on -> off
# led off -> on
print("OUTPUT")
pass
def check_button():
# check if the button is pressed
# do something
print("INPUT")
pass
def check_input(gpio_port):
# read the value from pin
# save it / do something with it
pass
def set_output(gpio_port):
# set some output pin
pass
def divide_stuff(num1, num2):
# simulate doing stuff
for i in range(num1, num2):
k = i/(i+1)
#Teile aus GUI-Thread
#update = pyqtSignal(int, name='update')
def __del__(self):
self.wait()
if __name__ == "__main__":
s = Slicer(0.1) # init slicer
# add all functions
s.add_slice(toggle_led)
s.add_slice(check_button)
#s.add_slice(run)
#...
s.add_slice(divide_stuff, (1, 11000))
# start the slicer
s.start()
# wait for keyboard input
try:
input() # in python3.x
# raw_input() in python2.x
except:
pass
# stop the slicer and exit
s.stop()
if __name__ == '__main__':
app = QApplication(sys.argv)
form = Form()
form.show()
sys.exit(app.exec_())