如何在单击按钮时重置计时器

时间:2018-09-25 10:51:01

标签: python-3.x timer pyqt5

当下面的函数运行时,我的代码中有两个按钮,它启动一个计时器并禁用另一个按钮。现在来简要分解正在发生的事情: 按下OuterSwitch按钮,该按钮将检查以确保内门已关闭,然后再打开外门。现在再次按下OuterSwitch按钮时,它会禁用innerswitch按钮并锁定外门。这还会启动一个计时器,持续3秒钟。现在,如果我这次按下外部开关打开外门,我希望它停止计时器并重置它,因此当我再次按下以关闭门时,它从3秒开始。目前,当我再次关闭门时,它只是并行运行多个计时器。我一直无济于事,希望有人可以指导我如何做到这一点?我希望这是有意义的,如果需要更多信息,请询问。

import sys
import board
import RPi.GPIO as GPIO
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap, QColor, QPalette
from PyQt5.QtWidgets import QApplication
import time
from functools import partial
from threading import Thread


Outer = 22
Inner = 27
GPIO.setup(Outer,GPIO.OUT)
GPIO.setup(Inner,GPIO.OUT)
GPIO.output(Outer,GPIO.HIGH)
GPIO.output(Inner,GPIO.HIGH)




class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.Timer = QtWidgets.QLCDNumber(self.centralwidget)
        self.Timer.setObjectName("Timer")
        self.horizontalLayout.addWidget(self.Timer)
        self.OuterSwitch = QtWidgets.QPushButton(self.centralwidget)
        self.OuterSwitch.setObjectName("OuterSwitch")
        self.horizontalLayout.addWidget(self.OuterSwitch)
        self.InnerSwitch = QtWidgets.QPushButton(self.centralwidget)
        self.InnerSwitch.setObjectName("InnerSwitch")
        self.horizontalLayout.addWidget(self.InnerSwitch)
        self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)




    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.OuterSwitch.setText(_translate("MainWindow", "Open Outer Door"))
        self.InnerSwitch.setText(_translate("MainWindow", "Open Inner Door"))





class ControlMainWindow(QtWidgets.QMainWindow):
    def __init__(self,parent=None):
        super(ControlMainWindow,self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.OuterSwitch.clicked.connect(self.OuterControl)
        self.ui.InnerSwitch.clicked.connect(self.InnerControl)


    def OuterControl(self):
        if GPIO.input(Inner)==0: #InnerDoorOpen
            return GPIO.output(Outer,GPIO.HIGH),print("Please Close Inner Door")
        elif GPIO.input(Outer) ==1: #Outer Door Close
            self.ui.OuterSwitch.setText(QtWidgets.QApplication.translate("MainWindow", "Close Outer Door",None))
            QtWidgets.QApplication.processEvents()
            return GPIO.output(Outer,GPIO.LOW) #Open Outer Door
        elif GPIO.input(Outer) == 0: #OuterDoor Open
            self.ui.InnerSwitch.setEnabled(False)
            self.ui.OuterSwitch.setText(QtWidgets.QApplication.translate("MainWindow", "Open Outer Door",None))
            QtWidgets.QApplication.processEvents()

            QtCore.QTimer.singleShot(3000,partial(self.ui.InnerSwitch.setEnabled,True))
            return GPIO.output(Outer,GPIO.HIGH) #Close OuterDoor




    def  InnerControl(self):
        if GPIO.input(Outer)==0: #Outer Open
            return GPIO.output(Inner,GPIO.HIGH), print("Please Close Outer Door")
        elif GPIO.input(Inner) ==1: #Inner Door Close
            self.ui.InnerSwitch.setText(QtWidgets.QApplication.translate("MainWindow", "Close Inner Door",None))
            QtWidgets.QApplication.processEvents()
            return GPIO.output(Inner,GPIO.LOW) #Open Inner
        elif GPIO.input(Inner) ==0:
            self.ui.InnerSwitch.setText(QtWidgets.QApplication.translate("MainWindow", "Open Inner Door",None))
            QtWidgets.QApplication.processEvents()
            return GPIO.output(Inner,GPIO.HIGH) #Close Inner





        #Troubleshoot-comment in
##    sys.excepthook=sys.excepthook
##    def exception_hook(exctype,value,traceback):
##        print(exctype,value,traceback)
##        sys.exit(1)
##    sys.excepthook=exception_hook




if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mySW = ControlMainWindow()
    mySW.show()
    sys.exit(app.exec_())
    MainWindow.show()
    sys.exit(app.exec_())

这是控制外门的代码的一部分。

def OuterControl(self):
        if GPIO.input(Inner)==0: #InnerDoorOpen
            return GPIO.output(Outer,GPIO.HIGH),print("Please Close Inner Door")
        elif GPIO.input(Outer) ==1: #Outer Door Close
            self.ui.OuterSwitch.setText(QtWidgets.QApplication.translate("MainWindow", "Close Outer Door",None))
            QtWidgets.QApplication.processEvents()
            return GPIO.output(Outer,GPIO.LOW) #Open Outer Door
        elif GPIO.input(Outer) == 0: #OuterDoor Open
            self.ui.InnerSwitch.setEnabled(False)
            self.ui.OuterSwitch.setText(QtWidgets.QApplication.translate("MainWindow", "Open Outer Door",None))
            QtWidgets.QApplication.processEvents()

            QtCore.QTimer.singleShot(3000,partial(self.ui.InnerSwitch.setEnabled,True))
            return GPIO.output(Outer,GPIO.HIGH) #Close OuterDoor

2 个答案:

答案 0 :(得分:0)

尝试一下QTimeLine类提供了控制动画的时间表。

import sys
from PyQt5.QtCore    import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui     import *

class Window(QWidget):
    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)
        self.resize(400, 230)
        self.setWindowTitle("QTimer.singleShot vs. QTimeLine")

        layV = QVBoxLayout()
        self.setLayout(layV)
        self.lcd = QLCDNumber()  
        self.i = 0        
        layH = QHBoxLayout()
        self.lblSingleShot = QLabel("QTimer.singleShot")
        self.lblSingleShot.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        self.lblTimeLine   = QLabel("QTimeLine")
        self.lblTimeLine.setFrameStyle(QFrame.Panel | QFrame.Sunken)
        layH.addWidget(self.lblSingleShot)
        layH.addWidget(self.lblTimeLine)

        self.btnStart = QPushButton("Start Timer", clicked=self.startTimer)

        layV.addWidget(self.lcd)
        layV.addLayout(layH)
        layV.addWidget(self.btnStart)

        self.timer = QTimer()  
        self.timer.setInterval(1000)
        self.timer.timeout.connect(self.updateData)        

        self.timeLine = QTimeLine(3000)                       # <---
        self.timeLine.setFrameRange(0, 2)  
        self.timeLine.setUpdateInterval(1000)
        self.timeLine.finished.connect(self.finishTimeLine)   # <---

    def finishTimeLine(self):                                 # <---
        self.lblTimeLine.setStyleSheet("background-color: green; color: white;") 

    def startTimer(self):
        if self.btnStart.text() == "Start Timer":
            self.i = 1
            self.lcd.display(self.i)
            self.timer.start(1000) 
            self.btnStart.setText("Stop Timer")
            QTimer.singleShot(3000, self.onShow)
            self.lblSingleShot.setStyleSheet("background-color: white; color: black;")
            self.lblSingleShot.setText("QTimer.singleShot")
            self.lblTimeLine.setStyleSheet("background-color: white; color: black;")
            self.lblTimeLine.setText("QTimeLine")

            self.timeLine.start()                             # <---
        else:
            self.btnStart.setText("Start Timer")
            self.timer.stop()
            self.timeLine.stop()                              # <---
            self.lblTimeLine.setStyleSheet("background-color: red; color: white;")
            self.lblTimeLine.setText("QTimeLine - Stop")
        self.i = 1            

    def updateData(self):
        self.i += 1
        self.lcd.display(self.i)

    def onShow(self):
        self.lblSingleShot.setStyleSheet("background-color: green; color: white;")    
        self.lblSingleShot.setText("<b>def onShow() - Start.")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex  = Window()
    ex.show()
    sys.exit(app.exec_())   

enter image description here

enter image description here

答案 1 :(得分:0)

我设法解决了这个问题: 所以我要做的是创建一个单独的计时器,可以将其杀死并将其设置为单发。然后,我设置一个可调用函数,该函数将将内部开关设置为true / active。仅当计时器启动时。.请参阅所附代码:

class ControlMainWindow(QtWidgets.QMainWindow):
    def __init__(self,parent=None):
        super(ControlMainWindow,self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.ui.OuterSwitch.clicked.connect(self.OuterControl)
        self.ui.InnerSwitch.clicked.connect(self.InnerControl)

        self.current_timer = None

    def starttimer(self):
        if self.current_timer:
            self.current_timer.stop()
            self.current_timer.deleteLater()
        self.current_timer=QtCore.QTimer()
        self.current_timer.setSingleShot(True)
        self.current_timer.start(3000)
        self.current_timer.timeout.connect(self.InnerSwitchOn)

    def InnerSwitchOn(self):   
        self.ui.InnerSwitch.setEnabled(True)

    def OuterControl(self):
        if GPIO.input(Inner)==0: #InnerDoorOpen
            return GPIO.output(Outer,GPIO.HIGH),print("Please Close Inner Door")
        elif GPIO.input(Outer) ==1: #Outer Door Close
            self.ui.OuterSwitch.setText(QtWidgets.QApplication.translate("MainWindow", "Close Outer Door",None))
            QtWidgets.QApplication.processEvents()
            return GPIO.output(Outer,GPIO.LOW) #Open Outer Door
        elif GPIO.input(Outer) == 0: #OuterDoor Open
            self.ui.InnerSwitch.setEnabled(False)
            self.ui.OuterSwitch.setText(QtWidgets.QApplication.translate("MainWindow", "Open Outer Door",None))
            QtWidgets.QApplication.processEvents()
            self.starttimer()
            return GPIO.output(Outer,GPIO.HIGH) #Close OuterDoor