Applicazioni multipiattaforma 100% GUI-Indipendent

|

Può capitare di dover realizzare programmi che siano utilizzabili con diverse interfacce grafiche, in Ruby ci sono diversi stratagemmi per farlo e al primo posto troviamo i blocchi, ecco un programmino d'esempio che funzione da gtk o console.

L'idea di base è che tutti i controlli dati vengono fatti dalla classe interna, mentre le interfacce si limitino solo a fare input/output; probabilmente questo approccio non va bene in tutti i casi, ma se si usano pochi semplici widget fa la sua bella figura.

Ho deciso di usare i metodi "error" e "notify", per semplicità, ma si sarebbero potute utilizzare anche le eccezioni; stesso discorso per l'alert. Gtk::Dialog sarebbe il widget giusto, ma rischierebbe di creare confusione.

Si esegue con:

ruby esempio.rb (Console) o ruby esempio.rb --gtk (Gtk)



#!/usr/bin/ruby
=begin
 == esempio.rb ==
 Una semplice implementazione di oggetti indipendenti dall'interfaccia grafica/console
 oOo. http://assente.altervista.org .oOo
=end

# Oggetto principale GUI-indipendent
class List
    def initialize()
        @a=[]
    end
    def add(value)
        # vari controlli sull'input
        if value==""
            error("Valore nullo")
        elsif value=~/[a-zA-Z]/
            error("Le lettere non sono ammesse")
        elsif value=~/[0-9]/
            @a << value
            notify("'#{value}' inserito")
        end
    end
    # yield viene sostituito con quello che passiamo a livello superiore,
    # puts oppure @display.text+=, fantastico, no?
    def show_all
        @a.each { |value| yield value}
    end
end

class ConsoleList < List
    def initialize
        super
        puts "Console mode"
        while true
            puts "1: Aggiungi 2: Visualizza 3: Esci"
            # toglie \n dall'input da terminale
            choice=gets.strip
            case (choice)
                when "1" then add
                when "2" then show_all
                when "3" then exit
            else
                error("Scelta non valida")                
            end        
        end
    end
    def add
        puts "Inserisci: "
        # manda al metodo List#add vedi su
        super(gets.strip)
    end
    # Richiamato da List
    def error(text)
        puts "!! #{text} !!"
    end
    def notify(text)
        puts ">> #{text}"    
    end
    def show_all
        super{|v| puts "|#{v}|"}
    end
end

class GtkList < List
    require 'gtk2'
    def initialize
        super
        puts "GUI mode"
        
        Gtk.init    
        
        #Inizializzo i widget
        @window=Gtk::Window.new
        @container=Gtk::VBox.new
        @entry=Gtk::Entry.new
        @display=Gtk::Label.new
        @button=Gtk::Button.new("Inserisci")
        
        #Assegno gli eventi
        @button.signal_connect("clicked"){add}
        @entry.signal_connect("activate"){add}
        @window.signal_connect("destroy"){exit}
        
        #impacchetto
        @container.add(@display).add(@entry).add(@display).add(@display).add(@button)
        @window.add(@container)
        
        @window.show_all
        
        Gtk.main
    end
    def add
        puts "Inserisci: "
        super(@entry.text)
        @entry.text=""
    end
    def error(text)
        # Con più spazio estendetevi Gtk::Alert :-)
        Gtk::Window.new.add(Gtk::Label.new("#{text}")).show_all
    end
    def notify(text)
        # Non necessario
        #Gtk::Window.new.add(Gtk::Label.new("#{text}")).show_all
        show_all
    end
    def show_all
        @display.text=""
        super{|v| @display.text+=v+" "}
    end
end

# Inizia qui
case(ARGV[0])
    when nil:     ConsoleList.new
    when "--gtk": GtkList.new
end


il Ruby?

non nascondo che questo titolo mi ha un po' preso di sprovvista in quanto il Ruby non era menzionato.

Perchè scegliere Ruby anzichè wxWidgets in diverse configurazioni? (C++, Python o JavaScript)

Perchè non sviluppare un confronto in questo senso ed aggiungere altre proposte che possono esserci?

=)

Ruby

ruby perche` e` sintatticamente stupendo e ad oggetti.
Certo le stesse cose si possono fare anche in diversi linguaggi e con diversi toolkit grafici, ma sarebbe una cosa ovvia.. ognuno sceglie quel che piu' gli piace.