How to correctly add a loading widget while the code run?
-
wrote on 2 Nov 2024, 13:41 last edited by
I've been working on adding a loading widget while the code analyzes an images and disappears when it finishes. However, I'm not sure if what I wrote is the correct way or not, and I'm also not sure if it's causing the code to run slower than before:
def create_loading_widget(self): loading_widget = QWidget(self) loading_widget.setFixedSize(300,200) loading_widget.setWindowTitle("Loading...") loading_widget.setWindowModality(QtCore.Qt.WindowModal) loading_widget.setStyleSheet("background-color:white; border: 2px solid gray; border-radius: 10px") layout = QVBoxLayout(loading_widget) loading_label = QLabel() loading_movie = QMovie("App\image\loading.gif") loading_label.setMovie(loading_movie) layout.addWidget(loading_label, alignment=Qt.AlignCenter) text_label = QLabel("Verificando imagen. Por favor espera...") text_label.setStyleSheet("font: black;") text_label.setAlignment(Qt.AlignCenter) layout.addWidget(text_label, alignment=Qt.AlignCenter) timer = QtCore.QTimer(self) self.timer = timer loading_widget.setLayout(layout) self.loading_movie = loading_movie return loading_widget class AnalysisThread(QThread): analysis_done = pyqtSignal(bool, str) def __init__(self, model_path, image_path, i): super().__init__() self.model_path = model_path self.image_path = image_path self.index = i def run(self): model = models.load_model(self.model_path) def preprocess_image(image_path): image = cv2.imread(image_path) image = cv2.resize(image, (110, 110)) image = image.astype('float32') / 255.0 image = np.expand_dims(image, axis=0) return image img = preprocess_image(self.image_path) pred = model.predict(img) arg_max = np.argmax(pred, axis=1)[0] if self.index == 0: self.analysis_done.emit(arg_max == 0, self.image_path) else: return arg_max def upload_image(self): file_name, _ = QFileDialog.getOpenFileName(None, "Open Image File", "", "Image Files (*.png *.jpg *.bmp)") if not file_name: return current_index = self.ui.stackedWidget.currentIndex() if current_index == 0: self.loading_widget = self.create_loading_widget() self.loading_widget.setVisible(True) self.loading_widget.resize(250, 250) center_point = self.rect().center() - QPoint(self.loading_widget.width() // 2, self.loading_widget.height() // 2) self.loading_widget.move(self.mapToGlobal(center_point)) self.loading_widget.show() self.loading_movie.start() self.analysis_thread = AnalysisThread('model.keras', file_name, 0) self.analysis_thread.analysis_done.connect(self.on_analysis_done) self.analysis_thread.start() elif current_index == 3: ####code not relevant####
It's my first time working on this. I'm using PyQt5 and Python 3.11.8 for this.
-
I've been working on adding a loading widget while the code analyzes an images and disappears when it finishes. However, I'm not sure if what I wrote is the correct way or not, and I'm also not sure if it's causing the code to run slower than before:
def create_loading_widget(self): loading_widget = QWidget(self) loading_widget.setFixedSize(300,200) loading_widget.setWindowTitle("Loading...") loading_widget.setWindowModality(QtCore.Qt.WindowModal) loading_widget.setStyleSheet("background-color:white; border: 2px solid gray; border-radius: 10px") layout = QVBoxLayout(loading_widget) loading_label = QLabel() loading_movie = QMovie("App\image\loading.gif") loading_label.setMovie(loading_movie) layout.addWidget(loading_label, alignment=Qt.AlignCenter) text_label = QLabel("Verificando imagen. Por favor espera...") text_label.setStyleSheet("font: black;") text_label.setAlignment(Qt.AlignCenter) layout.addWidget(text_label, alignment=Qt.AlignCenter) timer = QtCore.QTimer(self) self.timer = timer loading_widget.setLayout(layout) self.loading_movie = loading_movie return loading_widget class AnalysisThread(QThread): analysis_done = pyqtSignal(bool, str) def __init__(self, model_path, image_path, i): super().__init__() self.model_path = model_path self.image_path = image_path self.index = i def run(self): model = models.load_model(self.model_path) def preprocess_image(image_path): image = cv2.imread(image_path) image = cv2.resize(image, (110, 110)) image = image.astype('float32') / 255.0 image = np.expand_dims(image, axis=0) return image img = preprocess_image(self.image_path) pred = model.predict(img) arg_max = np.argmax(pred, axis=1)[0] if self.index == 0: self.analysis_done.emit(arg_max == 0, self.image_path) else: return arg_max def upload_image(self): file_name, _ = QFileDialog.getOpenFileName(None, "Open Image File", "", "Image Files (*.png *.jpg *.bmp)") if not file_name: return current_index = self.ui.stackedWidget.currentIndex() if current_index == 0: self.loading_widget = self.create_loading_widget() self.loading_widget.setVisible(True) self.loading_widget.resize(250, 250) center_point = self.rect().center() - QPoint(self.loading_widget.width() // 2, self.loading_widget.height() // 2) self.loading_widget.move(self.mapToGlobal(center_point)) self.loading_widget.show() self.loading_movie.start() self.analysis_thread = AnalysisThread('model.keras', file_name, 0) self.analysis_thread.analysis_done.connect(self.on_analysis_done) self.analysis_thread.start() elif current_index == 3: ####code not relevant####
It's my first time working on this. I'm using PyQt5 and Python 3.11.8 for this.
wrote on 2 Nov 2024, 14:21 last edited by@Rangerguy128
Looks reasonable to me. If you want to check any timing issue (a) time the thread completion without the UI animation or not in a thread and (b) Qt offers a QProgressDialog for this sort of thing, compare against that. -
@Rangerguy128
Looks reasonable to me. If you want to check any timing issue (a) time the thread completion without the UI animation or not in a thread and (b) Qt offers a QProgressDialog for this sort of thing, compare against that.wrote on 2 Nov 2024, 15:50 last edited by@JonB is it better and faster that way? Also, when Im using pyqtSignal, it's giving me a deprecated warning. Does that cause the code to slow down? I'm currently using PyQt5 and Python 3.11. Not interested in using Python 3.12 at the moment.
1/3