탐색기에 있는 파일을 끌어다 놓거나 버튼을 눌러 파일을 추가하는 위젯을 만들 것이다.
Drop 이벤트를 처리할 수 있는 Line Edit 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
'''
filedroplineedit.py
'''
from PyQt5.QtWidgets import QLineEdit, QToolButton
from PyQt5.QtGui import QDragEnterEvent, QDropEvent
from PyQt5.QtCore import pyqtSignal
class FileDropLineEdit(QLineEdit):
# 파일 첨부 시그널
fileDropped = pyqtSignal(str)
def __init__(self, parent=None):
super(FileDropLineEdit, self).__init__(parent)
# 드롭 이벤트를 처리할 수 있도록 위젯 설정
self.setAcceptDrops(True)
self.setPlaceholderText("파일을 여기에 끌어다 놓으세요.")
self.setReadOnly(True)
self.setStyleSheet(
"padding: 3px;"
"border-style: solid;"
"border-width: 1px;"
"border-color: gray;"
"border-radius: 3px")
self.setClearButtonEnabled(True)
self.findChild(QToolButton).setEnabled(True)
self.textChanged.connect(lambda: self.clear)
def dragEnterEvent(self, event: QDragEnterEvent):
# 드래그 앤 드롭을 허용할 데이터 타입이 있는지 확인합니다.
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dropEvent(self, event: QDropEvent):
# 파일 경로를 가져와서 시그널을 발생시킵니다.
files = [u.toLocalFile() for u in event.mimeData().urls()]
all_files = ""
for file_path in files:
self.fileDropped.emit(file_path)
all_files += file_path + ';'
if all_files:
self.clear()
self.setText(all_files[:-1])
setReadOnly(True)
를 호출하면 QLineEdit 위젯을 사용자가 수정할 수 없도록 설정한다. 이 설정 때문에 사용자가 Clear 버튼을 누르는 것과 같은 수정 작업을 수행하면 textChanged()
시그널은 발생하지 않는다.
따라서, findChild(QToolButton).setEnabled(True)
를 호출하여 Clear 버튼을 활성화해 준다. 이렇게 하면 Clear 버튼을 누를 때 textChanged()
시그널이 발생한다.
파일 선택 위젯 만들기
- 빈 Widget을 하나 생성한 뒤, QLabel, QLineEdit, QPushButton을 추가한다.
- QLineEdit을 FileDropLineEdit으로 승격시킨다.
- 끌어다 놓기 이외에도 파일 추가 버튼을 눌러 파일을 추가할 수 있도록 한다.
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
'''
fileselectorwidget.py
'''
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal
from PyQt5 import uic
# UI 파일 로드
form_class = uic.loadUiType("fileselectorwidget.ui")[0]
class FileSelectorWidget(QWidget, form_class):
# 파일 첨부 시그널
fileSelected = pyqtSignal(str)
def __init__(self, parent=None):
super(FileSelectorWidget, self).__init__(parent)
self.setupUi(self)
self.fileDropLineEdit.fileDropped.connect(self.handle_drop_file)
self.fileAddButton.clicked.connect(self.handle_upload_file)
self.fileAddButton.setStyleSheet(
"padding: 3px;"
"border-style: solid;"
"border-width: 1px;"
"border-color: gray;"
"border-radius: 3px")
def handle_upload_file(self):
# 파일 선택 대화상자 열기
file_path, _ = QFileDialog.getOpenFileName(self, "파일 업로드", "", "All Files (*)")
# 파일 선택 후 처리
if file_path:
self.fileWidget.clear()
self.fileWidget.setText(file_path)
self.fileSelected.emit(file_path)
def handle_drop_file(self, file_path):
self.fileSelected.emit(file_path)
if __name__ == "__main__":
# QApplication 인스턴스 생성
app = QApplication(sys.argv)
myWindow = FileSelectorWidget()
myWindow.show()
app.exec_()
파일 선택 위젯 사용하기
빈 Form에 Widget을 추가해서 해당 위젯을 FileSelectorWidget으로 승격하여 사용하면 된다.