Bir GNU/Linux uygulaması oluşturmak istiyorsunuz ancak nerenden başlayacağınızı bilemiyor musunuz? Biz buradayız! 🤚 Bu rehberin size basit GNU/Linux uygulamaları oluşturmanıza yardım edeceğini umuyoruz. Bu rehberin amacı ilk uygulamanızı hızlı bir şekilde ayarlayıp çalıştırabilmeniz için temel kod örnekleri ile bazı genel şeyleri nasıl yapacağınızı açıklamaktır.

Elbette ki, direk olarak resmi belgelere başvurmak isteyebilirsiniz. Ancak bunları nasıl yapacağınıza dair bir ön anlayış olmadan direk olarak resmi belgelere başvurmanın sonucunda zorlanabilirsiniz. Buradaki kod örnekleri inşallah yardımcı olur.
Ön koşullar:
- Temel düzeyde Python bilgisi, sınıflar hakkında bilgi sahibi olmanız önerilir.
- PyGObject'in kurulu olması - Ubuntu, Arch
- Libadwaita'nın kurulu olması - Ubuntu, Arch
- GTK 4'ün yüklü olması gerekir - Ubuntu, Arch
İlk uygulamamızın kaynak kodları
# PyGObject'i programa dahil edelim.
import gi
# GTK sürümünü tanımlayıp programa dahil edelim.
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk
def on_activate(app):
# Bir pencere oluşturalım ve...
win = Gtk.ApplicationWindow(application=app)
# ...pencereyi açalım
win.present()
# Uygulamamızın ID'sini tanımlayalım
app = Gtk.Application(application_id='net.teteos.example')
# Çalıştırıldığında yollanacak sinyali gönderelim. Üsteki kod bu sinyali alıp çalıştıracak.
app.connect('activate', on_activate)
# Uygulamamızı çalıştıralım.
app.run(None)
Bu kodu çalıştırdığımızda karşımıza boş bir pencere gelecek.

Sıradaki adımlarımız (şimdilik):
- Kodu sınıflara dönüştürmek. Çünkü bunu işlevsel tarzda yapmak Python'da biraz garip.
- Libadwaita'ya geçiş yapmak - çoğu modern GNOME uygulaması bu tasarımı kullanıyor. Bunu Win32'den WinUI'a geçiş yapmak gibi düşünebilirsiniz. Gerçi, bunu yapmasak da fena gözükmüyor.
O zaman fazla beklemeden bunu yapalım!
import sys
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1') # <-- Libadwaita'yı işin içine dahil ediyoruz.
from gi.repository import Gtk, Adw
class MainWindow(Gtk.ApplicationWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Verdiğimiz örnekler buraya gelecek.
class MyApp(Adw.Application):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.connect('activate', self.on_activate)
def on_activate(self, app):
self.win = MainWindow(application=app)
self.win.present()
app = MyApp(application_id="net.teteos.example")
app.run(sys.argv)
💡 Şimdikik __init__(self, *args, **kwargs)
konusunu anlamadıysanız endişelenmeyin.
💡 Ciddi bir uygulama için kendi uygulama kimliğinizi düşünmeniz gerekir. Kontrol ettiğiniz bir alan veya sayfanın tersi olmalıdır. Kendi alan adınız yoksa "io.github.kullanıcıadı.uygulamaismi" gibi yapabilirsiniz. En azından ben öyle yapıyorum
Sıradaki adım
Bu pencere hep boş kalacak değil ya! Biraz içini dolduralım o zaman.
Bir yazı ve bir düğme ile işe başlayabiliriz.
Öncelikle öğelerimizi listeleyecek bir widget'a ihtiyacımız var. Bunun için Gtk.Box()
kullanıcağız.
self.main_box = Gtk.Box() # Gtk.Box'ı tanımladık.
self.set_child(self.main_box) # Bunu pencereye ekledik.
Daha sonra "merhaba dünya" yazısını Gtk.Box'ın içine ekleyelim.
self.lbl_hello = Gtk.Label(
label = "Merhaba dünya"
)
self.main_box.append(self.lbl_hello)
Sırada düğmemiz var.
self.btn_hello = Gtk.Button(
label = "Bana tıkla"
)
self.btn_hello.connect(
"clicked",
self.btn_hello_clicked
)
self.main_box.append(self.btn_hello)
def btn_hello_clicked(self, button):
print("Merhaba dünya!")
Ve karşınızda bir yazı ve bir düğme! Ama biraz çirkin duruyorlar.

Bunları alt alta getirmeye ne dersiniz? Eğer benimle aynı fikirdeyseniz kodun şu kısmını aşağıdaki şekilde düzenleyin.
self.main_box = Gtk.Box(
orientation = Gtk.Orientation.VERTICAL
)
İşte oldu!

Şimdi başlık çubuğundaki yazıyı değiştirip varsayılan boyutu ayarlayalım.
self.set_default_size(300, 400)
self.set_title("Merhaba dünya!")

Dur bir dakika! GNOME'da üst çubukta hala "dosyaadi.py" yazıyor?
Bunun için uygulama adını ayarlamamız gerekiyor. Bunun için GLib'i dahil edelim.
from gi.repository import Gtk, Adw, GLib
Daha sonra aşağıdaki kodları programa ekleyelim.
GLib.set_application_name("Merhaba Dünya!")
GLib.set_prgname('Merhaba Dünya!')

(karakter sorunu sistem kaynaklı diye düşünüyorum, Arch GNU/Linux kullanıyorum.)

Başlık çubuğuna düğme ekleme
Öncelikle bir başlık çubuğu oluşturmalıyız.
self.hb = Gtk.HeaderBar()
self.set_titlebar(self.hb) # <-- Bunu başlık çubuğu olarak ayarlayalım
Daha sonra başlık çubuğuna ekleyeceğimiz düğmeyi hazırlayalım.
self.btn_open = Gtk.Button(
label = "Aç"
)
self.btn_open.set_icon_name("document-open-symbolic") # <-- Düğmemize bir simge ayarlıyoruz
self.hb.pack_start(self.btn_open)

Güzel! Peki bu düğmeyi neden bir dosya seçme penceresini açacak şekilde yapılandırmıyoruz?
self.dyl_open = Gtk.FileChooserNative.new(
title = "Bir dosya seçin",
parent = self,
action = Gtk.FileChooserAction.OPEN
) # İletişim kutusunu oluşturduk
self.dyl_open.connect("response", self.open_response) # Açıldığında gönderilecek sinyal
self.btn_open.connect("clicked", self.show_open_dialog) # Düğmeye tıklandığında gönderilecek sinyal
# Dosya yolunu gösterecek yazı
self.lbl_filepath = Gtk.Label()
def open_response(self, dialog, response):
if response == Gtk.ResponseType.ACCEPT:
file = dialog.get_file()
filename = file.get_path() # Dosya yolunu öğrendik
self.lbl_filepath.set_label(filename) # Dosya yolunu gösterecek yazıyı ayarladık
self.main_box.append(self.lbl_filepath) # Bu widget'ı ekledik.
Düğmeye tıklandığında:

Dosyayı seçtiğimizde:

Bunu Gtk.FileChooserAction.SAVE (kaydet) ya da Gtk.FileChooserAction.SELECT_FOLDER (klasör seç) şeklinde yapabilirsiniz.
Başlık çubuğuna hamburger menüsü ekleme
Bunun için aşağıdaki widget'ları kullanacağız.
Menü düğmemize bastığımızda MenuModel ile yapılandırılmış bir Popover yani baloncuk çıkacak. MenuModel'i kullanabilmemiz için Gio'yu programa dahil etmemiz gerekmekte.
from gi.repository import Gtk, Adw, GLib, Gio
Daha sonra yeni bir eylem oluşturalım.
menuAction = Gio.SimpleAction.new("birseyler", None) # Eylemi oluşturduk
menuAction.connect("activate", self.print_something) # Eylem sinyalini ayarladık
self.add_action(menuAction) # Eylemi ekledik
Bunu tetikleyecek düğmeyi oluşturalım.
menu = Gio.Menu.new() # Menüyü ayarladık.
menu.append("Bir şeyler yap!", "win.birseyler") # Düğmeyi menüye ekledik.
Görüntülenecek baloncuğu ayarlayalım.
self.popover = Gtk.PopoverMenu() # Baloncuğu oluşturduk
self.popover.set_menu_model(menu) # Menüyü ekledik
Daha sonra hamburger düğmemizi oluşturalım ve pencerenin sağ tarafına ekleyelim.
self.hamburger = Gtk.MenuButton() # Düğmeyi oluşturduk
self.hamburger.set_popover(self.popover) # Baloncuğu açacak şekilde yapılandırdık
self.hamburger.set_icon_name("open-menu-symbolic") # Güzel bir simge ayarladık
self.hb.pack_end(self.hamburger) # Başlık çubuğunun sağına ekledik.
def print_something(self, action, param):
print("Bir şeyler!")

Haydi uygulamaya biraz çekidüzen verelim
Öğeleri daha önce oluşturduğumuz bir kutu olan main_box
'ın içine yerleştirmiştik. Şimdi bu kutunun içindekileri ortaya sabitleyelim ve aralarında 6 piksel boşluk bırakılmasını sağlayalım.
...
self.main_box = Gtk.Box(
orientation = Gtk.Orientation.VERTICAL,
spacing = 6, # Öğeler arasında boşluk
halign = Gtk.Align.CENTER,
valign = Gtk.Align.CENTER # Öğeleri ortaya sabitledik
)
...

Koyu temayı ayarlayalım. Ayrıntılı bilgi için buraya bakabilirsiniz.
app = self.get_application()
sm = app.get_style_manager()
sm.set_color_scheme(Adw.ColorScheme.PREFER_DARK)

main_box
'a aralık özelliğini verelim. Bu pencereyi iyice küçülttüğümüzde pencere kenarlarına yapışmamasını sağlar. Bunu diğer nesnelerde de kullanabilirsiniz.
self.main_box.set_margin_top(10)
self.main_box.set_margin_bottom(10)
self.main_box.set_margin_start(10)
self.main_box.set_margin_end(10)

💡 Widget'lara göz atmak için libadwaita-demos (veya benzeri isimler) paketini kurup adwaita-1-demo
komutunu çalıştırın.
İşte bitti! Şimdilik bu kadar. Daha sonraki rehberde görüşmek üzere, Allah'a emanet olun.
Yararlanılan kaynak: https://github.com/Taiko2k/GTK4PythonTutorial