GUI Programlama için Sinyaller + Yuvalar modeline pratik bir alternatif var mı?


9

GUI Toolkit'lerin çoğu günümüzde Signals + Slots modelini kullanıyor. Qt ve GTK + idi, eğer yanılmıyorsam, ona öncülük etti.

Widget'lar veya grafiksel nesneler (bazen görüntülenmeyenler bile) ana döngü işleyicisine sinyal gönderir . Ana döngü işleyici daha sonra o widget / grafik nesnesi için atanan olayları , geri çağrıları veya yuvaları çağırır . virtualÖnceden tanımlanmış tüm sinyalleri işlemek için araç seti tarafından önceden sağlanan varsayılan (ve çoğu durumda ) olay işleyicileri vardır, bu nedenle, geliştiricinin her bir mesajın tüm ana döngüsünü ve işleyicisini kendisi yazmak zorunda olduğu önceki tasarımların aksine (WINAPI'yi düşünün), geliştirici sadece yeni işlevsellik uygulamak için ihtiyaç duyduğu sinyaller hakkında endişelenmelidir.

Şimdi bu tasarım bildiğim kadarıyla çoğu modern araç setinde kullanılıyor. Qt, GTK +, FLTK vb. Var. Java Swing var. C # bile bunun için bir dil özelliğine sahiptir (etkinlikler ve delegeler) ve Windows Forms bu tasarımda geliştirilmiştir. Aslında, son on yılda, GUI programlama için bu tasarım bir tür yazılı olmayan bir standart haline geldi. Verimliliği arttırdığı ve daha fazla soyutlama sağladığı için.

Ancak sorum şu:

Modern GUI programlama için paralel veya pratik herhangi bir alternatif tasarım var mı?

Yani Signals + Slots tasarımı, şehirdeki tek pratik tasarım mı? GUI Programlama'yı başka herhangi bir tasarımla yapmak mümkün müdür ? Alternatif bir tasarım üzerine inşa edilmiş modern (tercihen başarılı ve popüler) GUI araç kitleri var mı?


Windows API'sında bulduğunuz ileti kuyruğu paradigması, etkinlikler ve temsilciler gibi değildir . Delegeler, eşzamansız ve hemen çağrılır, örneğin std::function, eşzamansız bir sinyal olarak değil . Buna ek olarak, WinAPI gelmez sağlamak DefWindowProcvarsayılan uygulama olarak, Windows mesajları işler hangi. Bu yüzden sorunuzun hatalı mantığa dayandığını söyleyeceğim.
DeadMG

2
QT ve GTK +, olay odaklı bir yaklaşım kullanan ilk GUI çerçevelerini oluşturmaktan uzaktır. Konsept, Smalltalk-80'e ( en.wikipedia.org/wiki/Smalltalk ) kadar uzanır .
Doc Brown

İlginç bir soru, bu modelin çoklu dokunmatik arayüzlerle çok değişip değişmediğini merak ediyorum.
Ben DeMott

Cömert olurum ve sadece PostMessage değil, senkronize olan SendMessage'ı bildiğini varsayalım. Ancak, her mesaj için asla mesaj işleme döngüsünün tamamını yazmak zorunda olmadığınız için hala yanlıştır.
gbjbaanb

JavaFx, Bindings API'leri aracılığıyla benzer bir mekanizma sağlar.
Müh.Foad

Yanıtlar:



5

Bu benim en sevdiğim bir konu ve yaklaşık on yıl boyunca ('70'lerden '86'ya) olaylara yanıt veren nesnelerden oluşan bir GUI'ye sahip olmanın bunu yapmanın doğru yolu olduğunu düşündüm.

Sonra bunu yapmak için başka bir yol üzerinde tökezledi Burada anlatılan ve bir sourceforge proje ile burada .

Özetle, nesnelerle ilgili sorun devam etmeleridir ve bunları oluşturmak için kod yazarsanız, değişiklik gerekiyorsa bunları kademeli olarak değiştirmek için kod yazmanız ve bir şekilde bunlardan mesaj almanız gerekir. İstediğinizi boyayabilir ve farklı bir şey istiyorsanız yeniden boyayabilir ve önceki nesnelerin sürekliliği konusunda endişelenmenize gerek kalmaz mı? İleti işlemek için kod yazmak zorunda kalmazsanız da hoş olmaz mıydı, çünkü hepsi başlık altında yapılır?

Bu paket böyle yapar. Basit iletişim kutuları için kodda bir büyüklük sırası kaydeder. Dinamik olarak değişen diyaloglar için bunları mümkün kılar.

PS: Bunu web tarayıcısı kullanıcı arayüzleri için değil, yalnızca masaüstü arayüzleri ve uzak terminal arayüzleri için yaptım. Eminim mümkün, ama deneme şansım olmadı.


+1, Ancak kullanıcı tanımlı girdi gibi ekstra işlevsellik elde etmek nasıl mümkün olabilir?
ApprenticeHacker

@IntermediateHacker: Kullanıcı tanımlı girdi ile ne demek istediğinizden emin değilim. Form tasarımcı uygulamasına sahip olmak mı demek istediniz?
Mike Dunlavey

2

Bununla ilgili iki farklı yol var:

  1. Her widget'in ayrıntılı bir abone mekanizmasını (Sinyal / Yuva, Gözlemci / Gözlemlenebilir, Olay / Temsilci) göstermesini ve müşteri koduna abone olmasını ve buna göre işlem yapmasını sağlayın.
  2. Sunulan verilerin bir soyutlamasına karşı bir widget oluşturdu ve istemci kodunun bu soyutlamayı uygulamasını sağlayın.

İkinci yaklaşım için bir örnek:

interface Action {
     void execute();
     Bool isEnabled();
     Null<String> description();//used for tooltip
}
interface LabledAction extends Action {
     String getName();
}

Ve şimdi bir LabelButtonkarşı oluşturabilirsiniz LabledActionve istemci kodu sadece uygulayabilir veya varsa ve uygunsa, bazı genel varsayılan uygulama kullanabilirsiniz.

Bir bakıma, ikinci yaklaşım daha az esnek ancak daha katıdır. Bir şekilde göreceli olarak atomik yöntemlerle görünümü modelle birleştirmiyorsunuz. Gereksinimlerinize göre uygun bir GUI tasarlar ve ardından bu GUI ile etki alanı / uygulama mantığınız arasındaki bağdaştırıcıları uygularsınız.


Model / Görünüm / Denetleyici iyidir, ancak bu sadece gözlemci modelinin bir uzantısıdır, çünkü denetleyici kısmı widget'ın bir gözlemcisidir ve model kısmında widget modelin gözlemcisidir, bu yüzden başka bir şekilde aynı mekanizmadır .
Jan Hudec

1

Birkaç kontrol tipi sistem bir veritabanı yaklaşımı kullanır - her gui kontrolü veritabanında bir dosyaya bağlanır, böylece Gui her zaman veritabanı durumunu yansıtır. DB kancaları, bir değer değiştiğinde işlevleri tetiklemek için kullanılır.


4
bu hala fazladan bir DB katmanıyla sinyal yuvası değil mi?
cırcır ucube

Sonuçta tüm kesintiler veya geri aramalar altında - bunlar sadece düşük seviye asenkron işlemler
Martin Beckett
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.