不想用GPIO按钮启动的定时器

时间:2017-11-23 01:20:03

标签: python pyqt

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

1 个答案:

答案 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_())