QFileDialog窗口中没有可见的文件

6

我正在使用pyqt编写简单的代码。

在代码中,我调用了一个QFileDialog,但是当我使用静态函数调用时,一切都正常工作。但是当我使用正常的方法即使用dialog.exec_()时,我看不到文件对话框窗口中的任何文件。

只有在键入文件的完整路径后,我才能在文件对话框窗口中看到该文件。 请注意,这个问题只会在调用FileDialoghandler函数时出现。如果我不这样做,无论如何调用QFileDialog都可以正常工作。 而且,这个问题只发生在Linux上,在Windows7上一切正常。 我想知道这是PyQt的 bug 还是我漏掉了什么?

代码如下:

import sys
from PyQt4.QtCore import Qt
from PyQt4.QtGui import *
from PyQt4.QtCore import QAbstractFileEngine
from PyQt4.QtCore import QAbstractFileEngineHandler
from PyQt4.QtCore import QFSFileEngine

class FileDialogHandler(QAbstractFileEngineHandler):
    def create(self,filename):
        if str(filename).startswith(':'):
            return None # Will be handled by Qt as a resource file
        print("Create QFSFileEngine for {0}".format(filename))  
        return QFSFileEngine(filename)

class Example(QMainWindow):

    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):      

        self.textEdit = QTextEdit()
        self.setCentralWidget(self.textEdit)
        self.statusBar()

        openFile = QAction(QIcon('open.png'), 'Open', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open new File')
        openFile.triggered.connect(self.showDialog)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openFile)       

        self.setGeometry(300, 300, 350, 300)
        self.setWindowTitle('File dialog')
        self.show()

    def showDialog(self):
        handler = FileDialogHandler()
        #using QFileDialog.getOpenFileName works fine
        fname = QFileDialog.getOpenFileName(None, 'Open file', '/home','All files (*.*)')
        #dialog = QFileDialog()
        #dialog.setOption(QFileDialog.DontUseNativeDialog,False)
        #if dialog.exec_():
            #fname = dialog.selectedFiles()
        #else:
            #fname = None
        f = open(fname, 'r')        
        with f:        
            data = f.read()
            self.textEdit.setText(data) 

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

确认在Linux上这并不起作用。然而,相同的代码使用PySide可以正常工作- 因此可能是PyQt的错误。尽管如此,我建议你将其报告到PyQt邮件列表以获取明确的答案。 - ekhumoro
小心使用 f=open(fname,'r'); with f。不仅可以将这两个语句放在一个 with open(fname, 'r') as f 中,而且最重要的是要将其封装在 try... except IOError 中,以防止用户按下“取消”(即当 fname="" 时)导致程序崩溃。 - Pierre GM
在我的Win7上它不起作用。但是使用PySide可以正常工作。 - Avaris
@ekkhumoro:感谢确认,我正在迁移到 PySide。 - user1637766
@user1637766,Qt4已经不再被积极开发或维护。您可以考虑迁移到Qt5甚至Qt6。 - bfris
显示剩余2条评论
2个回答

11

我不久前也遇到了使用getOpenFilename时类似的问题。对我而言,解决方案是将后端从本地更改为Qt自己实现的对话框。这可以通过扩展的调用语法来实现,其形式如下:

filename = QtGui.QFileDialog.getOpenFileName(self,
                                             'Open file',
                                             '/home',
                                             'All files (*.*)',
                                             options=QtGui.QFileDialog.DontUseNativeDialog)

自从我更改了这个调用语法之后,再也没有出现过任何问题。


1
哇,你刚刚在这里回答了我的问题 https://stackoverflow.com/questions/58122168/in-pyqt5-getopenfilename-does-not-result-in-a-file-selection-pop-up我会在那里链接这个问题,让更多的人知道。 - zwep

0

在Windows 10中,通过命令提示符运行代码而不使用任何IDE时遇到了相同的问题。包括options=QtGui.QFileDialog.DontUseNativeDialog确实解决了这个问题(使用Python 3.10)。例如:

self.path_open, _ = QFileDialog.getOpenFileName(self, "Open file", "", "e-documents (*.docx *.pdf)",
                                                options=QFileDialog.DontUseNativeDialog)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接