[英]Timer that doesn't want to start with GPIO button
我有一個計時器,可以通過屏幕上的開始/停止按鈕或兩個GPIO按鈕啟動。
屏幕開始/停止按鈕可以正常工作。
GPIO按鈕並非始終有效。 我可以在終端窗口中看到“開始”打印,但是計時器沒有啟動。 如果我多次單擊按鈕,它可能會啟動。 如果我按ALT-TAB,它將啟動。
我在這里想念什么?
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import RPi.GPIO as GPIO
import time
from PyQt4 import QtGui, QtCore
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
class Timer(QtGui.QWidget):
def __init__(self):
super(Timer, self).__init__()
self.initUI()
def initUI(self):
# Setup font
font = QtGui.QFont()
font.setFamily('Lucida')
font.setFixedPitch(True)
font.setPointSize(30)
fontPalette = QtGui.QPalette()
# Background image
oImage = QtGui.QImage("bg.jpg")
sImage = oImage
sImage = oImage.scaledToWidth(1920)
palette = QtGui.QPalette()
palette.setBrush(10, QtGui.QBrush(sImage))
self.setPalette(palette)
# LCD display
self.lcd = QtGui.QLCDNumber(self)
self.lcd.setMode(1)
self.lcd.setSegmentStyle(1)
self.lcd.setDigitCount(8)
self.lcd.resize(1520, 1080)
self.lcd.setGeometry(200, 0, 1520, 1080)
self.lcd.setFrameShape(0)
self.lcd.display("00:00:00")
# Setup the timer
self.lcdTimer = QtCore.QTime(0,0,0,0)
self.lcd.display(self.lcdTimer.toString('mm:ss:zzz')[:8])
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updateLCD)
# Quit button
self.btnQuit = QtGui.QPushButton('Quit', self)
self.btnQuit.clicked.connect(self.quitTimer)
self.btnQuit.move(50, 1005)
# Start button
btnStart = QtGui.QPushButton('Start', self)
btnStart.move(750, 1005)
btnStart.clicked.connect(self.startBtn)
# Stop button
btnStop = QtGui.QPushButton('Stop', self)
btnStop.move(850, 1005)
btnStop.clicked.connect(self.stopBtn)
# Reset button
self.btnReset = QtGui.QPushButton('Reset', self)
self.btnReset.move(150, 1005)
self.btnReset.clicked.connect(self.buttonClicked)
# Setup the window
self.setWindowTitle('Timer')
self.setGeometry(0, 0, 1920, 1080)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
self.show()
def updateLCD(self):
telapsed = self.lcdTimer.elapsed()
msecs = telapsed % 1000
secs = int(telapsed / 1000)
mins = (secs / 60) % 60
secs = secs % 60
self.lcd.display(str(mins).zfill(2) + ":" + str(secs).zfill(2) + ":" + str(msecs)[:2].zfill(2))
time.sleep(0.05)
def buttonClicked(self):
sender = self.sender()
if sender.text() == "Reset":
self.lcdTimer = QtCore.QTime(0,0,0,0)
self.lcd.display(self.lcdTimer.toString('mm:ss:zzz')[:8])
def startBtn(self, channel):
print("Start")
self.lcdTimer.start()
self.timer.start()
def stopBtn(self, channel):
print("Stop")
self.timer.stop()
def quitTimer(self):
GPIO.cleanup()
QtCore.QCoreApplication.instance().quit()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = Timer()
GPIO.add_event_detect(18, GPIO.FALLING, callback=ex.startBtn, bouncetime=500)
GPIO.add_event_detect(23, GPIO.FALLING, callback=ex.stopBtn, bouncetime=500)
sys.exit(app.exec_())
編輯:
我在gui中獲得了要更新的計數器,但是現在我無法使開始按鈕重新啟動,因為它連接到錯誤的開始。
帶有###的注釋是可以更改的注釋,以使其與計時器更新gui或“開始”按鈕可以重新啟動計時器一起使用。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import RPi.GPIO as GPIO
import time
from PyQt4.QtGui import QWidget, QFont, QPalette, QImage, QBrush, QLCDNumber, QPushButton, QApplication, QTextEdit, QScrollArea, QTextCursor, QColor
from PyQt4.QtCore import QThread, Qt, QCoreApplication, QTime, QTimer, SIGNAL, pyqtSignal, QObject
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
class handleTimer(QObject):
timerChanged = pyqtSignal(str, name = 'timerChanged')
def __init__(self):
QObject.__init__(self)
self._isRunning = False
self.timerString = "00:00:00"
self.timerReset()
def timerStart(self, channel=0):
if not self._isRunning and self.timerString != "00:00:00":
print("-Reset")
self.timerReset()
elif not self._isRunning:
print("-Start")
self._isRunning = True
self.timer2.start()
self.lcdTimer2.start()
def stop(self, channel=0):
print("-Stop")
if self._isRunning:
self.updateNumber()
self.timer2.stop()
self.lcdTimer2.restart()
self._isRunning = False
def timerReset(self):
print("-Reset")
self.lcdTimer2 = QTime(0,0,0,0)
self.timer2 = QTimer(self)
self.timer2.setInterval(50)
self.timer2.timeout.connect(self.updateNumber)
self.updateNumber()
def updateNumber(self):
if self._isRunning:
self.telapsed = self.lcdTimer2.elapsed()
self.msecs = self.telapsed % 1000
self.secs = int(self.telapsed / 1000)
self.mins = (self.secs / 60) % 60
self.secs = self.secs % 60
self.timerString = str(self.mins).zfill(2) + ":" + str(self.secs).zfill(2) + ":" + str(self.msecs)[:2].zfill(2)
else:
self.timerString = "00:00:00"
self.timerChanged.emit(self.timerString)
print(self.timerString)
class Timer(QWidget):
def __init__(self):
super(Timer, self).__init__()
self.initUI()
def initUI(self):
# Setup font
font = QFont()
font.setFamily('Lucida')
font.setFixedPitch(True)
font.setPointSize(30)
fontPalette = QPalette()
# Background image
oImage = QImage("bg.jpg")
sImage = oImage
sImage = oImage.scaledToWidth(1920)
palette = QPalette()
palette.setBrush(10, QBrush(sImage))
self.setPalette(palette)
# LCD display
self.lcd = QLCDNumber(self)
self.lcd.setMode(1)
self.lcd.setSegmentStyle(1)
self.lcd.setDigitCount(8)
self.lcd.resize(1020, 1080)
self.lcd.setGeometry(200, 0, 1020, 1080)
self.lcd.setFrameShape(0)
self.lcd.display("00:00:00")
# Setup thread
self.simulThread = QThread()
### self.simulThread.start()
self.simulRunner = handleTimer()
self.simulRunner.moveToThread(self.simulThread)
self.simulRunner.timerChanged.connect(self.updateLCD)
# Quit button
self.btnQuit = QPushButton('Quit', self)
self.btnQuit.clicked.connect(self.quitTimer)
self.btnQuit.move(50, 1005)
# Reset button
self.btnReset = QPushButton('Reset', self)
self.btnReset.move(150, 1005)
self.btnReset.clicked.connect(self.simulRunner.timerReset)
# Start button
self.btnStart = QPushButton('Start', self)
self.btnStart.move(750, 1005)
### self.btnStart.clicked.connect(self.simulRunner.timerStart)
self.btnStart.clicked.connect(self.simulThread.start) ###
self.simulThread.started.connect(self.simulRunner.timerStart) ###
### GPIO.add_event_detect(18, GPIO.FALLING, callback=self.simulRunner.timerStart, bouncetime=1000)
GPIO.add_event_detect(18, GPIO.FALLING, callback=self.simulThread.start, bouncetime=1000) ###
# Stop button
self.btnStop = QPushButton('Stop', self)
self.btnStop.move(850, 1005)
self.btnStop.clicked.connect(lambda: self.simulRunner.stop())
# self.simulThread.finished.connect(self.simulRunner.timerDelete)
GPIO.add_event_detect(23, GPIO.FALLING, callback=lambda x: self.simulRunner.stop(), bouncetime=1000)
# Setup the window
self.setWindowTitle('Timer')
self.setGeometry(0, 0, 1220, 1080)
self.setWindowFlags(Qt.FramelessWindowHint)
def updateLCD(self, val):
self.lcd.display(val)
self.lcd.update()
def quitTimer(self):
GPIO.cleanup()
QCoreApplication.instance().quit()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Timer()
ex.show()
sys.exit(app.exec_())
似乎是add_event_detect阻塞了線程,或類似的東西。
可能有一個更簡單的解決方案,但這至少有效。
我將add_event_detect的回調函數放在它自己的線程中,並為按下的按鈕添加了自定義信號。 在具有計時器的線程中,我放置了一個監聽器,以了解所按下的按鈕。
編碼:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import RPi.GPIO as GPIO
import time
import threading
from PyQt4.QtGui import QWidget, QFont, QPalette, QImage, QBrush, QLCDNumber, QPushButton, QApplication, QTextEdit, QScrollArea, QTextCursor, QColor, QMainWindow
from PyQt4.QtCore import QThread, Qt, QCoreApplication, QTime, QTimer, pyqtSignal, QObject
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
class handleButtons(QObject):
button = pyqtSignal(str, name = 'button')
def __init__(self):
QObject.__init__(self)
def buttonListener(self, channel):
if channel == 18:
self.button.emit("start")
elif channel == 23:
self.button.emit("stop")
class handleTimer(QObject):
timerChanged = pyqtSignal(str, name = 'timerChanged')
finished = pyqtSignal()
def __init__(self):
QObject.__init__(self)
self._isRunning = False
self.timerString = "00:00:00"
self.timerReset()
def pushButton(self, button):
if button == "start":
self.timerStart()
elif button == "stop":
self.stop()
def timerStart(self, channel=0):
if not self._isRunning and self.timerString != "00:00:00":
self.timerReset()
elif not self._isRunning:
self._isRunning = True
self.timer2.start(50)
self.lcdTimer2.start()
def stop(self, channel=0):
if self._isRunning:
self.updateNumber()
self.timer2.stop()
self.lcdTimer2.restart()
self._isRunning = False
self.finished.emit()
def timerReset(self):
self.lcdTimer2 = QTime(0,0,0,0)
self.timer2 = QTimer()
self.timer2.setInterval(50)
self.timer2.timeout.connect(self.updateNumber)
self.updateNumber()
def updateNumber(self):
if self._isRunning:
self.telapsed = self.lcdTimer2.elapsed()
self.msecs = self.telapsed % 1000
self.secs = int(self.telapsed / 1000)
self.mins = (self.secs / 60) % 60
self.secs = self.secs % 60
self.timerString = str(self.mins).zfill(2) + ":" + str(self.secs).zfill(2) + ":" + str(self.msecs)[:2].zfill(2)
else:
self.timerString = "00:00:00"
self.timerChanged.emit(self.timerString)
class Timer(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
# Setup thread
self.timerThread = QThread()
self.timerRunner = handleTimer()
self.timerRunner.moveToThread(self.timerThread)
self.timerRunner.timerChanged.connect(self.updateLCD)
self.timerThread.started.connect(self.timerRunner.timerReset)
self.buttonRunner = handleButtons()
self.buttonRunner.moveToThread(self.timerThread)
self.buttonRunner.button.connect(self.timerRunner.pushButton)
self.timerThread.start()
self.initUI()
def initUI(self):
# Setup font
font = QFont()
font.setFamily('Lucida')
font.setFixedPitch(True)
font.setPointSize(30)
fontPalette = QPalette()
# Background image
oImage = QImage("bg.jpg")
sImage = oImage
sImage = oImage.scaledToWidth(1920)
palette = QPalette()
palette.setBrush(10, QBrush(sImage))
self.setPalette(palette)
# LCD display
self.lcd = QLCDNumber(self)
self.lcd.setMode(1)
self.lcd.setSegmentStyle(1)
self.lcd.setDigitCount(8)
self.lcd.resize(1020, 1080)
self.lcd.setGeometry(200, 0, 1020, 1080)
self.lcd.setFrameShape(0)
self.lcd.display("00:00:00")
# Quit button
self.btnQuit = QPushButton('Quit', self)
self.btnQuit.clicked.connect(self.quitTimer)
self.btnQuit.move(50, 1005)
# Start button
GPIO.add_event_detect(18, GPIO.FALLING, callback=self.buttonRunner.buttonListener, bouncetime=1000)
# Stop button
GPIO.add_event_detect(23, GPIO.FALLING, callback=lambda x: self.timerRunner.stop(), bouncetime=1000)
# Setup the window
self.setWindowTitle('Timer')
self.setGeometry(0, 0, 1220, 1080)
self.setWindowFlags(Qt.FramelessWindowHint)
def updateLCD(self, val):
self.lcd.display(val)
def quitTimer(self):
GPIO.cleanup()
QCoreApplication.instance().quit()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Timer()
main.show()
sys.exit(app.exec_())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.