QT (BÇOM Serisi – 2)

Basit Çoklu Oyun Motoru (BÇOM) serisinin ikinci yazısı ile serüvenimize devam edelim. İlk yazıya aşağıdaki adresten ulaşabilirsiniz:

Basit Çoklu Oyuncu Motoru – Snake v2.0 – Giriş

Bu yazımı, geliştireceğim uygulamalarda ve yazılarımda bundan sonra sıkça bahsedeceğim QT’ye ayırmak istiyorum. Yazının kapsamı her şeyiyle QT’yi anlatmak değil ki ona zaten bir yazı yetmez, apayrı bir yazı dizi gerekir ki yeri geldikçe kullanıma göre ilgili kabiliyetlerine yazılarımda yer vereceğim. Duruma göre kendine ait bir yazı dizisi haline de çevirebiliriz 😉 Bu arada, gerek kütüphanenin kendisinin dokümantasyonu, gerekse QT’ye ilişkin kitaplar oldukça çeşitli ve yeterli materyal içeriyor. Takıldığınızda google’a başvurmaktan çekinmeyin. Elbette, her yazımda olduğu gibi, faydalandığım, daha detaylı bilgiler içeren ve benzeri kaynakları yazımında sonundaki kaynaklar başlığı altında sizler ile paylaşıyor olacağım. Bunların da sizlere faydalı olacağını umuyorum.

Gelelim yazımın kapsamına, bu yazımda QT ile ilgili çok fazla teknik detaya girmeden genel olarak QT tarihçesi, öne çıkan kabiliyetleri, en önemli özelliklerinden bahsetmeye çalışacağım. Bunu da yaparken aslında bu ekosistemi kullanırken denk gelebileceğiniz kavramlar ve terimler üzerinden yapmaya gayret göstereceğim. Son olarak kurulum ile yazımı tamamlamayı planlıyorum (ilk etapta Visual Studio kullanarak örnek bir QT uygulaması geliştirmeyi de planlıyordum ama yazının gerek kapsamı gerekse uzun olması sebebi ile çıkarmaya karar verdim, tabi arada kod örnekleri olacak). Ee o zaman, daha fazla vakit kaybetmeden başlayalım.

Giriş

Öncelikle QT’yi ingilizce harfleri ile seslendirenler olduğu gibi (‘Q’ ve ‘T’), ‘cute’ şeklinde seslendirenler de mevcut. Hatta çoğunlukla, ikinci şekilde seslendirilmekte. Şimdi kısa bir tarihçe. QT’nin tohumları Norveç’li iki öğrenci tarafından 1990’lı yıllarda bir tez çalışması kapsamında atılmış.

İlk geliştirilme amacı da Unix ve Mac OS için kullanılabilecek bir grafiksel kullanıcı arayüzü geliştirmekmiş ve bunu kolay ve eğlenceli bir şekilde yapmak (o zamanın şartlarında gerçekten önemli bir hedef). Bunu yaparken de, o zamanlar oldukça popüler olan Nesne Yönelimli Yazılım geliştirme ilkelerini kendilerine şiar edinmişler. Aslında bakarsanız, kütüphanenin geldiği nokta da göz önüne alındığında, ne kadar doğru bir motivasyon ve hedef belirlendiğini göreceksiniz. O zamanlar bu arkadaşların QT anlamında ortaya koyduklarımı ilk tasarımlardan birisi aşağıdaki gibidir. Bunu paylaşıyorum, çünkü QT kullandıkça göreceğiniz üzere bu sınıfların bir çoğu halen kullanılıyor 🙂

Özet olarak QT yaklaşık olarak 25-28 yıllık bir geçmişe sahip, oldukça olgun ve yaygın olarak kullanılmakta olan bir kütüphane seti. Son olarak 5.13 sürümü yayınlanmış durumda. Aşağıda da, bu zamana kadar geçmişi özetleyen bir resim görebilirsiniz (tıkladığınız takdirde daha detaylı bir görünüm göreceksiniz):

QT Nedir?

Peki QT nedir ve neden kullanılabilir? Öncelikle neden kullanılabilir sorusuna bakacak olursak. Açıkçası bu noktada aşağıdaki hususları değerlendirmek de fayda var. Bunlardan bir yada birden fazlası sizin için önemli ise, QT sizin için doğru bir tercih olacaktır.

  • C++ tabanlı çoklu platform desteği sunan (bunlardan bazıları Linux, MacOS, Windows, Android ve iOS) bir Grafiksel Kullanıcı Arayüzü kütüphanesi,
  • C++ tabanlı Grafiksel Kullanıcı Arayüzü kütüphanesi :),
  • Grafiksel kullanıcı arayüzü bileşenleri yanında ağ programlama, veri tabanı erişimi ve benzeri kabiliyetleri çoklu platformlarda kullanabilme,
  • Olgun bir C++ kütüphanesi ve yaygın kullanıcı kitlesi,
  • Bildirimsel (“declarative“) bir dil kullanarak (bu durumda QML oluyor) hızlı grafiksel kullanıcı arayüzü geliştirme,
  • C++ yanında farklı dilleri kullanarak da (Java, Phyton, Ruby, C#, vb.) arayüzler geliştirmeye olanak sağlama,
  • QT’yi çok duyuyorum ve nedir merak ediyorum.

Artık bu noktada QT nin kapsamı hakkında bir fikriniz olduğunu düşünüyorum. Her ne kadar ağırlıklı olarak C++ kullanarak, grafiksel kullanıcı arayüz tabanlı uygulamalar geliştirme için kullanılıyor olsa da, kendi ifadeleri ile “Complete Cross Software Development Framework for Desktop, Mobile and Embedded Systems“, yani hem masaüstü hem mobil hem de gömülü sistemler için yazılım geliştirme çerçevesi olarak tanımlanabilir.

QT kütüphanesi bütün dünyada çok çeşitli firmalar tarafından kullanılmakta. Bunlardan bir kısmı KDE, Opera, VLC, Google Earth, EASA olarak sayılabilir.

QT sunduğu kabiliyetleri çeşitli modüller altında topluyor (Core, Network, GUI, vb.).  Bunların yanında gerek arayüzleri geliştirmek, gerekse çoklu dil desteği, uygulama oluşturma (qmake), kurulum dosyaları hazırlama ve benzeri işler için de araçlar sunmakta. Benzer şekilde VS gibi geliştirme ortamları için eklentileri de mevcut. Önümüzdeki başlıklarda bunlara sıra ile değineceğim. Bütün bunların yanında da, en çok başvuracağınız (başvurmanızı şiddetle tavsiye ettiğim) ise “Qt Assistant” aracıdır. Her türlü API, örnek kod ve benzeri dokümantasyona çevrim içi erişime ihtiyaç duymadan hızlı bir şekilde ulaşabilirsiniz. Bunun dışında QT’ye ilişkin internet üzerinde de bir çok kaynağa kolayca ulaşabilirsiniz.

QT’yi kullanırken dikkat etmeniz gereken bir diğer husus da lisanslama. Gerçi buna ayrı bir yazı da ayrılabilir, ama kısaca bahsedecek olursak, QT iki lisans altında sunuluyor bunlar Ticari ve Açık Kaynak Lisanslar. Ticari lisans ile her türlü dağıtım ve kullanım haklarını elde ediyorsunuz, ayrıca teknik destek ve benzeri konularda firma size yardımcı oluyor. Bunun dışındaki kullanımlarda ise açık kaynaklı lisans (GPL, LGPLv3) kullanılabilir. Burada da, kullandığınız kütüphane ve araçlara göre lisanslamalar farklılık gösterebiliyor. Hatta sürümler arasında da farklılıklar mevcut. Bunun ile ilgili olarak indirme sayfasında detaylı bilgi bulabilirsiniz.

Bunun yanında QT’ye ilişkin genel hususlar için de aşağıdaki sayfa oldukça bilgilendirici ve yönlendirici olacaktır.

https://doc.qt.io/qt-5/overviews-main.html#

Önemli Kavramlar

Evet geldik, QT ile ilgili bundan sonra sıkça karşılaşacağınız ve bence önemli olduğunu düşündüğüm kavramlara. Elbette bunlar bütün bir kümeyi kapsamıyor ama QT ile uygulama geliştirecekseniz bunlara göz atmakta fayda var. Öncelikle kütüphanenin genel yapısına ilişkin bir takım bilgiler vereceğim, yazımın başında neden QT kullanmanız gerektiğine göz atmıştık. Şimdi bu kütüphanenin önemli özelliklerine kısaca (yazı da kısa olacaktı 🙂 göz atacağız.
QT’yi anlamak için, örnek bir QT uygulama akışını anlamak oldukça önemli. Bu bağlamda da öncelikli olarak bakmamız gereken iki husus, olaylar ve bu olayların aslında yönetildiği ana olay döngüsü olacak. QT bir çok farklı Grafiksel Kullanıcı Arayüzü (GKA) kütüphanesi gibi olay güdümlü bir alt yapıya sahip. Peki bu ne demek? Şu demek, uygulamanın genel akışını, ortaya çıkan olaylar belirliyor (Ör. bir düğmeye basılması, pencerenin gösterilmesi ya da kapanması, vb.).
QT içerisinde bu olaylar QEvent temel sınıfı ile temsil edilmekte ve olayın tipine göre özelleşmektedir (Ör. klavye olayları için QKeyEvent, fare olayları için de QMouseEvent). Bu olayların her birinde, bu olayları işleyecek hedef nesneler ve olaya ilişkin parametreler bulunur. Bu hedef nesneler bu olayların kotarılmasına ilişkin mantığı kendi içlerinde barındırır ve gerekli işleri gerçekleştirirler. Bu olaylar hem uygulamanın içerisinden (düğmeye basılması) hem de dışarıdan (klavye/fare olayları) tetiklenebilir.
Bu olayların iletilmesi için kullanılan iki temel yöntem (API) vardır bunlar: sendEvent ve bir kuyruk kullanan postEvent. Yukarıda da bahsettiğim gibi, bir döngü bu olayları tek tek işleyerek dağıtır. Aşağıda bu kullanımlara ilişkin örnek kullanımları ve döngüyü görebilirsiniz. Tabi şunu da ifade etmekte fayda var, normal şartlarda, çoğu zaman hazır QT sınıflarını ya da görsel bileşenleri kullanacağınız için bu seviyede API çağrıları ile uğraşmıyor olacaksınız ama genel mantığı anlatmak adına bunların önemli olduğunu düşünüyorum.

yukarıdaki döngü, uygulamadan çıkılmasına ilişkin API’ler (QCoreApplication::exit() veya QCoreApplication::quit()) çağrılana kadar devam eder.
Yavaş yavaş, asıl varmak istediğimiz noktaya geliyoruz. Şimdi herhangi bir QT uygulamasını açtığınızda aşağıdaki gibi bir kod dizilimi göreceksiniz:

işte burada bulunan exec() API’si ile birlikte uygulamanın ana olay döngüsü başlar. Yukarıda bahsettiğim olay mekanizmasının çalışması için, birazdan anlatacağım sinyal/slot mekanizmalarının çalışması için, bu döngünün çalışması gerekmektedir. Başka neler buna ihtiyaç duyar diyecek olursanız: görsel bileşenler, zamanlayıcılar, ağ kabiliyetleri.
Burada dikkat edilmesi gereken hususlardan birisi de, pahalı işleri yaptığınız yer. Eğer bu tarz olayların kotaranlar, bu kotarıcı metotlar içerisinde çok uzun işlemler yaparlarsa, bu genel olay döngüsünü, ilgili işlem bitene kadar bloklar. Bunu önlemek için bu tarz işleri ayrı bir thread’de kotarmakta fayda var. Bu konuda da daha detaylı bilgi edinmek için https://wiki.qt.io/Threads_Events_QObjects#Events_and_the_event_loop kaynağı oldukça yeterli, bir göz atmanızı tavsiye ediyorum. Burada ayrıca thread’lere ilişkin bilgiler de bulunmakta. Şimdi de diğer önemli kavramlara bir göz atalım.

Meta-Nesne Sistem (Meta-Object System)

Olaylar ve olay döngülerinden sonra karşınıza çıkacak olan bir diğer önemli kavram da Meta-Nesne Sistemidir. Aslında eğer QT ile yazılmış herhangi bir kodu derlediğiniz zaman, kendi yazdığını dosyaların ve kodların yanında, otomatik olarak üretilmiş “moc_” uzantılı dosyalar ve otomatik olarak üretilmiş kodları göreceksiniz ki, bunlar da QT uygulaması oluşturulurken, nihai uygulamaya dahil olurlar. Bu işten sorumlu olan araç ise Meta-Nesne Derleyicisi (Meta-Object Compiler) dır, kısaca MOC diye de kullanılır. Bu derleyici yazmış olduğunu kodları tarar ve QT’nin C++ için olan eklentilerini tarar (ör. içerisinde bulduğu Q_OBJECT gibi anahtar kelimelere bakar) ve bunlara göre bahsedilen dosyaları otomatik olarak oluşturur. Bu aşamada aslında, uygulamayı oluşturduğunuz derleme aşamasına benzer fakat ek bir aşamadır. Burada oluşturulan dosyalar ne yapar diye soracak olursanız? Bunlardan en önemlileri sinyal/slot mekanizmaları, çalışma zamanı tip bilgisi (RTTI) kabiliyetler ve dinamik özellik sistemidir. MOC sisteminin de ilk etapta oluşturulmasının sebebi de sinyal ve slot mekanizması imiş (bunu ayrı bir başlık altında irdeleyeceğim). MOC ile ilgili daha detaylı bilgi ve burada bahsetmediğim bir takım kabiliyetleri için https://doc.qt.io/qt-5/moc.html adresine bakabilirsiniz.

Şimdi gelelim bu QObject sınıfına. QT’de en çok duyacağınız sınıflardan birisi de QObject’tir. Öncelikle QT’ye dair şu ana kadar ve bundan sonra bahsedeceğim bir çok kabiliyeti (ör. sinyal/slot) kullanabilmeniz için, sınıflarınızı QObject’ten türetmeniz gerekmekte ve genelde Q_OBJECT makrosunu sınıfınız içerisine yerleştirmeniz. Q_OBJECT MOC’un baktığı en önemli anahtar kelimedir. Şimdi, QT kullanacak örnek bir sınıf tanımlayalım birlikte:

QT için tanımlayacağınız ve hazır gelen bütün sınıfların genel yapısı basit olarak bu şekildedir. QObject’ten sınıfımızı türetip, Q_OBJECT ekleyerek, artık sınıfımızı MOC sistemi tarafından tanınır hale getirdik. Bu sayede uygulamamızı derlerken MOC da bu dosyaya bakarak ek dosyaları üretecek. Ayrıca bu sınıfa ilişkin meta-nesne bilgilerine de çalışma zamanında aşağıdaki gibi ulaşabileceğiz:

Tabi bunu zaten RTTI aracılığı ile “typeid(myclass).name()” çağrısı ile yapabilirdiniz ama QT bunu RTTI desteği olmadan da yapabilmekte. Bu da bize bu desteği olmayan veya bunun kapatıldığı durumlarda da bu kabiliyeti kullanabileceğimiz anlamına geliyor. Bunun yanında, yine RTTI’ı aktifleştirmeden “qobject_cast<>()” ‘i dynamic_cast gibi kullanabilirsiniz.

Kısaca sınıfımızı yukarıdaki hale getirince, aşağıdaki nimetlerden faydalanabiliyoruz:

  • RTTI desteği olmazsa bile sınıfımıza ilişkin “meta-nesne” bilgilerine erişim (sınıf ismi dönülmesi, çalışma zamanında newInstance() API’si ile bir nesnesinin oluşturulması, inherits() API’si ile nesnenin verilen sınıflardan türetilip türetilmediğinin kontrolü),
  • tr() API’si aracılığı ile farklı dil desteği kazandırılabilir,
  • Bu sınıflar artık yukarıda bahsettiğimiz olayları kullanabilirler,
  • Dinamik özellik sistemini kullanabilirler (bir sonraki başlıkta anlatacağım),
  • En önemlisi de, nesneler arası haberleşme için sinyal/slot mekanizmasını (ilerleyen başlıklarda anlatacağım) kullanabilirler.

Tabi burada şunu da belirtmekte fayda var ki, eğer yukarıda saydığım kabiliyete ihtiyacınız olmayacaksa, QObject’ten türetmek çok da ucuz değil ve siz bu şekilde aslında kullanmayacağınız bir takım kabiliyetleri yüklemiş oluyorsunuz ki bunun bir maliyeti olacaktır. Bu sebeple bunları kullanmayacaksanız ya da basit veri sınıfları için bu yaklaşımı uygulamayınız.

Son olarak Visual Studio eklentisini kurduğunuz zaman, VS, bu tarz dosyaların MOC tarafından çağrılmasını otomatik olarak tetikler. İlgili adımları çıktı penceresinden görebilirsiniz.

Meta-Nesne sistemine ve MOC’a ilişkin daha detaylı bilgilere ulaşmak için aşağıdaki adresleri hiç acımadan sömürebilirsiniz.

https://doc.qt.io/qt-5/metaobjects.html

https://doc.qt.io/qt-5/moc.html

Dinamik özellik sistemi (Property System)

QT, sınıflar için (tabi bir önceki başlıkta anlatılan şekilde tanımlanmış) güçlü bir özellik sistemi de sunmaktadır. Bu tarz kabiliyetler bazı derleyiciler tarafından özel anahtar kelimeler ile sağlanıyorken, QT bunu, derleyici ve platformdan bağımsız bir şekilde sunabilmekte. En basitinden bu sayede çalışma zamanında aşağıdaki gibi kullanım mümkün olmakta:

Bu sistem ile bu tarz bilgileri tutmak için sınıf içerisinde bir değişken tanımlamanıza gerek kalmıyor. Ayrıca kaynakların ifade ettiğine göre bu sayede, bu özellikle QML tarafından da kullanılabiliyormuş. Ayrıca çalışma zamanında ekleme ya da saklama ihtiyacı duyduğunuz bilgileri bu sayede güvenli bir şekilde tutabileceksiniz. Bu tarz dinamik olarak özellik eklemenin yanında sınıfınızı deklare ederken de bu özellikleri ekleyebilirsiniz. Bu sayede bu özelliklere ilişkin bir takım kısıtlamalar ve kontroller de eklenebilmekte. Hemen örnek bir kod üzerinden bunun kullanımına bakalım:

Yukarıdaki eklentiler ile birlikte iki tane getter/setter metodu eklemiş olduk. Bunların nasıl kullanacağımıza gelirsek aşağıda buna ilişkin de bir örnek kod görebilirsiniz. Temelde QT bu mekanizmalar için QVariant kullanmakta. Dikkatli kullanıcılarım artık std::any ve std::variant ile birlikte bu kabiliyetleri normal C++ uygulamalarında da kullanabileceklerini biliyorlardır.

Detaylı bilgi ve kullanılabilecek diğer özellik anahtar kelimeleri için https://doc.qt.io/qt-5/properties.html adresine göz atabilirsiniz.

sinyal/slot mekanizması

Evet, bana kalırsa QT’nin en önemli kabiliyetlerinden birisine gelmiş bulunuyoruz. Bana kalırsa QT’nin en güçlü kabiliyetlerinden de biridir. Buna ayrı bir başlık açmasak hakikaten ayıp olurdu. Peki nedir bu “Signal/Slot” mekanizması. Aslına bakarsanız tek bir cümle ile ifade edecek olursak bu kabiliyeti: “Nesneler arası haberleşme mekanizması.”. Evet bu kadar 🙂

Tabi tanımlamak kolay ama bunu mümkün kılan yukarıda da bahsetmiş olduğumu “meta-object system” mekanizmasıdır.

Yukarıda anlattıklarıma ilişkin daha detaylı bilgi ve daha fazlası için lütfen https://doc.qt.io/qt-5/signalsandslots.html başvurmaktan çekinmeyin, hatta muhakkak bir kere okuyun.

QT’nin görsel bileşen kabiliyetleri de göz önünde bulundurulunca, bunlar arasındaki haberleşme ihtiyacı eminim hepiniz için aşikardır. Bir düğmeye basınca ne olacak? Pencereyi kapattığımda yapılacakları nasıl tetiklerim? “Signal/Slot” lar işte bu ihtiyaçları QT yaklaşımı ile halletmekte. Peki bu arkadaşların rolleri nedir? Kaynak nesne var ise ilgili veriler ile bir sinyal yayımlar (signal).  Sinyal yayınlandıktan sonra, bu sinyale abone olan (ki kaynak sınıfın kendisi de bu olaya abone olabilir) sınıflar, bu verileri abone olan sınıflar içerisindeki “slot” olarak tanımlanmış üye metotlara yönlendirir. Aslında “slot” lar, sınıf üye metot tanımlamalarından bir farkı da yoktur. Aşağıda olası bazı bağlantılar ve bunların nasıl kullanılabileceğine ilişkin bir örnek gösterilmekte:

Peki bu normalde nasıl kotarılıyor? Ya “callback” dediğimiz fonksiyon işaretçileri ya da daha modern mekanizmalar ile bu halledilebiliyor, fakat bu da hem okunabilirlik hem de idame noktasında pek yeterli değil. Bunun yanında, bu tarz “callback” mekanizmasını kullanan diğer kütüphanelerde, genelde olayları tetikleyen sınıflar, hedef/abone olan sınıflara genel olarak bağımlılık içerebiliyor, QT’nin yaklaşımında bu tarz sıkıntılar yok, yani bir bağımlılık yok, ve tip güvenlidir (“type safe”). Tip güvenliğinden kastımız, sinyal ve slot metot imzaları ve tipleri aynı olmak zorundadır. Eğer bir sinyale slot bağlandı ise, ilgili sinyal tetiklendiğinde var ise bütün abone olan slot’lar haberdar edilir. Bir diğer avantajı ise sinyal/slot’ların “thread-safe” olmasıdır. Eğer bağlı olan sinyal ve slot’lar aynı thread’de çalışmaktaysalar, normal fonksiyon çağrısı şeklinde haberdar etme gerçekleşir. Fakat farklı thread’lerde iseler o zaman bu veriler bir kuyruk marifeti ile kopyalanır ve hedef thread’in olay döngüsü içerisinde kotarılır. Burada deklare edilen sinyaller otomatik olarak “moc” tarafından oluşturulur.

Şimdi, sinyal ve slotlara biraz daha yakından bakalım.

Sinyaller aslında bir olay olarak değerlendirilebilir ve sınıf içerisinde bir üye metot gibi deklare edilir fakat tanımlanmaz. Dönüş değeri void olmalıdır. Sinyal ve slot’ları kullanabilmek için sınıfınız, öncelikle QObject sınıfından türetilmeli ve içerisinde Q_OBJECT makrosu eklenmelidir (Peki neden? Başlığın başında bahsetmiştik).  Ayrıca sınıf içerisindeki sinyaller “signals:” satırından sonra deklare edilmesi gerekmektedir (merak edenler için “signal” anahtar kelimesi aslında bir makro ve karşılığı “public”). moc bu ibarelere göre gerekli kod oluşturmalarını gerçekleştirir (bu sinyale ilişkin örneğin tanımlama otomatik olarak üretilir). Çoğu QT görsel bileşenleri bu sinyalleri barındırmaktadır. Peki bu sinyali nasıl tetikleyeceğiz. Bu amaçla “emit” anahtar kelimesi kullanılmalıdır (peki emit in karşılığı nedir? Aslında bakarsanız hiç bir şey, sadece okunabilirliği arttırmak için eklenmiştir). Hemen örnek bir sinyal deklarasyonuna ve tetiklenmesine bakalım:

Slotlara tekrar bakacak olursak, aslında bunları üye metot tanımlamalarından bir farkları olmadığını ve sinyallerin yönlendirildiği metotlar olduğundan bahsetmiştir. Tabi slot’lar sadece üye metotlar olmak zorunda değiller, lambda, bağımsız fonksiyon ve fonksiyon nesneleri olabilirler. Sinyallere benzer şekilde slot’lar kullanmak isteyen sınıflar QObject sınıfından türetilmesi ve Q_OBJECT makrosunu içermelidir. Sinyallerin sınıf görünürlüğü her zaman “public” olsa da, slot’lar “public/protected/private” olabilir. Hemen örnek bir koda bakalım:

Sinyalleri ve slotları tanımladık, peki bunları nasıl bağlayacağız. Hemen ona da bakalım. Bu amaçla, QObject sınıfından edindiğimiz connect() API’si kullanılır. Bu API’ye sıra ile, gönderen nesnenin kendisi, ilgili sinyal tanımlamasının işaretçisi, alacak nesne ve slot fonksiyonunun işaretçisi geçirilir.

Bu şekilde aynı sinyali birden fazla slot’a ya da birden fazla sinyali de aynı slot’a bağlayabilirsiniz. Daha önce de bahsettiğim gibi nesnelerin yanında lambda ifadeleri de kullanılabilir.

Nesnelerin bağlanması durumunda, herhangi bir nesne silinirse ilgili bağlantı otomatik olarak koparılır.

Bunların yanında:

  • Koparma işlemi disconnect API si ile de aşağıdaki gibi de yapılabilir,
  • Bir sinyal başka bir sınıfın sinyaline yukarıdaki connect API si ile bağlanabilir,
  • Yukarıdaki bağlantı tipi el ile belirlenebilir. Bu amaçla  Qt::ConnectionType kullanılır,
  • Yukarıda verdiğimiz bağlamanın yanında Qt5’den önce de kullanılan ve makrolara dayalı bir bağlama yöntemi de vardı. Fakat, yeni sistem gibi derleme zamanında bazı kontroller/tip kontrolleri gerçekleştirilmiyor. Ama bazı durumlar için de, QML ile bağlama, bu kullanım gerekebiliyormuş. Yukarıdaki kullanımın karşılığı aşağıdaki gibi oluyor:

  • Bu kullanımlara ilişkin bilgi için http://doc.qt.io/qt-5/signalsandslots-syntaxes.html adresine bakabilirsiniz.

.ui dosyaları

Bu uzantıya sahip dosyalar, Qt Designer tarafından kullanılmakta ve tasarlanan grafiksel kullanıcı arayüzünü XML formatında ifade etmek için kullanılmaktadır. Yüksek ihtimal ile bu dosyalar ile hiç işiniz olmayacak ama ne olduğunu bilmekte fayda var. Daha detaylı bilgi ve örnek .ui dosyası için https://doc.qt.io/qt-5/designer-ui-file-format.html adresine bir göz atabilirsiniz.

QML

4.7 sürümü ile birlikte WPF ve benzeri GKA uygulamaları geliştirenlerin hemen hatırlayacağı xaml benzeri QML modülü ve bildirimsel dili (“declarative language“) eklendi. Bu dil sayesinde, artık grafiksel kullanıcı arayüzleri, bunların etkileşimi, QT’nin sunduğu alt yapılar ve tasarım araçları sayesinde kolay bir şekilde tanımlanabilmektedir. Burada ayrıca Javascript desteğinin de eklendiğinden bahsetmekte fayda var. Açık konuşmak gerekirse profesyonel hayatımda henüz bunu hiç kullanmadım ama örnek uygulamalarımızın bir kısmını bu dil ile geliştirmeyi planlıyorum. Ayrıca buradaki bileşenler, arka planda C++ kütüphaneleriniz ile de desteklenebilmekte. Daha detaylı bilgi için QML uygulamaları sayfasına bir göz atabilirsiniz.

Kütüphaneler ve API’ler

QT kütüphane ve kabiliyetleri belirli bir mantığa göre sınıflandırmakta. Bunlardan ilk grubu “Qt Essentials” olarak adlandırmakta. Bunlar bütün platformlar için sunulan ve kullanılabilecek olan kabiliyetleri temsil etmekte. Bunların yanında özel amaçlar için geliştirilmiş olan “Add-On Module” olarak adlandırılan modüller olabilmekte. Şimdi bunlara bir bakalım:

Temel kütüphaneler şu şekilde:

Qt CoreGrafiksel olmayan ve diğer kütüphaneler tarafından da kullanılan sınıflar (sinyal/slot, qobject, threading, File I/O, vb).
Qt GUIOpenGL de dahil olmak üzere bütün grafiksel kullanıcı arayüzlerine ilişkin kabiliyetleri barındırır.
Qt MultimediaSes, video ve kamera gibi multimedya kabiliyetleri
Qt Multimedia WidgetsMultimedya kabiliyetleri için sunulan görsel bileşenler
Qt NetworkAğ programlama ile ilgili bileşenler
Qt QMLQML ve JavaScript dillerine ilişkin sınıflar
Qt QuickBetimsel bir şekilde GKA tabanlı uygulama geliştirme için kullanılabilecek arayüzler
Qt Quick ControlsQML bileşenleri
Qt Quick DialogsQML diyalogları
Qt Quick LayoutsQML bileşenlerinin düzenlemek için kullanılabilecek yerleşim kabiliyetleri
Qt Quick TestQML uygulamaları için birim test kabiliyetleri
Qt SQLSQL tabanlı veri tabanı entegrasyonu için ihtiyaç duyulacak kabilyetler
Qt TestQT uygulamaları için birim test kabiliyetleri
Qt WidgetsQT GUI yi kullanan görsel bileşen kütüphanesi.

“Add-on” modüller ise aşağıdaki gibi. Bunlara ilişkin detaylı bilgilere ilgili bağlantılardan ulaşabilirsiniz.

Modül İsmiGeliştirme PlatformuDesteklenen Hedef Platformlar
Active QtWindowsWindows
Qt 3DHepsiHepsi
Qt Android ExtrasHepsiAndroid
Qt BluetoothHepsiAndroidiOSLinuxmacOS, and WinRT (*)
Qt ConcurrentHepsiHepsi (*)
Qt D-BusHepsiHepsi (*)
Qt GamepadHepsiVeroidiOSmacOS, tvOS, LinuxWindows, ve QNX
Qt Graphical EffectsHepsiHepsi
Qt HelpHepsiHepsi (*)
Qt Image FormatsHepsiHepsi
Qt LocationHepsiHepsi
Qt Mac ExtrasHepsimacOS
Qt NFCHepsiVeroid ve Linux (*)
Qt OpenGL(Deprecated)HepsiHepsi (*)
Qt Platform HeadersQt for WindowsLinuxmacOSQt for WindowsLinuxmacOSVeroid (*)
Qt PositioningHepsiVeroidiOSmacOSLinuxWinRT (*).
Qt Print SupportHepsiHepsi (*)
Qt PurchasingHepsiVeroidiOS, ve macOS.
Qt Quick Controls 1(Deprecated)HepsiHepsi (*)
Qt Quick ExtrasHepsiHepsi (*)
Qt Quick WidgetsHepsiHepsi (*)
Qt Remote ObjectsHepsiHepsi
Qt Script(Deprecated)HepsiHepsi
Qt SCXMLHepsiHepsi
Qt Script Tools(Deprecated)HepsiHepsi (*)
Qt SensorsHepsiVeroidQt for iOSWinRT, Mer, ve QNX.
Qt Serial BusHepsiWindowsLinuxBoot to Qttargets, ve QNX.
Qt Serial PortHepsiWindowsLinuxmacOS, ve QNX.
Qt SpeechHepsiHepsi QNX hariç.
Qt SVGHepsiHepsi
Qt UI ToolsHepsiHepsi (*)
Qt WebChannelHepsiHepsi
Qt WebEngineHepsiWindowsLinux, ve macOS.
Qt WebSocketsHepsiHepsi
Qt WebViewHepsiWeb motoru desteği sunan platformlar.
Qt Windows ExtrasHepsiWindows
Qt X11 ExtrasHepsiLinux/X11
Qt XMLHepsiHepsi (*)
Qt XML Patterns(deprecated)HepsiHepsi
Qt Waylve CompositorLinuxLinux ve Boot to Qt.
Sadece ticari lisans ya da GPL v3 kapsamında desteklenen eklentiler
Qt ChartsHepsiHepsi
Qt Data VisualizationHepsiHepsi
Qt Network AuthorizationHepsiHepsi
Qt Virtual KeyboardHepsiLinux ve Windowsdesktop, ve Boot to Qttargets.
Qt Quick WebGLHepsiWebGL-destekli tarayıcılar

Araçlar

Gelelim QT ile birlikte haşır neşir olacağınız araçlara. Tabi bunların bir kaçını da kullanarak QT uygulaması geliştirebilirsiniz, ama bunların da farkında olmakta fayda var. Şimdi kısa kısa bütün araçlara bir göz atalım. Bu araçları çevrim içi kurulum uygulaması ile kurabileceğiniz gibi, https://download.qt.io/official_releases/ adresinden tek tek de indirerek kurabilirsiniz.

Creator IDE: Çoklu platformda kullanılabilen entegre geliştirme ortamı (IDE). Bu sayede üçüncü parti bir uygulama ya da IDE’ye ihtiyaç duymadan C++ ve QML kullanarak farklı platformlar için QT uygulamaları geliştirebiliyorsunuz.

Designer: İsminden de anlaşılacağı üzere Widget kütüphanelerini kullanarak QT kullanarak grafiksel kullanıcı arayüzü hazırlamaya olanak sağlayan araçtır. Hazırlamanın yanında, farklı çözünürlük ve stiller için de nasıl göründüğünü görebilirsiniz.

Linguest: Uygulamalarınıza çoklu dil desteği eklemek için kullanabileceğiniz araç seti. Bu set içerisinde lupdate ve lrelease tarzı alt araçlar mevcut. Ayrıca bu araçlar Qt Creator IDE altından da çağrılabilmekte.

Assistant: Yukarıda da bahsettiğim üzere, QT dokümantasyonuna ulaşabileceğiniz uygulama.

qmake: Makefile benzeri çoklu platform için kullanabileceğiniz, yazılım oluşturma aracıdır. Bu arada QT CMake ve diğer benzeri araçları da desteklemekte.

Bunların yanında bilindik IDE’ler için de pluginler de sunulmakta. Bunlardan Visual Studio için olana yazımda kısaca değineceğim.

Bunlarında yanında daha bir kaç araç daha mevcut ama en sık kullanacaklarınız bunlar. Diğerleri için QT dokümantasyonuna başvurabilirsiniz.

Kurulum

Gelelim kısaca QT’yi nasıl kurabileceğinize. Bunun bir kaç yöntemi var ve ben burada iki yönteminden bahsedeceğim. Bunlar Windows işletim sistemi içindir (diğer platformlar için https://doc.qt.io/qt-5/gettingstarted.html adresine göz atabilirsiniz). Birincisi, ilgili aracın sitesinde kurulum dosyasını indirerek olacak ki ilk kullanım için bunu öneriyorum. Ya da daha önce Vcpkg yazımda bahsettiğim aracı kullanarak.

Şimdi gelelim ilk yönteme. Bu yöntemde, indirilen kurulum uygulamasını kullanıyor olacağız. Ekran çok karmaşık olmadığı sürece, işlemleri adım adım yazacağım. Gerekli olduğunu düşündüğüm kısımlarda ise ekran görüntülerini sizler ile paylaşacağım:

  1. https://www.qt.io/download adresine gidiyoruz,
  2. Burada kullanacağımız lisansı seçiyoruz ki, bizim durumumuzda “Open Source” olacak. Bunun için sayfanın sağ altında bulunan “Go Open Source” düğmesine tıklıyoruz,
  3. Daha sonra burada çevrim içi kurulum dosyasını mı yoksa el ile kurulum dosyalarını mı kullanacağımızı seçiyoruz. İlki için “Download” düğmesini tıklayarak “qt-unified-windows-x86-3.1.1-online.exe” dosyasını indiriyoruz (sürüm sizlerde farklı olabilir). İkinci seçenek için ise (özellikle kapalı ağda çalışanlar ya da internet erişimi olmayan bir bilgisayara kurulum yapacaklar için kullanışlı) https://www.qt.io/offline-installers ya da http://download.qt.io/archive/qt/ adreslerine giderek ihtiyaç duyduğunuz bileşenlere ilişkin kurulum dosyalarını indirebilirsiniz,
  4. Çevrim içi kuruluma devam etmek için “qt-unified-windows-x86-3.1.1-online.exe” kurulum dosyasına çift tıklıyoruz,
  5. İlk gelen pencerede “Welcome to the Qt online installer”, “Next” düğmesine basıyoruz,
  6. Sonra gelen “Qt Setup” penceresinde ise henüz hesap oluşturmadı iseniz hesap oluşturup, var ise ilgili bilgileri girip, sonraki karşılama ekranında da “Next” düğmesine tıklıyoruz,
  7. “Installation Folder” kısmında QT’nin kurulacağı dizini seçiyoruz. Bunu olabildiğince basit ve içerisinde boşluk bulundurmayan bir dizin seçmenizde fayda var,
  8. İşte şimdi geldik önemli bir pencereye. Neleri kuracağız? İlk etapta 5.13 sürümünü MSVC 2017 ve android bileşenlerini seçmenizi tavsiye ediyorum. Ayrıca Qt Creator ve 3D Designer’ı da eklemeniz iyi olacaktır. Sol taraftaki LTS, “Long Term Support” anlamına gelmekte ve uzun süreli destek verilecek olan sürümü ifade ediyor. Bir diğer ifade ile ticari uygulamalarınızda tercih edeceğiniz sürümler bunlar olmalı. Bunları seçtikten sonra “Next” düğmesine basarak, öncelikle var ise lisans sözleşmelerine okudum ve kabul ettiğim deyip, Başlangıç menülerine ekleme bilgisi pencerelerinde yine “Next” düğmelerine basıp, son “Install” düğmesi ile indirme ve kurulum işlemini başlatabilirsiniz.
  9.  
  10.  Şimdi kurulumun yapıldığı dizine gidelim. Burada ilgili Qt sürümlerine ilişkin dizinleri ve ortak kullanılan dosyaları göreceksiniz. Benim (eski sürüm) için görüntü aşağıdaki gibi.
  11. Şimdi 5.x.x dizinlerine girelim. Bendeki görüntü aşağıdaki gibi:
  12. Buradan QT’nin ilgili sürümünün (5.12.3), ilgili platforma (msvc2017 x86) ilişkin ye ilişkin bütün dosyalarına ulaşabilirsiniz. El ile VS ayarları yapmanız durumunda nereye geleceğiniz gördünüz. Gerçi VS plugin’ini kurduğunuzda bunlar ile uğraşmanıza gerek kalmayacak.
  13. Dikkatinizi çekmek istediğim son dizin de “plugins/platforms” dizini. Bu dizini, hazırladığını QT uygulamaları ile birlikte sağlamanız gerekiyor (tabi ilgili bilgisayarda QT kurulu değil ise).
  14. Şimdi QT’yi kurduktan sonra VS entegrasyonu için son bir adımımız daha var o da “VS addin”‘ini kurmak. Bunun için https://download.qt.io/official_releases/vsaddin/ sayfasına gidiyoruz ve son sürümün olduğu dizine (bu yazıyı yazdığımda 2.3.4. idi) giriyoruz,
  15. qt-vsaddin-msvc2019-2.3.4.vsix dosyasını tıklayarak indiriyoruz. Bu bir VS eklentisi.
  16. VS’i kapatıyoruz ve ilgili .vsiz uzantılı dosyaya çift tıklayarak kurulumu tamamlıyoruz. Artık VS ile QT uygulaması geliştirmek için her şey hazır.

Şimdi gelelim Vcpkg ile ilgili kurulum gerçekleştirilmesine. Bu adımlara geçmeden önce, bilgilerinizi tazelemek için aşağıdaki yazıya göz atabilirsiniz.

Vcpkg Aracı

Yukarıdaki yazımda bahsedilen şekilde vcpkg aracını çalıştırır hale getirdikten sonra “vcpkg search qt5” diyerek, mevcut qt kütüphanelerini görebilirsiniz. Ben bu komutu çağırdığımda aşağıdaki listeyi gördüm:

Göreceğiniz üzere sürümler biraz geriden geliyor, fakat ilk yönteme göre daha hızlı kurulum yapabilirsiniz. Kurulum ve VS ile entegrasyon için ilgili yazımdaki adımları takip edebilirsiniz.

Kaynaklar

  • https://www.wikiwand.com/en/Qt_(software)
  • https://wiki.qt.io/About_Qt
  • https://www.youtube.com/watch?v=YWiAUUblD34
  • https://www.qt.io/licensing/
  • https://download.qt.io/official_releases/
  • https://doc.qt.io/qt-5/properties.html
  • https://doc.qt.io/qt-5/gettingstarted.html
  • https://doc.qt.io/qt-5/metaobjects.html
  • https://doc.qt.io/qt-5/moc.html
  • https://wiki.qt.io/Books
  • https://www.cleanqt.io
  • https://wiki.qt.io/Threads_Events_QObjects#Events_and_the_event_loop
  • https://www.q7basic.org/Qt%20Designer.pdf
  • https://www.kdab.com/expertise/qt/
  • https://doc.qt.io/qt-5/overviews-main.html#
  • https://forum.qt.io/topic/22992/qt-yi-merak-edenlere-neden-qt

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.