PyQt5 QMainWindowにドロップ可能なファイルの拡張子を制限する

Share on:

前回作ったファイルのドロップイベントは全ての拡張子のファイルをドロップできるプログラムでした。一般的なプログラムではドロップできるファイルの拡張子を制限していることが多いので、ドロップ可能な拡張子を制限するプログラムを作成しました。

ドロップ可能な拡張子リスト

MainWindowクラスのプロパティにallow_suffixesというリストを用意して、その中に拡張子を入れるようにしました。複数指定したい場合も考慮してリストとしています。

1self.allow_suffixes = ['.png', '.pdf']

拡張子の比較とドロップ許可

MainWindowにドラッグしたファイルのパスは、event.mimeData().urls()でQUrlとして取得できます。そのQUrlのリストをpathlibのPathに変換します。

1urls = event.mimeData().urls()
2paths = [ Path(url.toLocalFile()) for url in urls ]

Pathのリストから重複無しの拡張子リストを作成します。そのリストから許可したい拡張子を削除していきます。

1suffixes = list( set([ path.suffix for path in paths ]) )
2for suffix in self.allow_suffixes:
3    if suffix in suffixes:
4        suffixes.remove(suffix)

リストのサイズが0より大きければ、許可する拡張子以外が含まれていることになるので、event.ignore()でドロップを許可しないようにすると、指定した拡張子以外ではドロップできないようになります。

1if len(suffixes) > 0:
2    event.ignore()
3else:
4    event.accept()

ソースコード

 1# -*- coding: utf-8 -*-
 2import sys
 3from pathlib import Path
 4from PyQt5 import QtWidgets
 5
 6class MainWindow(QtWidgets.QMainWindow):
 7    def __init__(self, app):
 8        super().__init__()
 9
10        self.textBrowser = QtWidgets.QTextBrowser(self)
11        self.setCentralWidget(self.textBrowser)
12        self.setAcceptDrops(True)
13        self.allow_suffixes = ['.png', '.pdf']
14        
15    def dragEnterEvent(self, event):
16        if event.mimeData().hasUrls():
17
18            urls = event.mimeData().urls()
19            paths = [ Path(url.toLocalFile()) for url in urls ]
20            suffixes = list( set([ path.suffix for path in paths ]) )
21            for suffix in self.allow_suffixes:
22                if suffix in suffixes:
23                    suffixes.remove(suffix)
24
25            if len(suffixes) > 0:
26                event.ignore()
27            else:
28                event.accept()
29        else:
30            event.ignore()
31    
32    def dropEvent(self, event):
33        urls = event.mimeData().urls()
34        paths = [ Path(url.toLocalFile()) for url in urls ]
35        self.textBrowser.setText( '\n'.join([str(p) for p in paths]) )
36
37def main():
38    app = QtWidgets.QApplication(sys.argv)
39    window = MainWindow(app)
40    window.show()
41    app.exec()
42 
43if __name__ == '__main__':
44    main()

関連記事