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


Rispondi

Il contenuto di questo campo è privato e non verrà mostrato pubblicamente.
  • Linee e paragrafi vanno a capo automaticamente.
Maggiori informazioni sulle opzioni di formattazione.