在PyQt中,如何从QThreadPool中的QRunnable run方法调用全局函数?

时间:2015-09-21 14:13:35

标签: multithreading python-2.7 pyqt threadpool

我正在实现一系列线程任务来编写文本报告文件,该报告由不同的部分组成。我有两个常见的函数(写头,写内容),它们是为报表的每个部分执行的,我使用Qthread池/ QRunnable与主GUI应用程序分开运行写入文件进程。只要在run方法中定义了任务,但是当我尝试从每个类的QRunnable的run方法调用一个全局函数时,我的程序崩溃(我得到一个SQLITE数据库错误),这种方法似乎工作正常(对应的)每个报告部分)。

实施例

class Application:

def report_to_file(self,file_path):
    self.report.file_path = val_file_path
    self.long_task = QThreadPool()
    self.long_task.setMaxThreadCount(1)
    start_report = StartReport(val_file_path)
    check_dups = DupStreetDesc()
    third_section = ThirdSection()
    start_report.signals.result.connect(self.process_results)
    check_dups.signals.result.connect(self.process_results)
    third_section.result.connect(self.process_results)
    self.long_task.start(start_report)
    self.long_task.start(check_dups)
    self.long_task.start(third_section)
    self.long_task.waitForDone()

def process_results(self):
    print "the task has been executed successfully!"

def finished(self):
    QMessageBox.information(self.validation_dia,"Message","Task finished")

在另一个模块中,我有我的Runnables并将函数写为全局变量(不包含在类中)

global report_file
global queries

def write_content(query_id, header_id, header_no_content_id, columns_name_id, include_footpaths=True, include_subtitle=False):

    # in here I query the db and write text into the file, this function is used from all the Qrunnable classes 

def write_headers(section_header, include_footpaths=False, include_subtitle=False):

    # here I write other content to the same file ,this function is used from all the Qrunnable classes 


class StartReport(QRunnable):

def __init__(self, file_path):
    super(StartReport,self).__init__()
    self.signals = GeneralSignals()
    self.file_path = file_path
    self.task = "Starting the Report"
    # print "on report start report file is " + str(self.report_file)
    self.org_name = org_name
    self.user = user
    self.report_title = "Roadnet Validation Report"
    global progress_win
    self.progress_win = progress_win
    self.progress_win.setLabelText("Report Initialisation")
    self.progress_win.show()

def run(self):
    if self.file_path is None:
        return
    else:
        global report_file
        # create the file and prints the header
        report_file = open(self.file_path, 'wb')
        report_file.write(str(self.report_title) + ' for {0} \n'.format(self.org_name))
        report_file.write('Created on : {0} at {1} By : {2} \n'.format(datetime.today().strftime("%d/%m/%Y"),
                                                                            datetime.now().strftime("%H:%M"),
                                                                            str(self.user)))
        report_file.write(
            "------------------------------------------------------------------------------------------ \n \n \n \n")
        self.signals.result.emit(self.task)

在上面的情况下,函数运行,因为一切都在run方法中发生

在下面的情况下,进入全局功能时进程崩溃

class DupStreetDesc(QRunnable):
    """
    duplicate street description report section creation
    :return: void if the report is to text
            list[string] if the report is to screen
    """
    def __init__(self):
        # print(StartReport.report_file)
        self.signals = GeneralSignals()
        self.task = "Checking duplicate street descriptions..."
        super(DupStreetDesc,self).__init__()
        # report_file
        # self.report_file = report_file
        global progress_win
        self.progress_win = progress_win
        self.progress_win.setLabelText("Checking duplicate street descriptions...")
    def run(self):
        global report_file
        global queries
        print "I run " + " report file is " + str(report_file)
        print " these are queries " + str(queries)
        print " this is the connection " + str(db)
        if report_file is None:
            items_list = write_content(0, 0, 0, 0)
            self.progress_win.setValue(1)
            return items_list
        else:
            # here is where I call the global functions
            write_headers(0)
            write_content(0, 0, 0, 0)
            progress_win.setValue(1)
        self.signals.result.emit(self.task)

class GeneralSignals(QObject):
    result = pyqtSignal(str)

我是Pyqt中这个Qthread池类的新手,在我看到的所有示例中,到目前为止,函数都是在run方法中运行而不调用任何外部函数。我不知道是否有可能,有人能告诉我正确的方法吗?

1 个答案:

答案 0 :(得分:0)

因此,可以从QRunnables调用全局(模块)函数。我的代码中的问题是我试图从QRunnables的run方法更新进度条,这就是导致代码中断的原因。