我正在使用PyQt4編寫監視文件夾的應用程序,並在收集數據(包含在子文件夾中)時導入數據,以便可以在生成數據時對其執行分析。使用QFileSystemWatcher在生成數據文件時導入數據文件的更好方法?
從本質上講,數據收集軟件的工作方式是它生成一個文件夾放置其數據文件。在該文件夾中,它會放置多個文件 - 不同的.xml文件,其中包含軟件的不同配置參數以及實際數據文件,並保存爲.csv文件。
我已經寫了一個小測試應用程序(下面),它能夠觀察文件夾,尋找附加子文件夾,然後觀察這些子文件夾中的文件更改,以便可以導入數據。不過,我不確定我是否會以最佳方式進行討論。特別是,因爲添加了多個文件,我必須篩選什麼是和不是我需要的文件(通常我只需要1個xml文件和1個數據文件,其他位是無關的)。另外,這可能是更大的問題 - 數據文件本身作爲另一個文件(只是一個臨時文件)開始,數據採集軟件然後在記錄結束時將其轉換爲相應的.csv文件(臨時文件然後被刪除)。生成.csv文件時生成的directoryChanged信號出現在轉換之後,但在文件完全寫入之前(有時 - 這是事情變得有點模糊的地方)。我的意思是,有時候,如果我在輸入信號時導入數據,整個數據集都會被導入。其他時候,只有一部分(例如前200行)被導入。但是,如果我等待下一個directoryChanged信號,那麼我會得到整個數據集。不過,我不確定如何專門等待下一個信號。我可以使用一個計數器(與我使用switch切換到True和False的方式相同),但這看起來相當笨拙(就像我目前用「switch」實現的方式對我來說似乎非常笨重)
這可能不是很清楚,所以我在下面提供了一個示例輸出。它說什麼「導入數據」,這是我的導入功能。這就是我有時可以得到完整數據集的地方,有時候我只能得到它的一部分。
我只是想知道是否有更好的方法去做這件事,因爲這是我第一次(讀:猜)如何做到這一點。
代碼:
class FileWatcher(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.resize(160, 160)
self.data_folder = None
self.current_xml = None
self.vr_csv = None
self.watch_path = []
self.watch_folder = None
self.switch = False
self.counter = 1
layout = QtGui.QVBoxLayout(self)
self.start_btn = QtGui.QPushButton("Start")
self.start_btn.clicked.connect(self.start_watching)
self.stop_btn = QtGui.QPushButton("Stop")
self.stop_btn.clicked.connect(self.stop_watching)
layout.addWidget(self.start_btn)
layout.addWidget(self.stop_btn)
def start_watching(self):
folder = QtGui.QFileDialog.getExistingDirectory(self)
self.watch_path.append(folder)
self.watch_folder = QtCore.QFileSystemWatcher(self.watch_path)
self.watch_folder.directoryChanged.connect(self.directory_changed)
def stop_watching(self):
self.data_folder = None
self.current_xml = None
self.vr_csv = None
self.watch_path = []
self.watch_folder = None
self.switch = False
self.counter = 1
def data_folder_changed(self, path):
print("data_folder_changed: %s" % self.counter)
self.counter += 1
xml_files = glob(path + "\\*VoltageRecording*.xml")
csv_files = glob(path + "\\*VoltageRecording*.csv")
if any(xml_files):
if self.current_xml != xml_files[-1]:
self.current_xml = xml_files[-1]
print(self.current_xml.split('\\')[-1])
vals = pxml.parse_vr(self.current_xml)
self.vr_csv = os.path.join(path, vals['voltage recording file'] + '.csv')
print(self.vr_csv.split('\\')[-1])
if any(csv_files):
if self.vr_csv == csv_files[-1]:
print("switch: %s" % self.switch)
if self.switch and self.vr_csv is not None:
print("Import Data")
print(self.vr_csv.split('\\')[-1])
self.switch = False
self.vr_csv = None
else:
self.switch = True
print()
def directory_changed(self, path):
data_folder_path = [glob(path+"/*")[-1], ]
print("directory_changed")
print(data_folder_path)
print()
self.data_folder = QtCore.QFileSystemWatcher(data_folder_path)
self.data_folder.directoryChanged.connect(self.data_folder_changed)
輸出示例(3個週期,所以將有3個數據文件導入):
directory_changed
['C:\\Users\\User\\Desktop\\Test_watch\\Test-001']
data_folder_changed: 1
data_folder_changed: 2
data_folder_changed: 3
Test-001_Cycle00001_VoltageRecording_001.xml
Test-001_Cycle00001_VoltageRecording_001.csv
data_folder_changed: 4
data_folder_changed: 5
data_folder_changed: 6
switch: False
data_folder_changed: 7
switch: True
Import Data
Test-001_Cycle00001_VoltageRecording_001.csv
data_folder_changed: 8
data_folder_changed: 9
Test-001_Cycle00002_VoltageRecording_001.xml
Test-001_Cycle00002_VoltageRecording_001.csv
data_folder_changed: 10
data_folder_changed: 11
data_folder_changed: 12
switch: False
data_folder_changed: 13
switch: True
Import Data
Test-001_Cycle00002_VoltageRecording_001.csv
data_folder_changed: 14
Test-001_Cycle00003_VoltageRecording_001.xml
Test-001_Cycle00003_VoltageRecording_001.csv
data_folder_changed: 15
data_folder_changed: 16
data_folder_changed: 17
data_folder_changed: 18
switch: False
data_folder_changed: 19
switch: True
Import Data
Test-001_Cycle00003_VoltageRecording_001.csv
data_folder_changed: 20