此工作代码提出qfiledialog,提示用户选择.csv文件:
def load(self,fileName=None):
if not fileName:
fileName=fileDialog.getOpenFileName(caption="Load Existing Radio Log",filter="csv (*.csv)")[0]
...
...
现在,我想更改该过滤器以更具选择性。该程序将每个项目保存为三个.csv文件(project.csv,project_fleetsync.csv,project_cluelog.csv(,但我只希望"文件"对话框显示第一个(project.csv(,以避免显示用户当只有三分之一可以通过LOAD((函数来处理其中的三分之一时,都有太多选择。
根据这篇文章,看起来解决方案是使用代理模型。因此,我将代码更改为以下(LOAD((中的所有注释行((都是我在各种组合中尝试的事情(:
def load(self,fileName=None):
if not fileName:
fileDialog=QFileDialog()
fileDialog.setProxyModel(CSVFileSortFilterProxyModel(self))
# fileDialog.setNameFilter("CSV (*.csv)")
# fileDialog.setOption(QFileDialog.DontUseNativeDialog)
# fileName=fileDialog.getOpenFileName(caption="Load Existing Radio Log",filter="csv (*.csv)")[0]
# fileName=fileDialog.getOpenFileName(caption="Load Existing Radio Log")[0]
# fileDialog.exec_()
...
...
# code for CSVFileSortFilterProxyModel partially taken from
# https://github.com/ZhuangLab/storm-control/blob/master/steve/qtRegexFileDialog.py
class CSVFileSortFilterProxyModel(QSortFilterProxyModel):
def __init__(self,parent=None):
print("initializing CSVFileSortFilterProxyModel")
super(CSVFileSortFilterProxyModel,self).__init__(parent)
# filterAcceptsRow - return True if row should be included in the model, False otherwise
#
# do not list files named *_fleetsync.csv or *_clueLog.csv
# do a case-insensitive comparison just in case
def filterAcceptsRow(self,source_row,source_parent):
print("CSV filterAcceptsRow called")
source_model=self.sourceModel()
index0=source_model.index(source_row,0,source_parent)
# Always show directories
if source_model.isDir(index0):
return True
# filter files
filename=source_model.fileName(index0)
# filename=self.sourceModel().index(row,0,parent).data().lower()
print("testing lowercased filename:"+filename)
if filename.count("_fleetsync.csv")+filename.count("_clueLog.csv")==0:
return True
else:
return False
文件仍在对话框中列出。显然我在做错事...
在此处的另一个stackoverflow问题上找到了解决方案。
来自该解决方案:
主要要注意的是致电 对话框。 Dialog.setproxymodel。
也看起来您必须使用filedialog.exec_((而不是filedialog.getopenfilename。您设置为setNameFilter的值确实显示在非本地对话框的滤波器循环字段中,但实际上仅用于装饰,因为接头滤波器过滤器覆盖了它。我认为这是一件好事
感谢用户Frank和Ariwez。
更新:要澄清,这是我正在使用的完整最终代码:
def load(self,fileName=None):
if not fileName:
fileDialog=QFileDialog()
fileDialog.setOption(QFileDialog.DontUseNativeDialog)
fileDialog.setProxyModel(CSVFileSortFilterProxyModel(self))
fileDialog.setNameFilter("CSV Radio Log Data Files (*.csv)")
fileDialog.setDirectory(self.firstWorkingDir)
if fileDialog.exec_():
fileName=fileDialog.selectedFiles()[0]
else: # user pressed cancel on the file browser dialog
return
... (the rest of the load function processes the selected file)
...
# code for CSVFileSortFilterProxyModel partially taken from
# https://github.com/ZhuangLab/storm-control/blob/master/steve/qtRegexFileDialog.py
class CSVFileSortFilterProxyModel(QSortFilterProxyModel):
def __init__(self,parent=None):
# print("initializing CSVFileSortFilterProxyModel")
super(CSVFileSortFilterProxyModel,self).__init__(parent)
# filterAcceptsRow - return True if row should be included in the model, False otherwise
#
# do not list files named *_fleetsync.csv or *_clueLog.csv
# do a case-insensitive comparison just in case
def filterAcceptsRow(self,source_row,source_parent):
# print("CSV filterAcceptsRow called")
source_model=self.sourceModel()
index0=source_model.index(source_row,0,source_parent)
# Always show directories
if source_model.isDir(index0):
return True
# filter files
filename=source_model.fileName(index0).lower()
# print("testing lowercased filename:"+filename)
# never show non- .csv files
if filename.count(".csv")<1:
return False
if filename.count("_fleetsync.csv")+filename.count("_cluelog.csv")==0:
return True
else:
return False