将小部件 (QCheckBox) 添加到 PyQt5 中的 QFileDialog (Python) 不起作用
Add widget (QCheckBox) to QFileDialog in PyQt5 (Python) not working
我想将 QCheckBox 添加到 QFileDialog。我想使用静态方法 QFileDialog.getSaveFileName() 来显示对话框。
我发现了几个类似的问题,都是c++的:
- Adding a widget in QFileDialog
- https://www.qtcentre.org/threads/42858-Creating-a-Custom-FileOpen-Dialog
- https://forum.qt.io/topic/103964/add-checkbox-to-qfiledialog/7
我已尽力将这些讨论翻译成 python,但尚未找到解决方案。我的代码 运行s,但复选框没有显示,即使我使用 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 使用不同的 window 样式。选项 2 显示了典型的 PyQt QFileDialog。
有人知道我错过了什么吗?
I would like to use the static method QFileDialog.getSaveFileName()
to show the dialog
这不可能。 C++ 代码中定义的静态方法对您的派生 class 一无所知,因此它将创建基 class 的实例,其中不包含您的修改。您必须显式实例化派生的 class,在实例上调用 exec()
,检查 return 代码并可能调用其 selectedFiles()
方法以查看选择了哪些文件。
问题是 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()
我想将 QCheckBox 添加到 QFileDialog。我想使用静态方法 QFileDialog.getSaveFileName() 来显示对话框。
我发现了几个类似的问题,都是c++的:
- Adding a widget in QFileDialog
- https://www.qtcentre.org/threads/42858-Creating-a-Custom-FileOpen-Dialog
- https://forum.qt.io/topic/103964/add-checkbox-to-qfiledialog/7
我已尽力将这些讨论翻译成 python,但尚未找到解决方案。我的代码 运行s,但复选框没有显示,即使我使用 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 使用不同的 window 样式。选项 2 显示了典型的 PyQt QFileDialog。
有人知道我错过了什么吗?
I would like to use the static method
QFileDialog.getSaveFileName()
to show the dialog
这不可能。 C++ 代码中定义的静态方法对您的派生 class 一无所知,因此它将创建基 class 的实例,其中不包含您的修改。您必须显式实例化派生的 class,在实例上调用 exec()
,检查 return 代码并可能调用其 selectedFiles()
方法以查看选择了哪些文件。
问题是 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()