Bases: QMainWindow, Ui_UploadWindow
File upload widget with real progress tracking.
Emits a signal with the file path when upload completes successfully.
Source code in src/views/file_load/upload_window.py
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 | class FileLoadView(QMainWindow, Ui_UploadWindow):
"""
File upload widget with real progress tracking.
Emits a signal with the file path when upload completes successfully.
"""
# Signal emitted when upload finishes, carrying the file path
uploadFinished = Signal(str)
def __init__(self) -> None:
"""
Sets up the upload window and connects UI elements to handlers.
Prepares the browse button and initializes worker and file references.
"""
super().__init__()
# Set up UI components from the .ui file
self.setupUi(self)
# Connect the Browse button to the file dialog handler
self.buttonBrowse.clicked.connect(self._browse)
# Placeholder for the UploadWorker thread (will be created on browse)
self._worker: Optional[UploadWorker] = None
# Store selected file path
self._file: Optional[str] = None
# ==========================================================================
# File Browsing and Starting Upload
# ==========================================================================
def _browse(self) -> None:
"""
Opens a file dialog to allow the user to pick a file.
The filter is determined by which radio button is selected.
"""
# Determine the file filter based on radio button selection
if self.radioExcel.isChecked():
file_name_filter = "Excel files (*.xlsx *.xls)"
elif self.radioCSV.isChecked():
file_name_filter = "CSV files (*.csv)"
elif self.radioPDF.isChecked():
file_name_filter = "PDF files (*.pdf)"
else:
# Fallback to all files if no specific radio is checked
file_name_filter = "All files (*)"
# Open the QFileDialog and retrieve the selected path
path, _ = QFileDialog.getOpenFileName(self, "Pick file", "", file_name_filter)
if path:
# If a path was chosen, start the upload process
self._start_upload(path)
def _start_upload(self, path: str) -> None:
"""
Starts the upload process by creating and running the worker thread.
Disables the browse button, resets the progress bar, and connects worker signals.
"""
# Store the chosen file path
self._file = path
# Display the path in the line edit
self.lineEditFilePath.setText(path)
# Reset progress bar to 0
self.progressBar.setValue(0)
# Disable the Browse button to prevent multiple uploads
self.buttonBrowse.setEnabled(False)
# Create the worker thread with the selected file path
self._worker = UploadWorker(path)
# Connect worker's progress signal to update the UI progress bar
self._worker.progress.connect(self._update_progress)
# Connect worker's finished signal to handle successful completion
self._worker.finished.connect(self._upload_finished)
# Connect worker's error signal to handle failures
self._worker.error.connect(self._upload_error)
# Start the worker thread (which invokes run() in a separate thread)
self._worker.start()
# ==========================================================================
# Progress and Completion Handlers
# ==========================================================================
def _update_progress(self, value: int) -> None:
"""
Updates the progress bar to reflect the current upload percentage.
Receives integer percentage from the worker.
"""
# Set the progress bar's value to the emitted percentage
self.progressBar.setValue(value)
def _upload_finished(self, path: str) -> None:
"""
Handles successful upload completion.
Updates UI to reflect 100% completion and re-enables the browse button.
Emits uploadFinished signal with the file path.
"""
# Ensure progress bar shows complete
self.progressBar.setValue(100)
# Re-enable the Browse button so user can upload another file
self.buttonBrowse.setEnabled(True)
# Emit the finished signal to notify parent that upload is done
self.uploadFinished.emit(path)
def _upload_error(self, error_msg: str) -> None:
"""
Handles errors that occur during upload.
Resets the UI and shows a critical message box with the error.
"""
# Re-enable the Browse button so user can retry
self.buttonBrowse.setEnabled(True)
# Reset progress bar to 0 to indicate failure
self.progressBar.setValue(0)
# Show an error message box with the error details
QMessageBox.critical(self, "Upload Error", f"Failed to upload file: {error_msg}")
# ==========================================================================
# Navigation Guards
# ==========================================================================
def can_go_next(self) -> bool:
"""
Prevents navigation to the next view until upload is fully complete.
Returns True only when progress bar reaches 100%.
"""
return self.progressBar.value() == 100
# noinspection PyMethodMayBeStatic
def can_go_back(self) -> bool:
"""
Prevents navigation backward from this first page.
The Upload window is the first page, so going back is not allowed.
"""
return False
|
__init__()
Sets up the upload window and connects UI elements to handlers.
Prepares the browse button and initializes worker and file references.
Source code in src/views/file_load/upload_window.py
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 | def __init__(self) -> None:
"""
Sets up the upload window and connects UI elements to handlers.
Prepares the browse button and initializes worker and file references.
"""
super().__init__()
# Set up UI components from the .ui file
self.setupUi(self)
# Connect the Browse button to the file dialog handler
self.buttonBrowse.clicked.connect(self._browse)
# Placeholder for the UploadWorker thread (will be created on browse)
self._worker: Optional[UploadWorker] = None
# Store selected file path
self._file: Optional[str] = None
|
can_go_back()
Prevents navigation backward from this first page.
The Upload window is the first page, so going back is not allowed.
Source code in src/views/file_load/upload_window.py
151
152
153
154
155
156
157 | def can_go_back(self) -> bool:
"""
Prevents navigation backward from this first page.
The Upload window is the first page, so going back is not allowed.
"""
return False
|
can_go_next()
Prevents navigation to the next view until upload is fully complete.
Returns True only when progress bar reaches 100%.
Source code in src/views/file_load/upload_window.py
142
143
144
145
146
147
148 | def can_go_next(self) -> bool:
"""
Prevents navigation to the next view until upload is fully complete.
Returns True only when progress bar reaches 100%.
"""
return self.progressBar.value() == 100
|