将小部件(QCheckBox)添加到PyQt5(Python)中的QFileDialog不工作

2024-09-30 20:20:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在QFileDialog中添加一个QCheckBox。我想使用静态方法QFileDialog.getSaveFileName()来显示对话框

我发现了几个类似的问题,都是用c++编写的:

  1. How to add checkbox to QFileDialog window in QT3?
  2. Adding a widget in QFileDialog
  3. https://www.qtcentre.org/threads/42858-Creating-a-Custom-FileOpen-Dialog
  4. 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.DonTusEnableDialog):

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

有人知道我错过了什么吗


Tags: fromimporttxtapp选项syspyqt5qapplication
2条回答

I would like to use the static method QFileDialog.getSaveFileName() to show the dialog

那是不可能的。C++代码中定义的静态方法对派生类一无所知,因此它将创建基类的实例,它不包含您的修改。您必须显式地实例化派生类,在实例上调用exec(),检查返回代码,并可能调用其selectedFiles()方法以查看选择了哪些文件

问题是getSaveFileName是一个静态方法,因此它们不会从ChkBxFileDialog继承,因此没有自定义行为

有两种选择:

  • 不要使用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实例,例如获取所有顶层并验证它是否是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()
    

相关问题 更多 >