我有一个计时器,我可以从屏幕上的开始/停止按钮或两个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_())
答案 0 :(得分:0)
似乎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_())