带有加载栏的 QDialog 未按时显示
QDialog with loading bar is not displaying on time
我有一个应用程序,它有一个 QMainWindow 和一个处理所有事件的后端控制器。来自 QMainWindow 的这些事件之一会发出一个信号,在控制器中调用此方法。
def add_files(self, file_paths):
try:
for file_path in file_paths:
file_name = os.path.basename(file_path)
"Some other working code here"
self.silent_save()
self.main_widget.update_file_display()
except Exception as e:
self.logger.error()
我还有一个 QDialog class,它的加载栏看起来像这样。
class FileLoadingScreen(QDialog, Ui_FileLoadingScreen):
def __init__(self, loading_gif_path, parent=None):
super(FileLoadingScreen, self).__init__(parent)
self.setupUi(self)
self.setWindowModality(QtCore.Qt.ApplicationModal)
# Setting up the loading.gif animation.
self.movie = QMovie(loading_gif_path)
self.loading_label.setMovie(self.movie)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
def start_animation(self, width, height, geometry):
self.resize(width, height)
self.setGeometry(geometry)
self.movie.start()
self.show()
def stop_animation(self):
self.movie.stop()
self.close()
我已经尝试了多种调用 start_animation 方法的方法。使用另一个线程(定时器问题)调用 start_animation,从控制器方法调用它,从 QMainWindow 内部调用它,使用从 QMainWindow 发射到控制器的信号调用它。由于显而易见的原因,thread 方法根本不起作用,但所有其他方法产生相同的结果,加载对话框显示,但仅在 add_files 方法完成执行之后。我知道谁拥有主执行线程的执行控制权是个问题,但我没有主意。
首先,我只想对所有发帖的人说声谢谢,这是一次非常需要的完整性检查。下面是我的解决方案,但我不建议这样做,除非你像我一样受到预算和时间的限制。理想情况下,来自我的控制器 add_files 方法的代码应该放在一个单独的助手 class 运行 中,在它自己的线程上,并且只向控制器发信号。但是,我的解决方案效果很好。
@pyqtSlot(list)
def add_files(self, file_paths):
self.call_loading()
t2 = Thread(target=self.start_file_copy, args=[file_paths])
t2.start()
def start_file_copy(self, file_paths):
try:
for file_path in file_paths:
file_name = os.path.basename(file_path)
"Some worker code here"
self.silent_save()
self.main_widget.update_file_display()
self.done_loading.emit()
except Exception as e:
self.logger.error()
def call_loading(self):
self.file_loading_screen.start_animation(self.main_screen.width(), self.main_screen.height(), self.main_screen.geometry())
@pyqtSlot()
def close_loading(self):
self.file_loading_screen.stop_animation()
我有一个应用程序,它有一个 QMainWindow 和一个处理所有事件的后端控制器。来自 QMainWindow 的这些事件之一会发出一个信号,在控制器中调用此方法。
def add_files(self, file_paths):
try:
for file_path in file_paths:
file_name = os.path.basename(file_path)
"Some other working code here"
self.silent_save()
self.main_widget.update_file_display()
except Exception as e:
self.logger.error()
我还有一个 QDialog class,它的加载栏看起来像这样。
class FileLoadingScreen(QDialog, Ui_FileLoadingScreen):
def __init__(self, loading_gif_path, parent=None):
super(FileLoadingScreen, self).__init__(parent)
self.setupUi(self)
self.setWindowModality(QtCore.Qt.ApplicationModal)
# Setting up the loading.gif animation.
self.movie = QMovie(loading_gif_path)
self.loading_label.setMovie(self.movie)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
def start_animation(self, width, height, geometry):
self.resize(width, height)
self.setGeometry(geometry)
self.movie.start()
self.show()
def stop_animation(self):
self.movie.stop()
self.close()
我已经尝试了多种调用 start_animation 方法的方法。使用另一个线程(定时器问题)调用 start_animation,从控制器方法调用它,从 QMainWindow 内部调用它,使用从 QMainWindow 发射到控制器的信号调用它。由于显而易见的原因,thread 方法根本不起作用,但所有其他方法产生相同的结果,加载对话框显示,但仅在 add_files 方法完成执行之后。我知道谁拥有主执行线程的执行控制权是个问题,但我没有主意。
首先,我只想对所有发帖的人说声谢谢,这是一次非常需要的完整性检查。下面是我的解决方案,但我不建议这样做,除非你像我一样受到预算和时间的限制。理想情况下,来自我的控制器 add_files 方法的代码应该放在一个单独的助手 class 运行 中,在它自己的线程上,并且只向控制器发信号。但是,我的解决方案效果很好。
@pyqtSlot(list)
def add_files(self, file_paths):
self.call_loading()
t2 = Thread(target=self.start_file_copy, args=[file_paths])
t2.start()
def start_file_copy(self, file_paths):
try:
for file_path in file_paths:
file_name = os.path.basename(file_path)
"Some worker code here"
self.silent_save()
self.main_widget.update_file_display()
self.done_loading.emit()
except Exception as e:
self.logger.error()
def call_loading(self):
self.file_loading_screen.start_animation(self.main_screen.width(), self.main_screen.height(), self.main_screen.geometry())
@pyqtSlot()
def close_loading(self):
self.file_loading_screen.stop_animation()