我目前正在尝试使用PyQt创建一个线程计时器应用程序。简单吧?我也是这么想的。然而,在花了一整天试图弄清楚出了什么问题之后,我仍然完全不知道。在我所有的巨大顽固中,我拒绝放弃应该是15分钟的项目。
Heres mah codez:
__author__ = 'Darth Vader'
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox, QApplication, QDialog
from PyQt5.QtCore import QThread
from timerui import Ui_Form
import sys
import ctypes
import time
import threading
class Timer(QThread):
def makeNoise(self):
pass
def run(self):
self.ui.startButton.setStyleSheet('''QPushButton {color: red;font: bold 15px;}''')
self.ui.startButton.setEnabled(False)
self.hour = int(self.ui.spinBoxHrs.value())
self.min = int(self.ui.spinBoxMin.value())
self.sec = int(self.ui.spinBoxSec.value())
if self.sec:
self.countSec = self.sec
elif self.min and not self.sec:
self.countSec = 60
self.min -= 1
elif self.hour and not self.min and not self.sec:
self.min = 59
self.countSec = 60
print(self.countSec)
while self.countSec or self.hour or self.min:
if not self.countSec and self.min:
self.min -= 1
self.countSec = 60
elif not self.countSec and not self.min and self.hour:
self.hour -= 1
self.min = 59
self.sec = 60
elif not self.countSec and not self.min and not self.hour:
self.makeNoise()
break
time.sleep(1)
self.countSec -= 1
self.ui.startButton.setText("%dh %dm %ds" % (self.hour, self.min, self.sec))
self.ui.startButton.setEnabled(True)
self.ui.startButton.setText("Start")
self.ui.startButton.setStyleSheet('QPushButton{}')
def setup(self, gui):
self.ui = gui
def __init__(self):
QThread.__init__(self)
def start():
t = Timer()
t.start()
if __name__ == '__main__':
myappid = u'org.ayoung.timer'
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
app = QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon('res/favicon.png'))
window = QDialog()
ui = Ui_Form()
ui.setupUi(window)
ui.startButton.clicked.connect(start)
window.show()
sys.exit(app.exec_())
错误:
QThread: Destroyed while thread is still running
QMutex: destroying locked mutex
从我读过的内容来看,这两个错误与垃圾收集有关,但我完全不知道如何修复它们。
谢谢!
答案 0 :(得分:1)
您的代码有三个问题。在解决第三个问题之前,你需要解决第一个问题(第二个问题应该在解决第一个问题后消失)
您的功能和方法令人困惑。我可以告诉你,因为你有一个名为start
的函数,但是函数签名中的第一个参数被称为self
这一事实表明你希望它是一个对象的方法。您可能需要阅读this以获得有关函数和方法之间差异的详细说明。
由于前一点以及QPushButton.clicked
信号发出布尔值这一事实,意味着当调用start
时,self
变量包含{{ 1}}(而不是对类实例的引用(也称为对象) - 会发生的是True
是方法而不是函数)
第start
行执行以下操作:
self.t = Timer().start()
创建Timer()
类Timer
方法称为start
方法的返回值存储在start()
中(我们忽略了self.t
不是对象引用的问题)。您要做的是创建self
的实例,并将其分配给Timer
。然后在self.t
上致电start()
。例如:
self.t
这可确保self.t = Timer()
self.t.start()
对象保存在某处,并且不会收集垃圾。
答案 1 :(得分:0)
def start(self):
self.t = Timer().start()
...
ui.startButton.clicked.connect(start)
这里是将信号连接到插槽。传递给广告位的参数是button state,即bool
。因此,self
在您的案例中为True
。