Kafayı yiyecektim. Basit bir "Dark Mode" tuşu ekleyeyim, kullanıcı memnun olsun diye düşünmüştüm. Meğerse kendi mezarımı kazıyormuşum. Şu an projemdeki her bir QWidget, QLabel ve QPushButton için ayrı ayrı stil kuralları yazdığım, yüzlerce satırlık bir stylesheet dosyam var. Kodun neredeyse %40'ı artık sadece renkler, kenarlıklar ve gölgelerle uğraşıyor. Qt Designer'da bir butonu sürüklediğimde içimden "ah, bir de bunun karanlık mod CSS'ini yazacağım" diye bir ses geliyor.
Stil Dosyası İsyanı
İşe hevesle başladım. "Light" temam hazırdı. stylesheet.qss dosyama gidip basitçe, kullanıcı dark mode'u seçince uygulanacak bir sınıf ekledim.
Güzel. Sonra, "Aa, ama bu arkaplan rengi değişince yazılar görünmez oldu" dedim. Hemen label'ların rengini de değiştirdim.
Sonra butonlar... Sonra input kutuları... Sonra combobox'lar... Sonra scrollbar'lar... Sonra QMenu'ler... Sonra QToolTip'ler... Her yeni bileşen, her özel durum (QPushButton:hover, QLineEdit:disabled) için aynı kuralları light ve dark için ikişer kez yazmak zorunda kaldım. Stylesheet dosyam şiştikçe şişti. Debug etmesi bir kabusa dönüştü. "Bu buton neden beyaz?" diye baktığımda, 387. satırdaki bir noktalı virgülü unuttuğumu fark ettim.
Otomasyon Çılgınlığı
"Buna bir çözüm bulmalıyım" dedim ve işleri daha da karmaşık hale getirdim. Renk paletimi bir JSON config dosyasına taşıdım. Sonra, bu JSON'u okuyup runtime'da dinamik olarak QSS (Qt'in CSS'i) string'i oluşturan bir Python scripti yazdım.
Şaka gibi ama, artık UI'mi değil, UI'mi boyayan script'in hatalarını debug ediyorum. StackOverflow'da "dynamic qss generation" diye arattığımda çıkan cevapların hepsini denedim, hiçbiri mükemmel değil. Özellikle QPalette ile setStyleSheet'i birlikte kullanmaya çalışınca ortaya çıkan öncelik savaşlarından bahsetmiyorum bile.
Çıkarılan Ders (Belki)
En baştan, temayı merkezi bir yerden yönetecek bir sistem düşünmeliydim. Belki de tüm renkleri bir Qt Resource (.qrc) dosyasındaki bir yapılandırmadan almalı, her bileşeni tek tek elle boyamak yerine, uygulama genelinde bir "renk sağlayıcı" kullanmalıydım. Ya da belki de... hiç bulaşmamalıydım. Light tema gayet güzeldi!
Neyse, sonuçta çalışıyor. Karanlık mod açılıyor, her şey karanlık oluyor. Ama arkasındaki kod o kadar korkunç ki, bir daha stylesheet'e dokunmaktan korkuyorum. Siz de böyle bir CSS/QSS kabusu yaşadınız mı? Bu işin daha temiz, daha sürdürülebilir bir yolu var mı? Qt'te theming için sizin gizli silahınız ne?
İşe hevesle başladım. "Light" temam hazırdı. stylesheet.qss dosyama gidip basitçe, kullanıcı dark mode'u seçince uygulanacak bir sınıf ekledim.
CSS:
.DarkMode QMainWindow { background-color: #2b2b2b; }
CSS:
.DarkMode QLabel { color: #e0e0e0; }
"Buna bir çözüm bulmalıyım" dedim ve işleri daha da karmaşık hale getirdim. Renk paletimi bir JSON config dosyasına taşıdım. Sonra, bu JSON'u okuyup runtime'da dinamik olarak QSS (Qt'in CSS'i) string'i oluşturan bir Python scripti yazdım.
Python:
def generate_qss(theme):
template = f"QMainWindow {{ background-color: {theme['bg']}; }}"
# ... ve 300 satır daha böyle...
return template
En baştan, temayı merkezi bir yerden yönetecek bir sistem düşünmeliydim. Belki de tüm renkleri bir Qt Resource (.qrc) dosyasındaki bir yapılandırmadan almalı, her bileşeni tek tek elle boyamak yerine, uygulama genelinde bir "renk sağlayıcı" kullanmalıydım. Ya da belki de... hiç bulaşmamalıydım. Light tema gayet güzeldi!
Neyse, sonuçta çalışıyor. Karanlık mod açılıyor, her şey karanlık oluyor. Ama arkasındaki kod o kadar korkunç ki, bir daha stylesheet'e dokunmaktan korkuyorum. Siz de böyle bir CSS/QSS kabusu yaşadınız mı? Bu işin daha temiz, daha sürdürülebilir bir yolu var mı? Qt'te theming için sizin gizli silahınız ne?