如何在线程中使用 QDateTime?
How can I use a QDateTime inside a Thread?
我有一个线程需要执行一个繁重的函数。
首先,我有一个函数,它从 GUI 中获取两个 QDateTime
值并将它们转换为 UNIX 时间戳。其次,"heavy" 函数使用这些值来执行任务。
这两个函数 (function_task, time_converter_to_unix)
不属于任何 class,所以据我所知我可以在线程中使用它们。
但不是参数,因为我无法访问 QDateTime
值。
Error: AttributeError: 'TaskThread' object has no attribute 'startTime'
如何访问 QDateTime
并从线程中读取内容?谢谢。
编辑: 完整代码。您还可以在以下 link 中找到 GUI 的 link:interface.ui
import sys
import datetime
import time
from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtCore import *
from PyQt4.QtGui import *
# Link to GUI
qtCreatorFile = "interface.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
def time_converter_to_unix(start_datetime, end_datetime):
# Convert QTimeEdit to UNIX Timestamp (int, msec included), and then to float
start_datetime_unix_int = start_datetime.toMSecsSinceEpoch ()
start_datetime_unix = (float(start_datetime_unix_int) / 1000)
end_datetime_unix_int = end_datetime.toMSecsSinceEpoch ()
end_datetime_unix = (float(end_datetime_unix_int) / 1000)
return start_datetime_unix, end_datetime_unix
def dummy_function(self, start_datetime_unix, end_datetime_unix):
# Dummy function, just to simulate a task
result = start_datetime_unix + end_datetime_unix
print result
class Tool(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent = None):
# Setting-ip UI
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
# Button Action
self.runButton.clicked.connect(self.onStart)
# Progress Bar and Label. At the begining, the bar is at 0
self.progressBar.setValue(0)
self.progressBar.setRange(0,100)
self.resultLabel.setText("Waiting...")
#Thread
self.myLongTask = TaskThread()
self.myLongTask.taskFinished.connect(self.onFinished)
def onStart(self):
# Before running the thread, we set the progress bar in waiting mode
self.progressBar.setRange(0,0)
self.resultLabel.setText("In progress...")
print "Starting thread..."
self.myLongTask.start()
def onFinished(self):
# Stop the pulsation when the thread has finished
self.progressBar.setRange(0,1)
self.progressBar.setValue(1)
self.resultLabel.setText("Done")
class TaskThread(QtCore.QThread):
taskFinished = QtCore.pyqtSignal()
def __init__(self):
QtCore.QThread.__init__(self)
def __del__(self):
self.wait()
def run(self):
# First, we read the times from the QDateTime elements in the interface
print "Getting times..."
start_datetime_unix, end_datetime_unix = time_converter_to_unix(self.startTime.dateTime(), self.endTime.dateTime())
# Then, we put these values in my_function
print "Executing function..."
dummy_function(self, start_datetime_unix, end_datetime_unix)
# To finish, we execute onFinished.
print "Finishing thread..."
self.taskFinished.emit()
def main():
app = QtGui.QApplication(sys.argv)
window = Tool()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
如果您将它与.ui 一起执行,您会看到,一旦我们单击"Run",进度条将保持等待模式,并出现上面注释的错误。
startTime
和 endTime
属于 GUI,而不属于线程,这就是您收到该错误的原因。
另一方面建议不要从其他线程访问GUI,最好在启动线程前获取值并设置为线程的属性如下图:
class Tool(QtGui.QMainWindow, Ui_MainWindow):
...
def onStart(self):
# Before running the thread, we set the progress bar in waiting mode
self.progressBar.setRange(0,0)
self.resultLabel.setText("In progress...")
self.myLongTask.start_dt = self.startTime.dateTime() # <----
self.myLongTask.end_dt = self.endTime.dateTime() # <----
print "Starting thread..."
self.myLongTask.start()
...
class TaskThread(QtCore.QThread):
...
def run(self):
# First, we read the times from the QDateTime elements in the interface
print "Getting times..."
start_datetime_unix, end_datetime_unix = time_converter_to_unix(self.start_dt, self.end_dt) # <----
# Then, we put these values in my_function
print "Executing function..."
dummy_function(self, start_datetime_unix, end_datetime_unix)
# To finish, we execute onFinished.
print "Finishing thread..."
self.taskFinished.emit()
我有一个线程需要执行一个繁重的函数。
首先,我有一个函数,它从 GUI 中获取两个 QDateTime
值并将它们转换为 UNIX 时间戳。其次,"heavy" 函数使用这些值来执行任务。
这两个函数 (function_task, time_converter_to_unix)
不属于任何 class,所以据我所知我可以在线程中使用它们。
但不是参数,因为我无法访问 QDateTime
值。
Error: AttributeError: 'TaskThread' object has no attribute 'startTime'
如何访问 QDateTime
并从线程中读取内容?谢谢。
编辑: 完整代码。您还可以在以下 link 中找到 GUI 的 link:interface.ui
import sys
import datetime
import time
from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtCore import *
from PyQt4.QtGui import *
# Link to GUI
qtCreatorFile = "interface.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
def time_converter_to_unix(start_datetime, end_datetime):
# Convert QTimeEdit to UNIX Timestamp (int, msec included), and then to float
start_datetime_unix_int = start_datetime.toMSecsSinceEpoch ()
start_datetime_unix = (float(start_datetime_unix_int) / 1000)
end_datetime_unix_int = end_datetime.toMSecsSinceEpoch ()
end_datetime_unix = (float(end_datetime_unix_int) / 1000)
return start_datetime_unix, end_datetime_unix
def dummy_function(self, start_datetime_unix, end_datetime_unix):
# Dummy function, just to simulate a task
result = start_datetime_unix + end_datetime_unix
print result
class Tool(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent = None):
# Setting-ip UI
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
# Button Action
self.runButton.clicked.connect(self.onStart)
# Progress Bar and Label. At the begining, the bar is at 0
self.progressBar.setValue(0)
self.progressBar.setRange(0,100)
self.resultLabel.setText("Waiting...")
#Thread
self.myLongTask = TaskThread()
self.myLongTask.taskFinished.connect(self.onFinished)
def onStart(self):
# Before running the thread, we set the progress bar in waiting mode
self.progressBar.setRange(0,0)
self.resultLabel.setText("In progress...")
print "Starting thread..."
self.myLongTask.start()
def onFinished(self):
# Stop the pulsation when the thread has finished
self.progressBar.setRange(0,1)
self.progressBar.setValue(1)
self.resultLabel.setText("Done")
class TaskThread(QtCore.QThread):
taskFinished = QtCore.pyqtSignal()
def __init__(self):
QtCore.QThread.__init__(self)
def __del__(self):
self.wait()
def run(self):
# First, we read the times from the QDateTime elements in the interface
print "Getting times..."
start_datetime_unix, end_datetime_unix = time_converter_to_unix(self.startTime.dateTime(), self.endTime.dateTime())
# Then, we put these values in my_function
print "Executing function..."
dummy_function(self, start_datetime_unix, end_datetime_unix)
# To finish, we execute onFinished.
print "Finishing thread..."
self.taskFinished.emit()
def main():
app = QtGui.QApplication(sys.argv)
window = Tool()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
如果您将它与.ui 一起执行,您会看到,一旦我们单击"Run",进度条将保持等待模式,并出现上面注释的错误。
startTime
和 endTime
属于 GUI,而不属于线程,这就是您收到该错误的原因。
另一方面建议不要从其他线程访问GUI,最好在启动线程前获取值并设置为线程的属性如下图:
class Tool(QtGui.QMainWindow, Ui_MainWindow):
...
def onStart(self):
# Before running the thread, we set the progress bar in waiting mode
self.progressBar.setRange(0,0)
self.resultLabel.setText("In progress...")
self.myLongTask.start_dt = self.startTime.dateTime() # <----
self.myLongTask.end_dt = self.endTime.dateTime() # <----
print "Starting thread..."
self.myLongTask.start()
...
class TaskThread(QtCore.QThread):
...
def run(self):
# First, we read the times from the QDateTime elements in the interface
print "Getting times..."
start_datetime_unix, end_datetime_unix = time_converter_to_unix(self.start_dt, self.end_dt) # <----
# Then, we put these values in my_function
print "Executing function..."
dummy_function(self, start_datetime_unix, end_datetime_unix)
# To finish, we execute onFinished.
print "Finishing thread..."
self.taskFinished.emit()