import customtkinter as ctk
import datetime
import tkinter.messagebox as messagebox
from typing import Tuple, Dict
# Konfigurasi tema awal CustomTkinter
ctk.set_appearance_mode("Dark")
ctk.set_default_color_theme("blue")
class AplikasiTanggalLive(ctk.CTk):
"""
Kelas utama aplikasi GUI menggunakan CustomTkinter dengan paradigma OOP.
Menampilkan waktu (live) dan tanggal saat ini dalam bahasa Indonesia dengan UI modern.
"""
def __init__(self) -> None:
super().__init__()
# Setup properti window utama
self.title("Jam & Tanggal Live - Modern UI")
self.geometry("450x320")
self.configure(fg_color="#1a1a24") # Background utama: Midnight Blue
self.resizable(False, False)
# Memanggil metode inisialisasi UI
self._setup_ui()
# Memulai siklus pembaruan waktu secara real-time
self._jalankan_jam_live()
def _setup_ui(self) -> None:
"""Membangun dan mengatur tata letak (layout) seluruh elemen UI."""
# Frame Utama: Memberikan efek elevasi dari background window
self.main_frame = ctk.CTkFrame(
self,
fg_color="#252530", # Background frame: Charcoal / Dark Grey
corner_radius=15
)
self.main_frame.pack(padx=20, pady=20, fill="both", expand=True)
# Label Judul (Header)
self.lbl_header = ctk.CTkLabel(
self.main_frame,
text="WAKTU SAAT INI",
font=("Segoe UI", 14, "bold"),
text_color="#4DA8DA" # Aksen warna biru muda
)
self.lbl_header.pack(pady=(20, 0))
# Label Waktu (Jam) - Hierarki tipografi terbesar untuk fokus utama
self.lbl_waktu = ctk.CTkLabel(
self.main_frame,
text="00:00:00",
font=("Segoe UI", 54, "bold"),
text_color="#FFFFFF"
)
self.lbl_waktu.pack(pady=(5, 0))
# Label Tanggal (Teks sekunder)
self.lbl_tanggal = ctk.CTkLabel(
self.main_frame,
text="Memuat tanggal...",
font=("Segoe UI", 16),
text_color="#A0A0B0" # Warna abu-abu terang agar kontras tetap nyaman
)
self.lbl_tanggal.pack(pady=(0, 25))
# Frame pembungkus untuk tombol-tombol agar presisi
self.btn_frame = ctk.CTkFrame(self.main_frame, fg_color="transparent")
self.btn_frame.pack(pady=(0, 20))
# Primary Button: Tombol Salin Info
self.btn_copy = ctk.CTkButton(
self.btn_frame,
text="Salin Teks",
font=("Segoe UI", 14, "bold"),
fg_color="#0066CC",
hover_color="#004C99",
corner_radius=8,
command=self._salin_ke_clipboard
)
self.btn_copy.grid(row=0, column=0, padx=10)
# Secondary Button: Tombol Tutup
self.btn_close = ctk.CTkButton(
self.btn_frame,
text="Tutup",
font=("Segoe UI", 14, "bold"),
fg_color="#4A4A5A",
hover_color="#3A3A4A",
corner_radius=8,
command=self.destroy
)
self.btn_close.grid(row=0, column=1, padx=10)
def _dapatkan_waktu_indo(self) -> Tuple[str, str]:
"""Logika backend untuk mengambil waktu sistem dan menerjemahkan ke bahasa Indonesia."""
nama_hari: Dict[str, str] = {
'Monday': 'Senin', 'Tuesday': 'Selasa', 'Wednesday': 'Rabu',
'Thursday': 'Kamis', 'Friday': 'Jumat', 'Saturday': 'Sabtu', 'Sunday': 'Minggu'
}
nama_bulan: Dict[int, str] = {
1: 'Januari', 2: 'Februari', 3: 'Maret', 4: 'April', 5: 'Mei', 6: 'Juni',
7: 'Juli', 8: 'Agustus', 9: 'September', 10: 'Oktober', 11: 'November', 12: 'Desember'
}
sekarang = datetime.datetime.now()
hari_en = sekarang.strftime("%A")
hari_id = nama_hari.get(hari_en, hari_en)
tanggal = sekarang.day
bulan_id = nama_bulan.get(sekarang.month, str(sekarang.month))
tahun = sekarang.year
teks_waktu = sekarang.strftime("%H:%M:%S")
teks_tanggal = f"{hari_id}, {tanggal} {bulan_id} {tahun}"
return teks_waktu, teks_tanggal
def _jalankan_jam_live(self) -> None:
"""Memperbarui label waktu dan tanggal setiap 1000 milidetik (1 detik)."""
try:
waktu_baru, tanggal_baru = self._dapatkan_waktu_indo()
# Update teks pada UI
self.lbl_waktu.configure(text=waktu_baru)
self.lbl_tanggal.configure(text=tanggal_baru)
# Looping pemanggilan fungsi ini sendiri setelah 1000 ms
self.after(1000, self._jalankan_jam_live)
except Exception as e:
self.lbl_tanggal.configure(text="Error sistem.", text_color="#FF4C4C")
print(f"Error pada loop waktu: {e}")
def _salin_ke_clipboard(self) -> None:
"""Menyalin teks waktu dan tanggal saat ini ke clipboard sistem."""
waktu, tanggal = self._dapatkan_waktu_indo()
teks_salinan = f"{waktu} - {tanggal}"
self.clipboard_clear()
self.clipboard_append(teks_salinan)
self.update() # Memastikan clipboard terupdate di beberapa OS
# Feedback visual singkat untuk pengguna
self.btn_copy.configure(text="Tersalin!", fg_color="#28A745", hover_color="#218838")
self.after(2000, lambda: self.btn_copy.configure(text="Salin Teks", fg_color="#0066CC", hover_color="#004C99"))
# Titik masuk program (Entry point)
if __name__ == "__main__":
app = AplikasiTanggalLive()
app.mainloop()