切换QStackWidget栈时QPushButton自动获取焦点且焦点状态无法取消的问题
Let's break down what's happening here and how to fix it:
The Problem
When you switch back to the first stack from the second one (after clicking the QListWidget), the "First" button gets a blue focus border—even though you never clicked it, and it's not set as checkable. This border won't go away unless you click another focusable element.
Why This Happens
Qt's focus management system automatically assigns focus to a focusable widget when its parent (the stack in this case) becomes visible. Since the "First" button is the first focusable widget in the first stack, it grabs the focus as soon as the stack is switched back to. That blue border is just Qt's default focus indicator, not a selected/check state.
Solutions
1. Redirect Focus to the Central Widget After Switching
The simplest fix is to explicitly give focus to the central widget instead of letting the button take it. Modify your switch_stack method like this:
def switch_stack(self, index_): self.stack_widget.setCurrentIndex(index_) # Shift focus to the central widget to remove it from the button self.central_widget.setFocus()
2. Disable Focus for the Button
If you don't want the button to ever receive focus (which makes sense if it's just a trigger for actions), set its focus policy to NoFocus when creating it:
from PyQt5.QtCore import Qt # Don't forget this import # ... button_1 = QPushButton('First') button_1.setFocusPolicy(Qt.NoFocus) # Add this line button_2 = QPushButton('Second') button_2.setFocusPolicy(Qt.NoFocus) # Optional, if you want the same for this button
3. Clear Focus in the First Stack Explicitly
If you want to keep the button's focus capability but just prevent it from grabbing focus on stack switch, you can clear focus for all widgets in the first stack:
def switch_stack(self, index_): self.stack_widget.setCurrentIndex(index_) if index_ == 0: # Clear focus from all widgets in the first sub-widget for widget in self.first_sub_widget.findChildren(QWidget): widget.clearFocus()
Tested Modified Code (Using Solution 1)
Here's your full code with the first solution applied (plus fixing the commented-out central widget line):
#!/usr/bin/env python3 import sys from PyQt5.QtGui import QGradient from PyQt5.QtWidgets import QGridLayout, QHBoxLayout, QListWidget, QMainWindow, QPushButton, QStackedWidget, QWidget, QApplication class M(QMainWindow): def __init__(self): super().__init__() self.set() def set(self): self.central_widget = QWidget(self) self.central_layout = QGridLayout() self.central_widget.setLayout(self.central_layout) self.setCentralWidget(self.central_widget) # Uncommented for proper widget hierarchy self.first_button = QPushButton('first stack') self.second_button = QPushButton('second stack') self.central_layout.addWidget(self.first_button, 0, 0, 1, 1) self.central_layout.addWidget(self.second_button, 0, 1, 1, 1) self.stack_widget = QStackedWidget() self.central_layout.addWidget(self.stack_widget, 1, 0, 1, 2) # add sub widget for stackwidget self.add_sub_widget_for_stack() # add func for button self.first_button.clicked.connect( lambda checked, x=0: self.switch_stack(x) ) self.second_button.clicked.connect( lambda checked, x=1: self.switch_stack(x) ) def add_sub_widget_for_stack(self): print('add') # add first sub widget self.first_sub_widget = QWidget() self.first_sub_widget.setLayout(QHBoxLayout()) button_1 = QPushButton('First') button_2 = QPushButton('Second') self.first_sub_widget.layout().addWidget(button_1) self.first_sub_widget.layout().addWidget(button_2) self.stack_widget.addWidget(self.first_sub_widget) # add second sub widget self.second_sub_widget = QWidget() self.second_sub_widget.setLayout(QHBoxLayout()) list_ = QListWidget() self.second_sub_widget.layout().addWidget(list_) self.stack_widget.addWidget(self.second_sub_widget) def switch_stack(self, index_): self.stack_widget.setCurrentIndex(index_) # Redirect focus to central widget self.central_widget.setFocus() if __name__ == '__main__': app = QApplication(sys.argv) m = M() m.show() sys.exit(app.exec_())
内容的提问来源于stack exchange,提问作者ssayno

