自定义非模态对话框类无法显示及QDialogButtonBox连接咨询
解答你的PyQt5自定义非模态对话框问题
Let's fix your two issues step by step:
1. 对话框无法显示内容的原因
你已经创建了QVBoxLayout并添加了QLabel和按钮框,但没有把这个布局绑定到对话框实例上。PyQt的布局必须通过setLayout()方法关联到窗口/对话框,否则布局内的控件不会被渲染到界面中。
在ModelessDialog的__init__方法末尾添加这行关键代码:
self.setLayout(layout)
2. QDialogButtonBox的信号连接问题
你的Cancel按钮连接存在逻辑错误:ModelessDialog.reject是类的静态方法,而不是当前对话框实例的方法,点击按钮时无法正确触发对话框关闭的逻辑。需要改为绑定到当前实例的reject()方法:
cancelBtn.clicked.connect(self.reject)
另外补充个小技巧:QDialogButtonBox本身提供了accepted、rejected这类更简洁的信号,如果你不想手动获取单个按钮,也可以直接绑定这些信号,比如:
buttonBox.rejected.connect(self.reject) buttonBox.clicked.connect(lambda btn: self.apply() if btn == applyBtn else None)
不过你手动获取按钮的方式完全没问题,只要修正实例方法的调用即可。
修改后的完整代码
from PyQt5.QtWidgets import * class Window(QWidget): def __init__(self): QWidget.__init__(self) cb = QCheckBox('Check me anytime', self) cb.move(20, 20) button = QPushButton('Open Dialog', self) button.move(20,50) self.resize(120, 90) button.clicked.connect(self.showDialog) def showDialog(self): self.dialog = ModelessDialog(self) self.dialog.show() class ModelessDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) layout = QVBoxLayout() lbl = QLabel("please show something ...") buttonBox = QDialogButtonBox( QDialogButtonBox.Cancel|QDialogButtonBox.Apply) layout.addWidget(lbl) layout.addWidget(buttonBox) # 新增:将布局绑定到对话框 self.setLayout(layout) self.resize(300, 200) applyBtn = buttonBox.button(QDialogButtonBox.Apply) applyBtn.clicked.connect(self.apply) cancelBtn = buttonBox.button(QDialogButtonBox.Cancel) # 修正:绑定到实例的reject方法 cancelBtn.clicked.connect(self.reject) self.setWindowTitle("Modeless") def apply(self): print("ModelessDialog: in apply") if __name__ == '__main__': import sys app = QApplication(sys.argv) win = Window() win.show() sys.exit(app.exec_())
现在运行代码,对话框会正常显示QLabel和按钮组,点击Cancel会关闭对话框,点击Apply会打印对应的调试信息。
内容的提问来源于stack exchange,提问作者SixHearts
相关产品推荐
相关产品推荐

