Modern kullanıcı arayüzlerinde (UI) statik ve keskin geçişler artık çağdışı kabul edilmektedir. Bir butona tıklandığında yumuşakça parlaması, açılır menülerin kayarak genişlemesi veya hata durumunda bir panelin kırmızıya dönüp titremesi kullanıcı deneyimini (UX) üst seviyeye taşır. Qt Quick dünyasında QML animasyonlar ve states mimarisi, GPU hızlandırmalı motoru sayesinde minimum kodla pürüzsüz 60 FPS görsel geçişler tasarlamanıza olanak tanır.
Bu rehberde; QML animasyon türlerini (NumberAnimation, ColorAnimation, SequentialAnimation), Behavior ile anında reaktif animasyonları ve State ile Transition bloklarını kullanarak temiz durum makineleri (State Machine) kurmayı öğreneceğiz.
QML Animasyon Türleri
Qt Quick içinde her veri tipine ve amaca uygun özelleşmiş animasyon nesneleri bulunur:
| Animasyon Tipi | Hedef Özellik | Örnek Kullanım |
|---|---|---|
NumberAnimation | x, y, width, height, opacity, scale | Konum kaydırma, boyutlandırma, opaklık |
ColorAnimation | color, border.color | Buton rengi ve zemin geçişleri |
RotationAnimation | rotation | İbreler, yükleniyor çarkları (spinner) |
SequentialAnimation | Sıralı çalışan animasyonlar | Önce büyü, sonra rengi değiştir |
ParallelAnimation | Eşzamanlı çalışan animasyonlar | Aynı anda hem büyü hem şeffaflaş |
1. Behavior ile Zahmetsiz Animasyonlar
Bir özelliğin değeri her değiştiğinde otomatik olarak yumuşak bir geçiş sağlamanın en pratik yolu Behavior tanımıdır:
import QtQuick 2.15
Rectangle {
id: animatedBox
width: 100
height: 100
color: "#3498db"
radius: 8
// x konumu ne zaman değişirse 400ms içinde yumuşakça kaydır
Behavior on x {
NumberAnimation {
duration: 400
easing.type: Easing.OutBack // Hafif yaylanma efekti!
}
}
// Renk ne zaman değişirse 250ms içinde erit
Behavior on color {
ColorAnimation { duration: 250 }
}
MouseArea {
anchors.fill: parent
onClicked: {
animatedBox.x = (animatedBox.x === 0) ? 200 : 0
animatedBox.color = (animatedBox.color == "#3498db") ? "#e74c3c" : "#3498db"
}
}
}
İpucu:
easing.typeparametresi animasyonun matematiğini belirler (Easing.Linear,Easing.InOutQuad,Easing.OutBounce,Easing.OutBack). Doğal ve fiziksel hissettiren bir arayüz içinEasing.OutQuadveyaEasing.OutBackstandart tercihlerdir.
2. Durumlar (States) ve Geçişler (Transitions)
Bir bileşenin birden fazla görsel durumu olduğunda (örneğin: NORMAL, HOVERED, ERROR, LOADING), if/else bloklarıyla stil değiştirmek yerine State Machine kurmak profesyonel standarttır.
Aşağıda iki farklı durumu (normal ve danger) ve aralarındaki animasyonlu geçişi içeren bir uyarı paneli örneği yer almaktadır:
import QtQuick 2.15
Rectangle {
id: alertCard
width: 320
height: 120
radius: 12
state: "normal" // Başlangıç durumu
// --- DURUM TANIMLARI (STATES) ---
states: [
State {
name: "normal"
PropertyChanges { target: alertCard; color: "#2c3e50"; scale: 1.0 }
PropertyChanges { target: statusText; text: "Sistem Normal"; color: "#2ecc71" }
PropertyChanges { target: warningIcon; opacity: 0.0 }
},
State {
name: "danger"
PropertyChanges { target: alertCard; color: "#c0392b"; scale: 1.05 }
PropertyChanges { target: statusText; text: "KRİTİK SICAKLIK!"; color: "#ffffff" }
PropertyChanges { target: warningIcon; opacity: 1.0 }
}
]
// --- GEÇİŞ ANİMASYONLARI (TRANSITIONS) ---
transitions: [
Transition {
from: "normal"
to: "danger"
// İki durum arasında aynı anda renk, boyut ve opaklık geçişi yap
ParallelAnimation {
ColorAnimation { target: alertCard; property: "color"; duration: 300 }
NumberAnimation { target: alertCard; property: "scale"; duration: 200; easing.type: Easing.OutBack }
NumberAnimation { target: warningIcon; property: "opacity"; duration: 300 }
}
},
Transition {
from: "danger"
to: "normal"
ParallelAnimation {
ColorAnimation { target: alertCard; property: "color"; duration: 300 }
NumberAnimation { target: alertCard; property: "scale"; duration: 200 }
NumberAnimation { target: warningIcon; property: "opacity"; duration: 300 }
}
}
]
// Arayüz Elemanları
Row {
anchors.centerIn: parent
spacing: 15
Text {
id: warningIcon
text: "⚠️"
font.pixelSize: 32
}
Text {
id: statusText
font.pixelSize: 20
font.bold: true
anchors.verticalCenter: parent.verticalCenter
}
}
// Durumu Değiştiren Test Tıklaması
MouseArea {
anchors.fill: parent
onClicked: {
alertCard.state = (alertCard.state === "normal") ? "danger" : "normal"
}
}
}
3. Sıralı Animasyon ile Dikkat Çekme Titremesi (Shake Effect)
Bir input alanı hatalı girildiğinde pencereyi veya kutuyu sağa-sola sallamak için SequentialAnimation harika bir çözümdür:
SequentialAnimation {
id: shakeAnimation
NumberAnimation { target: errorInput; property: "x"; to: errorInput.x + 10; duration: 50 }
NumberAnimation { target: errorInput; property: "x"; to: errorInput.x - 10; duration: 50 }
NumberAnimation { target: errorInput; property: "x"; to: errorInput.x + 8; duration: 50 }
NumberAnimation { target: errorInput; property: "x"; to: errorInput.x - 8; duration: 50 }
NumberAnimation { target: errorInput; property: "x"; to: errorInput.x; duration: 50 }
}
Hatalı giriş algılandığında tek yapılması gereken shakeAnimation.start() çağırmaktır!
Özet
QML’in animasyon motoru modern bir uygulamanın ruhudur. Behavior ile küçük mikro etkileşimleri, States & Transitions ile karmaşık ekran akışlarını birkaç satırda kurgulayarak kullanıcılarınıza üst düzey bir arayüz tecrübesi sunabilirsiniz.