簡體   English   中英

不想以GPIO按鈕啟動的計時器

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM