Home QT 파일 선택 위젯 만들기(2)
Post
Cancel

QT 파일 선택 위젯 만들기(2)

파일 선택 위젯(1) 보다 기능이 추가된 위젯을 만들 것이다.

탐색기에 있는 파일/폴더를 끌어다 놓거나 버튼을 눌러 파일/폴더를 추가/삭제할 수 있다.

Drop 이벤트를 처리할 수 있는 Tree Widget 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
'''
filedroptreewidget.py
'''
import os
from PyQt5.QtWidgets import QTreeWidget, QTreeWidgetItem
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon

class FileDropTreeWidget(QTreeWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setHeaderHidden(True)
        self.setSelectionMode(QTreeWidget.ExtendedSelection)
        self.setAlternatingRowColors(True)

        # 드롭 이벤트를 받도록 설정
        self.setAcceptDrops(True)

    # 드래그 앤 드롭 액션이 들어갈 때 위젯으로 보내는 이벤트
    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    # 드래그 앤 드롭 동작이 진행되는 동안 전송되는 이벤트
    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    # 드래그 앤 드롭 동작이 완료되면 전송되는 이벤트
    def dropEvent(self, event):
        # 드랍된 파일 정보 가져오기
        if event.mimeData().hasUrls():
            event.setDropAction(Qt.CopyAction)
            event.accept()
            for url in event.mimeData().urls():
                path = str(url.toLocalFile())
                if os.path.isfile(path):
                    # 파일인 경우에는 QTreeWidgetItem을 생성하여 TreeWidget에 추가
                    self.add_file_icon_item(path)
                else:
                    self.add_folder_icon_item(path)
        else:
            event.ignore()

    def add_file_icon_item(self, root):
        item = QTreeWidgetItem(self, [root])
        item.setIcon(0, QIcon("icon/mIconFile.svg"))  # 파일 아이콘 설정
        self.addTopLevelItem(item)

    def add_folder_icon_item(self, root):
        item = QTreeWidgetItem(self, [root])
        item.setIcon(0, QIcon("icon/mIconFolder.svg"))  # 폴더 아이콘 설정
        self.addTopLevelItem(item)
        self.add_subdirs(item, root)

    def add_subdirs(self, parent, root):
        for item in os.listdir(root):
            if os.path.isdir(os.path.join(root, item)):
                sub_dir_path = os.path.join(root, item)
                sub_dir_item = QTreeWidgetItem(parent, [item])
                sub_dir_item.setIcon(0, QIcon("icon/mIconFolder.svg"))
                parent.addChild(sub_dir_item)
                self.add_subdirs(sub_dir_item, sub_dir_path)
            if os.path.isfile(os.path.join(root, item)):
                file_item = QTreeWidgetItem(parent, [item])
                file_item.setIcon(0, QIcon("icon/mIconFile.svg"))  # 파일 아이콘 설정
                parent.addChild(file_item)

Drop 이벤트 검증 및 파일 선택 위젯 만들기

  1. 아래 그림과 같은 Form을 만든다. Tree Widget은 FileDropTreeWidget으로 승격시킨다. qt_trd_1
  2. 추가된 버튼들에도 기능을 추가해준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
'''
fileselectorlistwidget.py
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic

# UI 파일 로드
form_class = uic.loadUiType("fileselectorlistwidget.ui")[0]

class FileSelectorListWidget(QWidget, form_class):
    def __init__(self, parent=None):
        super(FileSelectorListWidget, self).__init__(parent)
        self.setupUi(self)

        # 버튼에 대한 이벤트 처리
        self.btnFileAdd.clicked.connect(self.add_file)
        self.btnFileRemove.clicked.connect(self.remove_item)
        self.btnFolderAdd.clicked.connect(self.add_folder)

    def add_file(self):
        # 파일 선택 다이얼로그 생성
        file_dialog = QFileDialog(self)
        file_dialog.setFileMode(QFileDialog.ExistingFiles)
        if file_dialog.exec_():
            file_names = file_dialog.selectedFiles()

            # 선택된 파일들 Tree Widget에 추가
            for file_name in file_names:
                self.fileTreeWidget.add_file_icon_item(file_name)

    def remove_item(self):
        # 선택된 아이템 삭제
        root = self.fileTreeWidget.invisibleRootItem()
        for item in self.fileTreeWidget.selectedItems():
            (item.parent() or root).removeChild(item)

    def add_folder(self):
        # 폴더 선택 다이얼로그 생성
        dir_dialog = QFileDialog(self)
        dir_dialog.setFileMode(QFileDialog.Directory)
        if dir_dialog.exec_():
            dir_name = dir_dialog.selectedFiles()[0]

            # 선택된 폴더 Tree Widget에 추가
            self.fileTreeWidget.add_folder_icon_item(dir_name)

if __name__ == "__main__":
    # QApplication 인스턴스 생성
    app = QApplication(sys.argv)
    myWindow = FileSelectorListWidget()
    myWindow.show()
    app.exec_()
  • invisibleRootItem() : QTreeWidget 클래스에서 제공하는 트리 위젯의 루트 아이템을 반환하는 메소드

  • (item.parent() or root).removeChild(item) : item.parent()는 item의 부모 item을 반환합니다. 만약 item이 top-level item이라면 부모가 없으므로 None을 반환. item.parent()None인 경우에는 root.removeChild(item)을 실행하고, 그렇지 않은 경우에는 item.parent().removeChild(item) 을 실행

  
qt_trd_2qt_trd_3

Icon Source

This post is licensed under CC BY 4.0 by the author.
Trending Tags