Python 意外的执行顺序-GUI仅在下载完成后更新

Python 意外的执行顺序-GUI仅在下载完成后更新,python,qt,user-interface,pyside,Python,Qt,User Interface,Pyside,我用pyside开发了一个GUI,它在按下按钮后执行命令。调用的函数中的第一个命令将在文本终端中将状态更新为“正在下载…”。第二个命令将启动实际下载(通过Pandas和cx_Oracle执行的SQL查询) 奇怪的是,文本_终端只有在下载完成后才更新。有什么建议可以导致这种情况吗 ui.text_terminal.append("Downloading....") self.df = dbrs.retrieve(date) 在处理重画事件之前,GUI不会更新。这些操作通常在事件循环开始时完成。如

我用pyside开发了一个GUI,它在按下按钮后执行命令。调用的函数中的第一个命令将在文本终端中将状态更新为“正在下载…”。第二个命令将启动实际下载(通过Pandas和cx_Oracle执行的SQL查询)

奇怪的是,文本_终端只有在下载完成后才更新。有什么建议可以导致这种情况吗

ui.text_terminal.append("Downloading....")
self.df = dbrs.retrieve(date)

在处理重画事件之前,GUI不会更新。这些操作通常在事件循环开始时完成。如果您的应用程序正忙于运行python代码,则在该代码完成运行之前,它不会进入事件循环的下一个周期。正确的方法是将长时间运行的操作推送到一个单独的线程中,这样它就不会占用主GUI线程,并且事件循环可以继续处理GUI更新事件,但是有一些方法可以绕过它

您可以简单地告诉应用程序处理重绘事件

ui.text_terminal.append("Downloading....")
QtGui.QApplication.processEvents()
self.df = dbrs.retrieve(date)
检索
函数之前调用此函数,它将强制更新GUI

另一种方法是简单地将操作推到下一个事件循环周期,这意味着在它执行之前至少会有1次重画。您可以通过单发
QTimer
完成此操作。这会打断函数的流程,因此只有在下载后不做任何其他事情时才有意义

def do_retrieve(self, date):
    self.df = dbrs.retrieve(date)

ui.text_terminal.append("Downloading....")
QtCore.QTimer.singleShot(1, lambda: self.do_retrieve(date))

在处理重画事件之前,GUI不会更新。这些操作通常在事件循环开始时完成。如果您的应用程序正忙于运行python代码,则在该代码完成运行之前,它不会进入事件循环的下一个周期。正确的方法是将长时间运行的操作推送到一个单独的线程中,这样它就不会占用主GUI线程,并且事件循环可以继续处理GUI更新事件,但是有一些方法可以绕过它

您可以简单地告诉应用程序处理重绘事件

ui.text_terminal.append("Downloading....")
QtGui.QApplication.processEvents()
self.df = dbrs.retrieve(date)
检索
函数之前调用此函数,它将强制更新GUI

另一种方法是简单地将操作推到下一个事件循环周期,这意味着在它执行之前至少会有1次重画。您可以通过单发
QTimer
完成此操作。这会打断函数的流程,因此只有在下载后不做任何其他事情时才有意义

def do_retrieve(self, date):
    self.df = dbrs.retrieve(date)

ui.text_terminal.append("Downloading....")
QtCore.QTimer.singleShot(1, lambda: self.do_retrieve(date))

GUI代码通常有一个事件循环运行以处理更新。如何确保“循环”在执行其他任务之前已完成最新任务?可能发生的情况是,在下载时事件循环未运行。如果希望GUI执行任何操作,则长时间运行的任务需要由单独的线程完成。GUI代码通常有一个事件循环运行以处理更新。如何确保“循环”在执行其他任务之前已完成最新任务?可能发生的情况是,在下载时事件循环未运行。如果你想让GUI做任何事情,那么长时间运行的任务需要由一个单独的线程来完成。“因此,只有在下载后不做任何其他事情时,它才真正有意义。”-可以将“其他任何事情”移到do_retrieve()中。这里的主要问题是使用同步API进行下载,但正确的解决方案是异步启动检索,并在检索完成时调用回调。下载仍然会阻塞UI,只是过了一会儿。“因此,只有在下载后不做任何其他事情时,它才真正有意义。”-可以将“其他任何事情”移到do_retrieve()中。这里的主要问题是使用同步API进行下载,但正确的解决方案是异步启动检索,并在完成检索后调用回调。