单击停止按钮时无法使秒表停止

Can't make stopwatch stop when click stop button

我正在尝试在我的 GUI 上构建这个秒表: 它应该在我点击 "run" 按钮时开始 运行,并在小文本 window 上显示它的 运行; 一旦我点击 "stop" 按钮,我希望它在大文本 window 上显示 "test ended at 'hh:mm:ss'",并清除小文本 window,然后 "hold"时钟直到我下次单击 "run" 按钮"

一切都按计划进行,预计一旦我点击 "stop" 时钟会消失一秒钟,然后又会恢复。 此外,如果我想重新启动秒表,我需要在 "run" 按钮上单击两次(不是第一次,而是第二次和第三次..)

我也遇到了这个错误(尽管出现了 GUI): RecursionError:调用 Python 对象时超出最大递归深度

这是我用 Qt Designer 生成的代码:

from PyQt5 import QtCore, QtGui, QtWidgets
import time                                                            

class Ui_MainWindow(object):
  def setupUi(self, MainWindow):
    MainWindow.setObjectName("MainWindow")
    MainWindow.resize(895, 422)
    self.centralwidget = QtWidgets.QWidget(MainWindow)
    self.centralwidget.setObjectName("centralwidget")
    ###txtoutput = big window for text###
    self.txtoutput = QtWidgets.QTextBrowser(self.centralwidget)
    self.txtoutput.setGeometry(QtCore.QRect(150, 200, 471, 192))
    self.txtoutput.setObjectName("txtoutput")
    ###modeltype = droplist###
    self.modeltype = QtWidgets.QComboBox(self.centralwidget)
    self.modeltype.setGeometry(QtCore.QRect(50, 90, 69, 22))
    self.modeltype.setObjectName("modeltype")
    self.modeltype.addItem("")
    self.modeltype.addItem("")
    self.modeltype.addItem("")
    ###seriallbl = label above input window###
    self.seriallbl = QtWidgets.QLabel(self.centralwidget)
    self.seriallbl.setGeometry(QtCore.QRect(90, 30, 81, 16))
    self.seriallbl.setObjectName("seriallbl")
    ###getserialbtn = "Enter" button###
    self.getserialbtn = QtWidgets.QPushButton(self.centralwidget)
    self.getserialbtn.setGeometry(QtCore.QRect(210, 50, 75, 23))
    self.getserialbtn.setObjectName("getserialbtn")
    ###chuckrealeasebtn = "Chuck"/"Release" button###
    self.chuckrealeasebtn = QtWidgets.QPushButton(self.centralwidget)
    self.chuckrealeasebtn.setEnabled(False)
    self.chuckrealeasebtn.setGeometry(QtCore.QRect(50, 120, 75, 23))
    self.chuckrealeasebtn.setObjectName("chuckrealeasebtn")
    self.chuckrealeasebtn.setCheckable(True)
    ###runbtn = "Run" button###
    self.runbtn = QtWidgets.QPushButton(self.centralwidget)
    self.runbtn.setGeometry(QtCore.QRect(580, 70, 91, 61))
    font = QtGui.QFont()
    font.setPointSize(28)
    font.setBold(True)
    font.setWeight(75)
    self.runbtn.setFont(font)
    self.runbtn.setCheckable(True)
    self.runbtn.setObjectName("runbtn")
    ###serialinput = Text box for serial # input###
    self.serialinput = QtWidgets.QTextEdit(self.centralwidget)
    self.serialinput.setGeometry(QtCore.QRect(50, 50, 151, 31))
    self.serialinput.setObjectName("serialinput")
    ###stopbtn = "Stop" button###
    self.stopbtn = QtWidgets.QPushButton(self.centralwidget)
    self.stopbtn.setGeometry(QtCore.QRect(680, 70, 91, 61))
    font = QtGui.QFont()
    font.setPointSize(28)
    font.setBold(True)
    font.setWeight(75)
    self.stopbtn.setFont(font)
    self.stopbtn.setObjectName("stopbtn")
    self.chuckrealeasebtn.setEnabled(False)
    ###exitbtn = "Exit" button###
    self.exitbtn = QtWidgets.QPushButton(self.centralwidget)
    self.exitbtn.setGeometry(QtCore.QRect(740, 370, 75, 23))
    self.exitbtn.setObjectName("exitbtn")
    self.timelbl = QtWidgets.QLabel(self.centralwidget)
    self.timelbl.setGeometry(QtCore.QRect(260, 140, 147, 23))         # +
    self.timelbl.setObjectName("timelbl")
    ###timertxt = label above timer window###
    self.timertxt = QtWidgets.QTextBrowser(self.centralwidget)
    self.timertxt.setGeometry(QtCore.QRect(260, 160, 141, 31))
    self.timertxt.setObjectName("timertxt")

    MainWindow.setCentralWidget(self.centralwidget)
    self.retranslateUi(MainWindow)
    QtCore.QMetaObject.connectSlotsByName(MainWindow)

def retranslateUi(self, MainWindow):
    _translate = QtCore.QCoreApplication.translate
    MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
    self.modeltype.setItemText(0, _translate("MainWindow", "Type 1"))
    self.modeltype.setItemText(1, _translate("MainWindow", "Type 2"))
    self.modeltype.setItemText(2, _translate("MainWindow", "Type 3"))
    self.seriallbl.setText(_translate("MainWindow", "Enter serial #"))
    self.getserialbtn.setText(_translate("MainWindow", "Enter"))
    self.chuckrealeasebtn.setText(_translate("MainWindow", "chuck"))
    self.runbtn.setText(_translate("MainWindow", "Run"))
    self.stopbtn.setText(_translate("MainWindow", "Stop"))
    self.exitbtn.setText(_translate("MainWindow", "Exit"))
    self.timelbl.setText(_translate("MainWindow", "Timer"))

这是我的主要功能:

from PyQt5 import QtWidgets, QtCore
from mainwin import Ui_MainWindow
import time


 class ApplicationWindow(QtWidgets.QMainWindow):
  def __init__(self):
    super(ApplicationWindow, self).__init__()

    self.ui = Ui_MainWindow()
    self.ui.setupUi(self)   

    self.ui.exitbtn.clicked.connect(self.exit_Clicked)      
    self.ui.getserialbtn.clicked.connect(self.serial_Entered)
    self.ui.chuckrealeasebtn.clicked.connect(self.chuck_Clicked)
    self.ui.runbtn.clicked.connect(self.runbtn_Clicked)                    
    self.ui.stopbtn.clicked.connect(self.stopbtn_Clicked)                    

def runbtn_Clicked(self): 
    if self.ui.runbtn.isChecked(): 
        self.ui.stopbtn.setEnabled(True)
        self.ui.runbtn.setEnabled(False)
        self.timer = QtCore.QTimer(self)                            
        self.timer.timeout.connect(self.start_Timer)                   
        self.time = 0
        self.timeInterval = 1000                                    
        self.timer.start(self.timeInterval)                                      
        self.ui.timertxt.setText(time.strftime('%H:%M:%S',time.gmtime(self.time)))

def start_Timer(self):  
    self.time += 1
    self.set_Timer(self.time)
def set_Timer(self, int):
    if self.ui.runbtn.isChecked(): 
        self.time = int
        self.ui.timertxt.setText(time.strftime('%H:%M:%S',time.gmtime(self.time)))
        self.set_Timer(self.time)
def stopbtn_Clicked(self):  
    self.ui.stopbtn.setEnabled(False)
    self.ui.runbtn.setEnabled(True)
    self.ui.txtoutput.append("Test Ended at "+ time.strftime('%H:%M:%S',time.gmtime(self.time)))
    self.ui.timertxt.clear()
    self.time = 0

###exit_clicked = "Exit" button function###
def exit_Clicked(self):                                      
   self.close()        

###chuck_Clicked = "Chuck"/"Release" button function###    
def chuck_Clicked(self):
    if self.ui.chuckrealeasebtn.isChecked():
        mytext = self.ui.serialinput.toPlainText()
        self.ui.chuckrealeasebtn.setText("Release")
        self.ui.getserialbtn.setEnabled(False)
        self.ui.runbtn.setEnabled(True)
        self.ui.txtoutput.append(mytext+" - is chucked, Ready to run")
    else:
        self.ui.chuckrealeasebtn.setText("Chuck")
        self.ui.txtoutput.clear()
        self.ui.chuckrealeasebtn.setEnabled(False)
        self.ui.getserialbtn.setEnabled(True)
        self.ui.runbtn.setEnabled(False)

###serialentered = function that checks if the serial # that was entered is found or not found in a certain list###    
def serial_Entered(self):
    serialnum = self.ui.serialinput.toPlainText()
    listnum=self.ui.modeltype.currentIndex()
    if (listnum==0):
        with open(r'C:\Users\hv_lab\Documents\python tests\Serial Numbers - Type 1.txt') as r1:
            if serialnum in r1.read():
                self.ui.txtoutput.append(serialnum+" - Serial was found in List 1")
                self.ui.chuckrealeasebtn.setEnabled(True)
            else:
                self.ui.txtoutput.append(serialnum+" - Serial was NOT found in List 1")
                self.ui.chuckrealeasebtn.setEnabled(False)
    elif (listnum==1):
        with open(r'C:\Users\hv_lab\Documents\python tests\Serial Numbers - Type 2.txt') as r2:
            if serialnum in r2.read():
                self.ui.txtoutput.append(serialnum+" - Serial was found in List 2")
                self.ui.chuckrealeasebtn.setEnabled(True)
            else:
                self.ui.txtoutput.append(serialnum+" - Serial was NOT found in List 2")
                self.ui.chuckrealeasebtn.setEnabled(False)
    elif (listnum==2):
        with open(r'C:\Users\hv_lab\Documents\python tests\Serial Numbers - Type 3.txt') as r3:
            if serialnum in r3.read():
                self.ui.txtoutput.append(serialnum+" - Serial was found in List 3")
                self.ui.chuckrealeasebtn.setEnabled(True)
            else:
                 self.ui.txtoutput.append(serialnum+" - Serial was NOT found in List 3")
                 self.ui.chuckrealeasebtn.setEnabled(False)


if __name__ == "__main__":
   import sys
   app = QtWidgets.QApplication(sys.argv)
   application = ApplicationWindow()
   application.show()
   sys.exit(app.exec_())

如果有人能提供帮助,我将不胜感激。 提前致谢! :D

试一试:

from PyQt5 import QtCore, QtGui, QtWidgets
import time                                                            

# from mainwin import Ui_MainWindow
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(895, 422)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        ###txtoutput = big window for text###
        self.txtoutput = QtWidgets.QTextBrowser(self.centralwidget)
        self.txtoutput.setGeometry(QtCore.QRect(150, 200, 471, 192))
        self.txtoutput.setObjectName("txtoutput")
        ###modeltype = droplist###
        self.modeltype = QtWidgets.QComboBox(self.centralwidget)
        self.modeltype.setGeometry(QtCore.QRect(50, 90, 69, 22))
        self.modeltype.setObjectName("modeltype")
        self.modeltype.addItem("")
        self.modeltype.addItem("")
        self.modeltype.addItem("")
        ###seriallbl = label above input window###
        self.seriallbl = QtWidgets.QLabel(self.centralwidget)
        self.seriallbl.setGeometry(QtCore.QRect(90, 30, 81, 16))
        self.seriallbl.setObjectName("seriallbl")
        ###getserialbtn = "Enter" button###
        self.getserialbtn = QtWidgets.QPushButton(self.centralwidget)
        self.getserialbtn.setGeometry(QtCore.QRect(210, 50, 75, 23))
        self.getserialbtn.setObjectName("getserialbtn")
        ###chuckrealeasebtn = "Chuck"/"Release" button###
        self.chuckrealeasebtn = QtWidgets.QPushButton(self.centralwidget)
        self.chuckrealeasebtn.setEnabled(False)
        self.chuckrealeasebtn.setGeometry(QtCore.QRect(50, 120, 75, 23))
        self.chuckrealeasebtn.setObjectName("chuckrealeasebtn")
        self.chuckrealeasebtn.setCheckable(True)
        ###runbtn = "Run" button###
        self.runbtn = QtWidgets.QPushButton(self.centralwidget)
        self.runbtn.setGeometry(QtCore.QRect(580, 70, 91, 61))
        font = QtGui.QFont()
        font.setPointSize(28)
        font.setBold(True)
        font.setWeight(75)
        self.runbtn.setFont(font)
        self.runbtn.setCheckable(True)
        self.runbtn.setObjectName("runbtn")
        ###serialinput = Text box for serial # input###
        self.serialinput = QtWidgets.QTextEdit(self.centralwidget)
        self.serialinput.setGeometry(QtCore.QRect(50, 50, 151, 31))
        self.serialinput.setObjectName("serialinput")
        ###stopbtn = "Stop" button###
        self.stopbtn = QtWidgets.QPushButton(self.centralwidget)
        self.stopbtn.setGeometry(QtCore.QRect(680, 70, 91, 61))
        font = QtGui.QFont()
        font.setPointSize(28)
        font.setBold(True)
        font.setWeight(75)
        self.stopbtn.setFont(font)
        self.stopbtn.setObjectName("stopbtn")
        self.chuckrealeasebtn.setEnabled(False)
        ###exitbtn = "Exit" button###
        self.exitbtn = QtWidgets.QPushButton(self.centralwidget)
        self.exitbtn.setGeometry(QtCore.QRect(740, 370, 75, 23))
        self.exitbtn.setObjectName("exitbtn")
        self.timelbl = QtWidgets.QLabel(self.centralwidget)
        self.timelbl.setGeometry(QtCore.QRect(260, 140, 147, 23))        
        self.timelbl.setObjectName("timelbl")
        ###timertxt = label above timer window###
        self.timertxt = QtWidgets.QTextBrowser(self.centralwidget)
        self.timertxt.setGeometry(QtCore.QRect(260, 160, 141, 31))
        self.timertxt.setObjectName("timertxt")

        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.modeltype.setItemText(0, _translate("MainWindow", "Type 1"))
        self.modeltype.setItemText(1, _translate("MainWindow", "Type 2"))
        self.modeltype.setItemText(2, _translate("MainWindow", "Type 3"))
        self.seriallbl.setText(_translate("MainWindow", "Enter serial #"))
        self.getserialbtn.setText(_translate("MainWindow", "Enter"))
        self.chuckrealeasebtn.setText(_translate("MainWindow", "chuck"))
        self.runbtn.setText(_translate("MainWindow", "Run"))
        self.stopbtn.setText(_translate("MainWindow", "Stop"))
        self.exitbtn.setText(_translate("MainWindow", "Exit"))
        self.timelbl.setText(_translate("MainWindow", "Timer"))


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(ApplicationWindow, self).__init__()

        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)   

        self.ui.exitbtn.clicked.connect(self.exit_Clicked)      
        self.ui.getserialbtn.clicked.connect(self.serial_Entered)
        self.ui.chuckrealeasebtn.clicked.connect(self.chuck_Clicked)
        self.ui.runbtn.clicked.connect(self.runbtn_Clicked)                    
        self.ui.stopbtn.clicked.connect(self.stopbtn_Clicked)      

        self.timer = QtCore.QTimer(self)                           # +++                   
        self.timer.timeout.connect(self.start_Timer)               # +++        
        self.timeInterval = 1000                                   # +++

    def runbtn_Clicked(self): 
#        if self.ui.runbtn.isChecked():                            # --- ???
        self.ui.stopbtn.setEnabled(True)
        self.ui.runbtn.setEnabled(False)
#            self.timer = QtCore.QTimer(self)                            
#            self.timer.timeout.connect(self.start_Timer)                   
        self.time = 0
#        self.timeInterval = 1000                                    
        self.timer.start(self.timeInterval)                                      
        self.ui.timertxt.setText(time.strftime('%H:%M:%S',time.gmtime(self.time)))

    def start_Timer(self):  
        self.time += 1
        self.set_Timer(self.time)

    def set_Timer(self, int):
#        if self.ui.runbtn.isChecked():                            # --- ???
        self.time = int
        self.ui.timertxt.setText(time.strftime('%H:%M:%S',time.gmtime(self.time)))

#        self.set_Timer(self.time)                                 # --- ???

    def stopbtn_Clicked(self):  
        self.ui.stopbtn.setEnabled(False)
        self.ui.runbtn.setEnabled(True)
        self.ui.txtoutput.append("Test Ended at "+ time.strftime('%H:%M:%S',time.gmtime(self.time)))
        self.ui.timertxt.clear()
        self.timer.stop()                                          # +++ !!!
#        self.time = 0

    ###exit_clicked = "Exit" button function###
    def exit_Clicked(self):                                      
       self.close()        

    ###chuck_Clicked = "Chuck"/"Release" button function###    
    def chuck_Clicked(self):
        if self.ui.chuckrealeasebtn.isChecked():
            mytext = self.ui.serialinput.toPlainText()
            self.ui.chuckrealeasebtn.setText("Release")
            self.ui.getserialbtn.setEnabled(False)
            self.ui.runbtn.setEnabled(True)
            self.ui.txtoutput.append(mytext+" - is chucked, Ready to run")
        else:
            self.ui.chuckrealeasebtn.setText("Chuck")
            self.ui.txtoutput.clear()
            self.ui.chuckrealeasebtn.setEnabled(False)
            self.ui.getserialbtn.setEnabled(True)
            self.ui.runbtn.setEnabled(False)

    ###serialentered = function that checks if the serial # that was entered is found or not found in a certain list###    
    def serial_Entered(self):
        serialnum = self.ui.serialinput.toPlainText()
        listnum=self.ui.modeltype.currentIndex()
        if (listnum==0):
            with open(r'C:\Users\hv_lab\Documents\python tests\Serial Numbers - Type 1.txt') as r1:
                if serialnum in r1.read():
                    self.ui.txtoutput.append(serialnum+" - Serial was found in List 1")
                    self.ui.chuckrealeasebtn.setEnabled(True)
                else:
                    self.ui.txtoutput.append(serialnum+" - Serial was NOT found in List 1")
                    self.ui.chuckrealeasebtn.setEnabled(False)
        elif (listnum==1):
            with open(r'C:\Users\hv_lab\Documents\python tests\Serial Numbers - Type 2.txt') as r2:
                if serialnum in r2.read():
                    self.ui.txtoutput.append(serialnum+" - Serial was found in List 2")
                    self.ui.chuckrealeasebtn.setEnabled(True)
                else:
                    self.ui.txtoutput.append(serialnum+" - Serial was NOT found in List 2")
                    self.ui.chuckrealeasebtn.setEnabled(False)
        elif (listnum==2):
            with open(r'C:\Users\hv_lab\Documents\python tests\Serial Numbers - Type 3.txt') as r3:
                if serialnum in r3.read():
                    self.ui.txtoutput.append(serialnum+" - Serial was found in List 3")
                    self.ui.chuckrealeasebtn.setEnabled(True)
                else:
                     self.ui.txtoutput.append(serialnum+" - Serial was NOT found in List 3")
                     self.ui.chuckrealeasebtn.setEnabled(False)


if __name__ == "__main__":
   import sys
   app = QtWidgets.QApplication(sys.argv)
   application = ApplicationWindow()
   application.show()
   sys.exit(app.exec_())

谢谢大家。 我将代码更改为:

class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
    super(ApplicationWindow, self).__init__()


    self.ui = Ui_MainWindow()
    self.ui.setupUi(self)   

    self.ui.exitbtn.clicked.connect(self.exit_Clicked)      
    self.ui.getserialbtn.clicked.connect(self.serial_Entered)
    self.ui.chuckrealeasebtn.clicked.connect(self.chuck_Clicked)
    self.ui.runbtn.clicked.connect(self.runbtn_Clicked)                    
    self.ui.stopbtn.clicked.connect(self.stopbtn_Clicked)                    

def runbtn_Clicked(self): 
    self.ui.stopbtn.setEnabled(True)
    self.ui.runbtn.setEnabled(False)
    self.ui.chuckrealeasebtn.setEnabled(False)
    self.timer = QtCore.QTimer(self)                            
    self.timer.timeout.connect(self.start_Timer)                   
    self.time = 0
    self.timeInterval = 1000                                    
    self.timer.start(self.timeInterval)                                      
    self.ui.timertxt.setText(time.strftime('%H:%M:%S',time.gmtime(self.time)))

def start_Timer(self):  
    self.time += 1
    self.set_Timer(self.time)
def set_Timer(self, int):
    self.time = int
    self.ui.timertxt.setText(time.strftime('%H:%M:%S',time.gmtime(self.time)))
        #self.set_Timer(self.time)
def stopbtn_Clicked(self):  
    self.ui.stopbtn.setEnabled(False)
    self.ui.chuckrealeasebtn.setEnabled(True)
    self.ui.txtoutput.append("Test Ended at "+ time.strftime('%H:%M:%S',time.gmtime(self.time)))
    self.ui.timertxt.clear()
    self.timer.stop()

而且效果很好(: