2012-11-19 92 views
3

我使用自定义QFileDialog,因为我想选择多个目录。 但exec_函数是非常缓慢的,我不明白为什么。我正在使用最新版本的PyQt。PyQt QFileDialog exec_很慢

代码段:

from PyQt4 import QtGui, QtCore, QtNetwork, uic 

class MainWindow(QtGui.QMainWindow): 
    def __init__(self, parent=None): 
     super(MainWindow, self).__init__(parent) 
     uic.loadUi('gui.ui', self)    
     self.connect(self.multiPackerAddDirsBtn, 
        QtCore.SIGNAL('clicked()'), self.multiPackerAddDirs) 

    def multiPackerAddDirs(self): 
     dialog = QtGui.QFileDialog(self) 
     dialog.setFileMode(QtGui.QFileDialog.Directory) 
     dialog.setOption(QtGui.QFileDialog.ShowDirsOnly, True) 
     dialogTreeView = dialog.findChild(QtGui.QTreeView) 
     dialogTreeView.setSelectionMode(
      QtGui.QAbstractItemView.ExtendedSelection) 
     if dialog.exec_(): 
      for dirname in dialog.selectedFiles(): 
       self.multiPackerDirList.addItem(str(dirname)) 
       print(str(dirname)) 

if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    window = MainWindow() 
    window.show() 
    app.exec_() 
+0

你在哪个平台上?文件对话框*总是*缓慢,或者仅当您使用您发布的代码时? – ekhumoro

+0

我在Windows 7上。如果我使用像getSaveFileName这样的预定义方法,它的速度很快,但是如果我使用dialog = QtGui.QFileDialog(self)创建一个自定义对话框,并使用dialog.exec_(),它就像地狱一样慢。 – Ahsous

回答

3

QFileDialog构造函数创建一个Qt对话框,而静态函数(如getSaveFileName)将创建一个原生一个(除非DontUseNativeDialog选项设置为True)。

本机对话框可能比Qt更快或更慢,具体取决于使用的平台。

对于某些平面,看起来问题可能更严重。请参阅this longstanding bug,它会影响使用Qt 4.7/4.8的Windows XP和Windows 7(以及其他版本)。

UPDATE

只是要清楚:

在Windows中,静态函数QFileDialog.getExistingDirectory打开本地的“浏览文件夹”对话框中,只允许选择一个目录。所以Qt无法提供本地对话框来选择多个目录,因为Windows不提供一个。

另一个主要的选择是使用Qt自己的非本地文件对话框和猴子补丁,如this faq中所建议的。但是,正如您已经发现的那样,目前由于底层实现中的错误而导致令人烦恼的缓慢的显着缺点。

剩下的唯一选择是编写自己的目录列表对话框,或者试着想办法解决您的直接问题(即不使用文件对话框)。

+0

我试图让DontUseNativeDialog为False,但没有产生任何效果。 有没有另一种方法来创建一个文件对话框,我可以选择多个目录? – Ahsous

+0

@Ahsous。没有什么可说的,但我尽可能地更新了答案。 – ekhumoro

0

我的默认Qt文件浏览器对话框的性能非常慢。列出一个目录花费了大约5秒,选择一个文件花了大约3秒。添加“DontUseNativeDialog”选项完全解决了我的问题。

file_path = QtGui.QFileDialog.getSaveFileName(self, 'Title', path, "", "", QtGui.QFileDialog.DontUseNativeDialog) 
print file_path