PyQt5のQFileSystemWatcherでフォルダを監視するテスト
2021/03/13 categories:PyQt5| tags:PyQt5|Python|
PyQt5でファイルの監視を試してみる為にQFileSystemWatcherを使ってみました。
ファイルリストの表示
QListViewに監視するフォルダ内のファイルパスを表示することにしました。ファイルパスの表示は、下記のコードのようにフォルダ内のファイルを取得して、全ての行を削除してから行の追加、データの登録という処理を行います。
def updateListView(self, path):
paths = list( path.glob('*.*') )
self.model.removeRows( 0, self.model.rowCount() )
self.model.insertRows( 0, len(paths) )
for row, p in enumerate(paths):
self.model.setData( self.model.index(row, 0), str(p) )
監視するフォルダのパスをQLineEditで指定
QLineEditに監視するフォルダのパスを入力することにしました。QLineEditのテキストが変更したときには下記のコードを実行して、監視するフォルダのパスを削除、ファイルリストの更新、監視するフォルダのパスを追加という処理をします。
def lineEditChanged(self, text):
path = Path(text)
for d in self.fileSystemWatcher.directories():
self.fileSystemWatcher.removePath(d)
if not path.exists():
return
self.updateListView(path)
self.fileSystemWatcher.addPath(text)
フォルダ内のファイルが変更されたときの処理
QFileSystemWatcherのdirectoryChangedにdirectory_changedをconnectして、フォルダ内のファイルが変更されたときにdirectory_changedを実行するようにします。
self.fileSystemWatcher.directoryChanged.connect(self.directory_changed)
def directory_changed(self, string):
self.updateListView(Path(string))
動作の様子
ソースコード
import sys
from pathlib import Path
from PyQt5 import QtWidgets, QtCore
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.centralWidget = QtWidgets.QWidget(self)
self.setCentralWidget(self.centralWidget)
self.centralLayout = QtWidgets.QVBoxLayout(self.centralWidget)
self.centralWidget.setLayout(self.centralLayout)
self.lineEdit = QtWidgets.QLineEdit(self.centralWidget)
self.listView = QtWidgets.QListView(self.centralWidget)
self.centralLayout.addWidget(self.lineEdit)
self.centralLayout.addWidget(self.listView)
self.model = Model(self.listView)
self.listView.setModel(self.model)
self.listView.setItemDelegate(Delegate())
self.fileSystemWatcher = QtCore.QFileSystemWatcher(self)
self.lineEdit.textChanged.connect(self.lineEditChanged)
self.fileSystemWatcher.directoryChanged.connect(self.directory_changed)
def updateListView(self, path):
paths = list( path.glob('*.*') )
self.model.removeRows( 0, self.model.rowCount() )
self.model.insertRows( 0, len(paths) )
for row, p in enumerate(paths):
self.model.setData( self.model.index(row, 0), str(p) )
def lineEditChanged(self, text):
path = Path(text)
for d in self.fileSystemWatcher.directories():
self.fileSystemWatcher.removePath(d)
if not path.exists():
return
self.updateListView(path)
self.fileSystemWatcher.addPath(text)
def directory_changed(self, string):
self.updateListView(Path(string))
class Model(QtCore.QAbstractItemModel):
def __init__(self, parent):
super(Model, self).__init__(parent)
self.item = []
def columnCount(self, parent=QtCore.QModelIndex()):
return 1
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return QtCore.QVariant()
if role == QtCore.Qt.EditRole or role == QtCore.Qt.DisplayRole:
return self.item[index.row()]
return QtCore.QVariant()
def flags(self, index):
if index.isValid():
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable
return QtCore.Qt.ItemIsEnabled
def index(self, row, column, parent=QtCore.QModelIndex()):
return self.createIndex( row, column, self.item[row] )
def insertRow(self, row, parent=QtCore.QModelIndex()):
self.insertRows(row, 1, parent)
def insertRows(self, row, count, parent=QtCore.QModelIndex()):
self.beginInsertRows(parent, row, row + count - 1)
self.item[row:row] = [ None for _ in range(count) ]
self.endInsertRows()
def parent(self, index):
return QtCore.QModelIndex()
def removeRow(self, row, parent=QtCore.QModelIndex()):
self.removeRows(row, 1, parent)
def removeRows(self, row, count, parent=QtCore.QModelIndex()):
self.beginRemoveRows(parent, row, row + count - 1)
del self.item[row:row+count]
self.endRemoveRows()
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.item)
def setData(self, index, value, role=QtCore.Qt.EditRole):
if role == QtCore.Qt.EditRole:
self.item[index.row()] = value
return True
return False
class Delegate(QtWidgets.QStyledItemDelegate):
def __init__(self, parent=None, setModelDataEvent=None):
super(Delegate, self).__init__(parent)
self.setModelDataEvent = setModelDataEvent
def createEditor(self, parent, option, index):
return QtWidgets.QLineEdit(parent)
def setEditorData(self, editor, index):
value = index.model().data(index, QtCore.Qt.EditRole)
editor.setText(str(value))
def setModelData(self, editor, model, index):
model.setData(index, editor.text())
if not self.setModelDataEvent is None:
self.setModelDataEvent()
def main():
app = QtWidgets.QApplication(sys.argv)
mainwindow = MainWindow()
mainwindow.show()
app.exec()
if __name__ == '__main__':
main()