python - 在 PyQt5(Python)中将小部件(QCheckBox)添加到 QFileDialog 不起作用
问题描述
我想将 QCheckBox 添加到 QFileDialog。我想使用静态方法 QFileDialog.getSaveFileName() 来显示对话框。
我发现了几个类似的问题,都在 c++ 中:
- 如何在 QT3 的 QFileDialog 窗口中添加复选框?
- 在 QFileDialog 中添加一个小部件
- https://www.qtcentre.org/threads/42858-Creating-a-Custom-FileOpen-Dialog
- https://forum.qt.io/topic/103964/add-checkbox-to-qfiledialog/7
我尽力将这些讨论翻译成 python,但还没有找到解决方案。我的代码运行,但复选框没有显示,即使我使用 QFileDialog.DontUseNativeDialog。
这就是我继承 QFileDialog 的方式:
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtWidgets import QCheckBox
class ChkBxFileDialog(QFileDialog):
def __init__(self, chkBxTitle=""):
super().__init__()
self.setOption(QFileDialog.DontUseNativeDialog)
chkBx = QCheckBox(chkBxTitle)
self.layout().addWidget(chkBx)
#end __init__
#end ChkBxFileDialog
我以两种方式运行它。
选项 1(带有额外的 QFileDialog.DontUseNativeDialog):
import sys
from PyQt5.QtWidgets import QApplication
if __name__ == "__main__":
app = QApplication(sys.argv)
fileDialog = ChkBxFileDialog(chkBxTitle="Chkbx")
fileName = fileDialog.getSaveFileName(filter='*.txt', initialFilter='*.txt',
options=QFileDialog.DontUseNativeDialog)[0]
sys.exit(app.exec_())
选项 2(没有额外的 QFileDialog.DontUseNativeDialog):
import sys
from PyQt5.QtWidgets import QApplication
if __name__ == "__main__":
app = QApplication(sys.argv)
fileDialog = ChkBxFileDialog(chkBxTitle="Chkbx")
fileName = fileDialog.getSaveFileName(filter='*.txt', initialFilter='*.txt')[0]
sys.exit(app.exec_())
该复选框不会与任一选项一起显示。选项 1 使用不同的窗口样式。选项 2 显示了典型的 PyQt QFileDialog。
有谁知道我错过了什么?
解决方案
问题是 getSaveFileName 是一个静态方法,因此它们不从 ChkBxFileDialog 继承,因此没有自定义行为。
有2个选项:
不要使用 getSaveFileName 而是直接使用 QFileDialog 实现逻辑:
import sys from PyQt5.QtWidgets import QApplication, QCheckBox, QDialog, QFileDialog class ChkBxFileDialog(QFileDialog): def __init__(self, chkBxTitle="", filter="*.txt"): super().__init__(filter=filter) self.setSupportedSchemes(["file"]) self.setOption(QFileDialog.DontUseNativeDialog) self.setAcceptMode(QFileDialog.AcceptSave) self.selectNameFilter("*.txt") chkBx = QCheckBox(chkBxTitle) self.layout().addWidget(chkBx) def main(): app = QApplication(sys.argv) dialog = ChkBxFileDialog() if dialog.exec_() == QDialog.Accepted: filename = dialog.selectedUrls()[0].toLocalFile() print(filename) if __name__ == "__main__": main()
使用一些技巧来获取 QFileDialog 实例,例如获取所有 topLevels 并验证它是否是 QFileDialog。
import sys from functools import partial from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QApplication, QCheckBox, QDialog, QFileDialog def add_checkbox(chkBxTitle): for tl in QApplication.topLevelWidgets(): if isinstance(tl, QFileDialog): tl.setOption(QFileDialog.DontUseNativeDialog) chkBx = QCheckBox(chkBxTitle) tl.layout().addWidget(chkBx) def main(): app = QApplication(sys.argv) QTimer.singleShot(1000, partial(add_checkbox, "")) fileName, _ = QFileDialog.getSaveFileName( filter="*.txt", initialFilter="*.txt", options=QFileDialog.DontUseNativeDialog ) if __name__ == "__main__": main()
推荐阅读
- mysql - 为什么在我的嵌套集层次结构中我的 HAVING 子句没有正确比较 int 值?
- javascript - 如何在 WSO2 中将 JSON 作为字符串发送?
- vue.js - 如何在 Nuxt.js 中使用 Mixpanel
- xslt - 是否嵌套 Xpath 谓词
- sql - 我要找还没有合作过电影的导演和演员
- react-native - 比较 React Native 中的两个状态变量
- url - 如何将我的服务器域设置为 www.foobar.com 而不是 foobar.com?
- oauth-2.0 - Salesforce 身份以保护外部 REST 端点
- docker-compose - SNS localstack 给出 403 Client Error: Forbidden for url error while publishing message
- javascript - Javascript 闭包和变量