Membuat Aplikasi Baca/Tulis File dengan PyQt5: Panduan Interaksi GUI dan Sistem Berkas untuk Pemula




**Pendahuluan**  
Manipulasi file adalah operasi fundamental dalam pemrograman. Artikel ini akan membimbing Anda membuat aplikasi GUI sederhana menggunakan PyQt5 yang mampu menulis dan membaca file teks. Kode ini mencakup validasi input, manajemen status komponen GUI, dan operasi I/O dasar, cocok untuk pemula yang ingin memahami integrasi antarmuka pengguna dengan operasi sistem berkas.

---

### **Struktur Proyek**  
1. **Antarmuka Pengguna**  
   - Field input nama file  
   - Editor teks untuk input/output  
   - Tombol aksi tulis/baca  
2. **Logika Operasi File**  
   - Validasi input  
   - Operasi tulis file  
   - Operasi baca file  

---

### **1. Implementasi GUI**  
#### **Komponen Utama**  
```python
# Input nama file
self.fileEdit = QLineEdit()

# Area teks input/output
self.inputTextEdit = QTextEdit()
self.outputTextEdit = QTextEdit()
self.outputTextEdit.setReadOnly(True)  # Hanya baca

# Tombol aksi
self.writeButton = QPushButton('Tulis Data')
self.readButton = QPushButton('Baca Data')
```

#### **Tata Letak**  
```python
layout = QVBoxLayout()
layout.addWidget(QLabel('Nama file'))
layout.addWidget(self.fileEdit)
layout.addWidget(QLabel('Data yang akan ditulis'))
layout.addWidget(self.inputTextEdit)
layout.addWidget(QLabel('Data yang dibaca'))
layout.addWidget(self.outputTextEdit)

# Layout tombol horizontal
buttonLayout = QHBoxLayout()
buttonLayout.addStretch()
buttonLayout.addWidget(self.writeButton)
buttonLayout.addWidget(self.readButton)

layout.addLayout(buttonLayout)
```

**Tampilan GUI:**  
```
[Nama File]        : _______________
[Data Input]       : [Text Editor]
[Data Output]      : [Text Editor]
            [Tulis Data] [Baca Data]
```

---

### **2. Logika Operasi File**  
#### **Validasi Input**  
```python
def writeButtonClick(self):
    # Cek nama file tidak kosong
    if not self.fileEdit.text().strip():
        QMessageBox.critical(self, 'Error', 'Nama file harus diisi')
        return
    
    # Cek konten tidak kosong
    if self.inputTextEdit.document().isEmpty():
        QMessageBox.critical(self, 'Error', 'Data input kosong')
        return
```

#### **Operasi Tulis File**  
```python
try:
    with open(self.fileEdit.text(), 'w') as f:
        f.write(self.inputTextEdit.toPlainText())
    # Update status UI
    self.toggleUI(False)
except Exception as e:
    QMessageBox.critical(self, 'Error', f'Gagal menulis file: {str(e)}')
```

#### **Operasi Baca File**  
```python
def readButtonClick(self):
    try:
        with open(self.fileEdit.text(), 'r') as f:
            self.outputTextEdit.setPlainText(f.read())
    except FileNotFoundError:
        QMessageBox.critical(self, 'Error', 'File tidak ditemukan')
    except Exception as e:
        QMessageBox.critical(self, 'Error', f'Gagal membaca file: {str(e)}')
```

---

### **Manajemen Status UI**  
```python
def toggleUI(self, write_mode):
    """Mengaktifkan/menonaktifkan komponen"""
    self.fileEdit.setEnabled(write_mode)
    self.inputTextEdit.setEnabled(write_mode)
    self.writeButton.setEnabled(write_mode)
    self.readButton.setEnabled(not write_mode)
```

**Flow UI:**  
1. Saat awal: Tombol "Baca Data" dinonaktifkan  
2. Setelah tulis sukses:  
   - Field input dinonaktifkan  
   - Tombol "Baca Data" diaktifkan  

---

### **Best Practices**  
1. **Error Handling**  
   - Gunakan blok `try-except` untuk operasi file  
   - Tampilkan pesan error spesifik dengan `QMessageBox`  

2. **Manajemen Resource**  
   Gunakan `with open()` untuk automatisasi penutupan file:  
   ```python
   with open(filename, 'w') as f:
       f.write(content)
   ```

3. **Validasi Input**  
   - Cek ekstensi file  
   - Batasi ukuran file maksimum  
   ```python
   if not filename.endswith('.txt'):
       QMessageBox.warning(self, 'Peringatan', 'Hanya file .txt yang diizinkan')
   ```

---

### **Penyempurnaan yang Direkomendasikan**  
1. **File Dialog**  
   ```python
   from PyQt5.QtWidgets import QFileDialog
   
   def browseFile(self):
       filename, _ = QFileDialog.getSaveFileName(
           self, 'Simpan File', '', 'Text Files (*.txt)')
       if filename:
           self.fileEdit.setText(filename)
   ```

2. **Riwayat File**  
   Simpan daftar file terakhir yang diakses menggunakan `QSettings`:  
   ```python
   self.settings = QSettings('MyCompany', 'MyApp')
   self.recent_files = self.settings.value('recent_files', [])
   ```

3. **Enkripsi Dasar**  
   Tambahkan opsi enkripsi sederhana:  
   ```python
   from cryptography.fernet import Fernet
   
   def encrypt_content(self, content):
       return Fernet(key).encrypt(content.encode())
   ```

---

### **Diagram Alur Aplikasi**  
```
[User Input] --> [Validasi] --> [Tulis File] --> [Update UI]
                          `--> [Baca File]  --> [Tampilkan Konten]
```

---

### **Kesimpulan**  
Aplikasi ini menunjukkan:  
✅ Integrasi operasi file dengan GUI  
✅ Manajemen state komponen yang dinamis  
✅ Penanganan error yang baik  

**Challenge:** Tambahkan fitur berikut:  
- Pilihan mode append/salin baru  
- Preview isi file sebelum menyimpan  
- Pengecekan duplikasi nama file  

---

**Referensi Tambahan:**  
- [Dokumentasi QTextEdit](https://doc.qt.io/qt-5/qtextedit.html)  
- [Panduan File Handling Python](https://realpython.com/read-write-files-python/)  
- [PyQt5 Input Validation](https://www.pythonguis.com/tutorials/pyqt-validating-user-input/)

Komentar