
**Pendahuluan**
Aplikasi manajemen kontak adalah proyek ideal untuk mempelajari konsep CRUD (Create, Read, Update, Delete) dalam GUI. Artikel ini akan membimbing Anda membuat aplikasi phonebook sederhana menggunakan PyQt5 dengan fitur tambah, edit, dan hapus kontak. Kita akan menggunakan kombinasi QListWidget dan QDialog untuk antarmuka yang interaktif.
---
### **Struktur Proyek**
1. **`main.py`** - File utama aplikasi
2. **`MainForm.py`** - Form utama manajemen kontak
3. **`EntryForm.py`** - Dialog form input data
---
### **1. File main.py**
```python
#!/usr/bin/python3
import sys
from PyQt5.QtWidgets import QApplication
from MainForm import MainForm
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainForm()
window.show()
app.exec_()
```
**Penjelasan:**
- Inisialisasi aplikasi Qt
- Membuat dan menampilkan form utama
- Memulai event loop
---
### **2. File MainForm.py**
#### **Komponen Utama**
```python
class MainForm(QWidget):
def __init__(self):
super().__init__()
# Inisialisasi UI
self.setupUi()
# Data storage
self.contacts = [] # Alternatif: gunakan model data terpisah
```
**Struktur UI:**
```python
def setupUi(self):
# Konfigurasi window
self.setGeometry(300, 300, 450, 350)
self.setWindowTitle('Phonebook Manager')
# Tombol aksi
self.buttonLayout = QHBoxLayout()
buttons = [
('Tambah', self.addButtonClick),
('Ubah', self.editButtonClick),
('Hapus', self.deleteButtonClick),
('Kosongkan', self.contactList.clear),
('Keluar', self.close)
]
for text, handler in buttons:
btn = QPushButton(text)
btn.clicked.connect(handler)
self.buttonLayout.addWidget(btn)
# List kontak
self.contactList = QListWidget()
# Layout utama
mainLayout = QVBoxLayout()
mainLayout.addWidget(self.contactList)
mainLayout.addLayout(self.buttonLayout)
self.setLayout(mainLayout)
```
**Fitur CRUD:**
1. **Tambah Kontak**
```python
def addButtonClick(self):
dialog = EntryForm()
if dialog.exec_() == QDialog.Accepted:
name = dialog.nameLineEdit.text().strip()
phone = dialog.phoneLineEdit.text().strip()
if name and phone:
self.contactList.addItem(f"{name} - {phone}")
```
2. **Edit Kontak**
```python
def editButtonClick(self):
selected = self.contactList.currentItem()
if not selected: return
dialog = EntryForm()
name, phone = selected.text().split(" - ")
dialog.nameLineEdit.setText(name)
dialog.phoneLineEdit.setText(phone)
if dialog.exec_() == QDialog.Accepted:
selected.setText(f"{dialog.nameLineEdit.text()} - {dialog.phoneLineEdit.text()}")
```
3. **Hapus Kontak**
```python
def deleteButtonClick(self):
row = self.contactList.currentRow()
if row >= 0:
self.contactList.takeItem(row)
```
---
### **3. File EntryForm.py**
```python
class EntryForm(QDialog):
def __init__(self):
super().__init__()
self.setupUi()
def setupUi(self):
# Konfigurasi dialog
self.setWindowTitle('Form Kontak')
self.setFixedSize(300, 150)
# Komponen input
self.nameLineEdit = QLineEdit()
self.phoneLineEdit = QLineEdit()
# Validasi input
self.phoneLineEdit.setValidator(QIntValidator())
# Tombol aksi
self.buttonBox = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel
)
self.buttonBox.accepted.connect(self.validate)
self.buttonBox.rejected.connect(self.reject)
# Layout
formLayout = QFormLayout()
formLayout.addRow('Nama Lengkap:', self.nameLineEdit)
formLayout.addRow('Nomor HP:', self.phoneLineEdit)
formLayout.addRow(self.buttonBox)
self.setLayout(formLayout)
def validate(self):
"""Validasi input sebelum accept"""
if self.nameLineEdit.text() and self.phoneLineEdit.text():
self.accept()
else:
QMessageBox.warning(self, 'Error', 'Semua field harus diisi!')
```
---
### **Arsitektur Aplikasi**
```
+-----------------------+
| Main Window |
| +-------------------+ |
| | Daftar Kontak | |
| +-------------------+ |
| [Tambah][Edit][Hapus] |
+-----------------------+
|
v
+-----------------------+
| EntryForm Dialog |
| Nama: _______________ |
| No HP: ______________ |
| [OK] [Batal] |
+-----------------------+
```
---
### **Best Practices**
1. **Pemisahan Logika**
- Pisahkan logika bisnis ke class terpisah
- Gunakan model-view-controller pattern
2. **Validasi Data**
```python
# Di EntryForm.py
self.phoneLineEdit.setValidator(QRegExpValidator(
QRegExp("[0-9]{8,15}"), self))
```
3. **Persistensi Data**
Simpan data ke file JSON:
```python
def save_data(self):
with open('contacts.json', 'w') as f:
json.dump([self.contactList.item(i).text()
for i in range(self.contactList.count())], f)
```
---
### **Penyempurnaan**
1. **Pencarian Kontak**
```python
self.searchField = QLineEdit()
self.searchField.textChanged.connect(self.filter_contacts)
def filter_contacts(self, text):
for i in range(self.contactList.count()):
item = self.contactList.item(i)
item.setHidden(text.lower() not in item.text().lower())
```
2. **Import/Export CSV**
```python
def export_csv(self):
with open('contacts.csv', 'w') as f:
writer = csv.writer(f)
writer.writerow(['Nama', 'Telepon'])
for i in range(self.contactList.count()):
name, phone = self.contactList.item(i).text().split(' - ')
writer.writerow([name, phone])
```
---
### **Kesimpulan**
Aplikasi ini menunjukkan:
✅ Implementasi CRUD dasar
✅ Manajemen dialog modal
✅ Penggunaan layout manager
**Challenge:** Tambahkan fitur grup kontak dan foto profil!
---
**Referensi Tambahan:**
- [Dokumentasi QListWidget](https://doc.qt.io/qt-5/qlistwidget.html)
- [PyQt Form Validation](https://www.pythonguis.com/tutorials/pyqt6-form-validation/)
- [Model-View Programming](https://doc.qt.io/qt-6/model-view-programming.html)
Komentar
Posting Komentar