PyQt5主窗口打开的子窗口控件无法点击问题求助
问题:PyQt5子窗口控件无法点击,主窗口关闭后恢复正常
我用PyQt5开发桌面应用,点击主窗口按钮打开QWidget子窗口后,窗口能正常显示,但所有按钮、ComboBox控件都无法点击;关闭主窗口后,子窗口仍保持打开,且控件恢复可点击状态。以下是子窗口代码和主窗口调用方法,求解决。
子窗口代码
from PyQt5 import QtCore, QtGui, QtWidgets class Interaction: def __init__(self): self.wanted = False self.interaction_type = None self.chain = None self.res_type = None self.res_number = None self.atom_name = None def set_interaction_type(self, interaction_type): self.interaction_type = interaction_type def set_chain(self, chain): self.chain = chain def set_res_type(self, res_type): self.res_type = res_type def set_res_number(self, res_number): self.res_number = res_number def set_atom_name(self, atom_name): self.atom_name = atom_name def set_wanted(self, wanted): if isinstance(wanted, bool): self.wanted = wanted class Ui_Form(QtWidgets.QWidget): def __init__(self, list_of_available_items, parent): super().__init__() self.interactions_type = ['R', 'H', 'vdW'] self.items = list_of_available_items self.filter = Interaction() self.setupUi() self.setFocusPolicy(QtCore.Qt.StrongFocus) # self.show() def setupUi(self): self.setObjectName("Form") self.resize(542, 128) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(sizePolicy) self.gridLayout = QtWidgets.QGridLayout(self) self.gridLayout.setObjectName("gridLayout") self.interactionTypeLabel = QtWidgets.QLabel(self) self.interactionTypeLabel.setFocusPolicy(QtCore.Qt.NoFocus) self.interactionTypeLabel.setObjectName("interactionTypeLabel") self.gridLayout.addWidget(self.interactionTypeLabel, 0, 0, 1, 2) self.interactionTypeComboBox = QtWidgets.QComboBox(self) self.interactionTypeComboBox.setObjectName("interactionTypeComboBox") self.gridLayout.addWidget(self.interactionTypeComboBox, 0, 2, 1, 2) self.wantedRadioButton = QtWidgets.QRadioButton(self) self.wantedRadioButton.setObjectName("wantedRadioButton") self.gridLayout.addWidget(self.wantedRadioButton, 0, 4, 1, 1) self.unwantedRadioButton = QtWidgets.QRadioButton(self) self.unwantedRadioButton.setObjectName("unwantedRadioButton") self.gridLayout.addWidget(self.unwantedRadioButton, 0, 5, 1, 1) self.interactionChainLabel = QtWidgets.QLabel(self) self.interactionChainLabel.setObjectName("interactionChainLabel") self.gridLayout.addWidget(self.interactionChainLabel, 1, 0, 1, 1) self.interactionResTypeLabel = QtWidgets.QLabel(self) self.interactionResTypeLabel.setObjectName("interactionResTypeLabel") self.gridLayout.addWidget(self.interactionResTypeLabel, 1, 1, 1, 2) self.interactionResNLabel = QtWidgets.QLabel(self) self.interactionResNLabel.setObjectName("interactionResNLabel") self.gridLayout.addWidget(self.interactionResNLabel, 1, 3, 1, 1) self.interactionAtomNameLabel = QtWidgets.QLabel(self) self.interactionAtomNameLabel.setObjectName("interactionAtomNameLabel") self.gridLayout.addWidget(self.interactionAtomNameLabel, 1, 4, 1, 2) self.interactionChainComboBox = QtWidgets.QComboBox(self) self.interactionChainComboBox.setObjectName("interactionChainComboBox") self.gridLayout.addWidget(self.interactionChainComboBox, 2, 0, 1, 1) self.interactionResTypeComboBox = QtWidgets.QComboBox(self) self.interactionResTypeComboBox.setObjectName("interactionResTypeComboBox") self.gridLayout.addWidget(self.interactionResTypeComboBox, 2, 1, 1, 2) self.interactionResNComboBox = QtWidgets.QComboBox(self) self.interactionResNComboBox.setObjectName("interactionResNComboBox") self.gridLayout.addWidget(self.interactionResNComboBox, 2, 3, 1, 1) self.interactionAtomNameComboBox = QtWidgets.QComboBox(self) self.interactionAtomNameComboBox.setObjectName("interactionAtomNameComboBox") self.gridLayout.addWidget(self.interactionAtomNameComboBox, 2, 4, 1, 2) self.interactionDialogButtonBox = QtWidgets.QDialogButtonBox(self) self.interactionDialogButtonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) self.interactionDialogButtonBox.setObjectName("interactionDialogButtonBox") self.gridLayout.addWidget(self.interactionDialogButtonBox, 3, 4, 1, 2) self.retranslateUi() QtCore.QMetaObject.connectSlotsByName(self) self.interactionTypeComboBox.currentIndexChanged.connect(self.set_interaction_type) self.wantedRadioButton.clicked.connect(self.set_filter_wanted) self.unwantedRadioButton.clicked.connect(self.set_filter_unwanted) # DEFAULTS self.populate_interactions_type() self.wantedRadioButton.click() # CLASS METHODS def populate_interactions_type(self): for interaction in self.interactions_type: self.interactionTypeComboBox.addItem(interaction) def set_interaction_type(self): self.filter.set_interaction_type(self.interactionTypeComboBox.currentText()) def set_filter_wanted(self): if self.wantedRadioButton.isChecked(): self.filter.set_wanted(True) else: self.filter.set_wanted(False) def set_filter_unwanted(self): if self.unwantedRadioButton.isChecked(): self.filter.set_wanted(False) else: self.filter.set_wanted(True) def get_interaction_obj(self): return self.filter def retranslateUi(self): self.interactionTypeLabel.setText("Select interaction type:") self.wantedRadioButton.setText("Enable") self.unwantedRadioButton.setText("Disable") self.interactionChainLabel.setText("Chain:") self.interactionResTypeLabel.setText("Res Type:") self.interactionResNLabel.setText("Res #:") self.interactionAtomNameLabel.setText("Atom Name:") if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) ui = Ui_Form(list(), QtWidgets.QMainWindow) ui.show() sys.exit(app.exec_())
主窗口调用代码
def add_interaction(self): self.interaction_ui = Ui_Form(list(), self) self.interaction_ui.show()
解决方案
问题根源:创建子窗口时未将父窗口参数传递给QWidget构造函数,导致子窗口未正确关联主窗口作为父控件,引发两个问题:
- 子窗口无法获取正确的焦点和事件处理权限,控件无法响应点击
- 主窗口关闭时,子窗口因无父控件关联,不会被自动销毁,独立存在
修复步骤:
修改子窗口__init__方法,将parent参数传递给父类构造函数:
原代码:def __init__(self, list_of_available_items, parent): super().__init__()修改为:
def __init__(self, list_of_available_items, parent): super().__init__(parent)额外优化:
若希望子窗口为模态窗口(打开后主窗口无法操作),可在调用show()前添加self.setWindowModality(QtCore.Qt.ApplicationModal),符合常规弹窗交互逻辑。
内容的提问来源于stack exchange,提问作者NiccoloB
相关产品推荐
相关产品推荐

