【问题标题】:How can I use a QDateTime inside a Thread?如何在线程中使用 QDateTime?
【发布时间】:2018-11-17 03:06:15
【问题描述】:

我有一个线程需要执行繁重的功能。

首先,我有一个函数,它从 GUI 获取两个 QDateTime 值并将它们转换为 UNIX 时间戳。其次,“重”函数使用这些值来执行任务。

(function_task, time_converter_to_unix) 两个函数都不属于任何类,所以据我所知,我可以在线程中使用它们。

但不是参数,因为我无法访问 QDateTime 值。

错误:AttributeError:“TaskThread”对象没有属性“startTime”

如何访问QDateTime 并从线程中读取内容?谢谢。

编辑: 完整代码。您还可以在以下链接中找到指向 GUI 的链接: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一起执行,你会看到,一旦我们点击“运行”,进度条停留在等待模式,出现上面注释的错误。

【问题讨论】:

  • 错误信息很清楚:你的startTime 类中没有startTime 属性。与那里没有 endTime 属性的方式相同。在您发布的简短代码片段中,没有设置这些属性并给出错误消息的地方,您也没有在其他地方设置它们。你打算在哪里为你的类设置这些属性?
  • 对不起。我刚刚写了完整的代码。如您所见,QDateTime 对象(startTime 和 endTime)来自 .ui。
  • 好的...所以,您的Tool 类确实或至少应该具有startTimeendTime 属性,因为它是Ui_MainWindow 的子类。但是,您的 TaskThread 是一个完全不同的类,它没有这些属性。但是您试图在其run 方法中使用这些属性,就好像它们属于TaskThread 类一样。因此,您观察到的错误。
  • 如果您绝对需要从TaskThread's run 方法访问startTimeendTime,您需要将这些属性从Tool 复制到TaskThread 类(将它们传递为例如TaskThread's 构造函数参数)或简单地将整个Tool 类的链接复制到TaskThread 中(也将其作为构造函数参数传递)。
  • 您能否提供一个代码,以便我更好地解释答案?我真的很感激。

标签: python multithreading pyqt pyqt4 qthread


【解决方案1】:

startTimeendTime 属于 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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多