You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5实现:在不阻塞GUI的情况下从字符串列表中重复更新状态栏

Fixing Non-Blocking Status Bar Message Sequences in PyQt5

Hey there! The issue you're facing is super common when working with GUI frameworks like PyQt5: using time.sleep() blocks the main event loop, freezing your entire interface until the loop finishes. Instead, we can use QTimer to schedule status bar updates without blocking the GUI, plus add logic to interrupt the current sequence if the button is clicked again.

Here's the revised code that does exactly what you want:

import sys
from PyQt5 import QtWidgets, QtCore

class Window(QtWidgets.QMainWindow):
    """Main Window."""
    MSG_ID = 1
    def __init__(self, parent=None):
        """Initializer."""
        super().__init__(parent)
        self.messages = []
        self.current_msg_idx = -1
        self.setWindowTitle('Main Window')
        self.setStatusBar(QtWidgets.QStatusBar())
        self.statusBar().showMessage("My message first time")
        
        # Set up timer for non-blocking status updates
        self.status_timer = QtCore.QTimer(self)
        self.status_timer.setInterval(1000)  # Trigger every 1 second
        self.status_timer.timeout.connect(self._show_next_status_message)
        
        self.button = QtWidgets.QPushButton("Test", self)
        self.button.clicked.connect(self.handleButton)

    def handleButton(self):
        # Stop any ongoing message sequence immediately
        self.status_timer.stop()
        
        # Generate new message list
        self.messages = [f"message_num {msg_id}" for msg_id in range(Window.MSG_ID, Window.MSG_ID+3)]
        Window.MSG_ID +=3
        
        # Start the new sequence
        if self.messages:
            self.current_msg_idx = 0
            # Show first message right away
            self.statusBar().showMessage(self.messages[self.current_msg_idx], 1000)
            self.current_msg_idx +=1
            # Start timer for subsequent messages if needed
            if self.current_msg_idx < len(self.messages):
                self.status_timer.start()
        
        print(self.messages)

    def _show_next_status_message(self):
        if self.current_msg_idx < len(self.messages):
            # Display the next message in the sequence
            self.statusBar().showMessage(self.messages[self.current_msg_idx], 1000)
            self.current_msg_idx +=1
        else:
            # No more messages left - stop timer and reset index
            self.status_timer.stop()
            self.current_msg_idx = -1

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(app.exec_())

Key Changes Explained:

  • Replaced time.sleep() with QTimer: The timer runs in the background and triggers updates without blocking the main event loop, keeping your GUI responsive at all times.
  • Interruptible Sequences: Every time you click the button, we first stop the active timer. This instantly halts the current message sequence and starts the new one.
  • Message Index Tracking: We use self.current_msg_idx to keep track of where we are in the message list. The timer increments this index each time it triggers until all messages are displayed.
  • Immediate First Message: Instead of waiting for the timer to trigger the first message, we show it right when the button is clicked for a smoother user experience.

Now your button will stay clickable even while messages are being displayed, and clicking it again will instantly switch to the new set of messages.

内容的提问来源于stack exchange,提问作者ivan199415

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:28:12