Qt-GUIs mit Ruby

Wer hat nicht manchmal das Bedürfnis (oder auch einfach, und vielleicht wahrscheinlicher, die Anforderung) schnell mal eine schöne, plattformunabhängige GUI für eines seiner neuen Programme herzustellen? Man muss sich schon klar darüber sein, dass man selbst zwar vielleicht gar kein Verlangen nach einer grafischen Oberfläche hat, z.B. weil man erkannt hat, dass man unglaublich viel Zeit sparen kann und zu (zumindest für sich selbst) brauchbaran Programm kommt, wenn man sich auf den Kern seiner Anwendung konzentriert und sich wenig Gedanken über die Benutzeroberfläche macht. Man kann natürlich nicht nur Zeit sparen, sondern man kann sich einfach auch ans Kommandos schreiben gewöhnt haben und gar nicht verstehen, warum man jetzt dafür eine GUI braucht. Allerdings benutzen viele Leute Software nur, wenn sie eine GUI hat. Schlimmer noch: Manche meinen, „das kann gar kein richtiges Programm sein, wenn es keine GUI hat“..

Nunja: Genug der (wertenden) Vorworte, man kann aus vielen Gründen an den Punkt kommt, an dem man eine GUI braucht, und dann will man keine Zeit verschwenden und dafür soll dieser Guide sein: Schnell eine „einfache“ GUI für ein „einfaches“ Programm machen (d.h. zusammenklicken) mit der eigentlichen Logik verknüpfen, ausführbar machen, verteilen und Ruhm & Ehre einfahren.

A) Benötigte Programme installieren:

  • Bei RubyInstaller holt man sich die aktuelle Ruby 1.8.7 Version und das DevKit. Ruby installiert man irgendwohin (wir nehmen hier an, das sei in c:ruby187). Den DevKit entpackt man irgendwohin (hier: c:rubydevkit).
  • Nun öffnet man eine CMD-Box als Administrator und installiert Qt und ocragem install -r rubyqt4 ocra
  • Es kann dabei sein, dass die Qt Installation fehlschlägt, weil eine native Erweiterung während der Installation erzeugt werden soll und dafür scheinbar benötigte Bibliotheken fehlen (das kommt seltsamerweise nicht immer vor, das gem-Programm scheint sich unter unterschiedlichen Bedingungen unterschiedliche Pakete zu holen – wenn jemand weiß, warum, bitte mir sagen..)
  • Naja und das wars eigentlich schon: Weil die RubyGems-Leute so cool sein, ist jetzt wirklich schon alles da, was man zum GUI machen braucht..

B) GUI erzeugen

  • Unter „<ruby-install-dir>librubygems1.8gemsqtruby4-2.1.0-x86-mswin32bin“ finden sich die Qt-Tools zum Weitermachen: Dort die „designer.exe“ öffnen und es wird sich der Qt-Designer öffnen. Bei dessen Start wird man gefragt werden, welche Art von „Form“ man gerne erzeugen würde (für ein Hauptfenster wählen wir „Main Window“ aus und wählen „Create“. Der Rest ist eigentlich selbsterklärend: Rechts im Programmfenster findet sich eine Leiste mit verschiedenen GUI-Bestandteilen, die man auf seinem „Main Window“ unterbringen kann, wie auch immer es Sinn macht.
  • Wenn man fertig ist, wählt man „File > SaveAs“ und speichert seine GUI als ui-Datei, also einer XML-Version der GUI, die beschreibt welche GUI-Bestandteile wo sein sollen.
  • Diese ui-Datei kann man auf zweierlei Arten in sein Ruby-Programm einbinden:
    • „Dynamisch“: Hierbei wird (einfach gesagt) aus der ui-Datei mit einem Qt::UiLoader-Objekt zur Laufzeit des Programms eine GUI erzeugt, d.h. die in der ui-Datei beschriebenen Bestandteile werden erzeugt und entsprechend positioniert. Eine einfache Variante sieht dann ungefähr so aus:
      [sourcecode language=“ruby“]
      require ‚rubygems‘
      require ‚Qt4‘
      require ‚qtuitools‘

      class MyApp < Qt::Application
      def initialize()
      super(ARGV)
      file = Qt::File.new(‚gui.ui‘)
      file.open(Qt::File::ReadOnly)

      loader = Qt::UiLoader.new
      window = loader.load(file, nil)
      file.close
      if (window.nil?)
      print "Error. Window is nil.n"
      exit
      end
      window.show
      end
      end
      def run_dynamic()
      a = MyApp.new
      a.exec
      end
      [/sourcecode]
      Über [sourcecode language=“ruby“]Qt::Application#findChild(…)[/sourcecode] kann man dabei auf einzelne GUI-Bestandteile zugreifen, etwa um EventHandler zu registrieren.

    • „Statisch“: Hierbei wird bevor das Programm läuft mit dem (wieder im „<ruby-install-dir>librubygems1.8gemsqtruby4-2.1.0-x86-mswin32bin“-Ordner befindlichen) „rbuic4“-Tool aus der ui-Datei eine Ruby-Quelle generiert, die dann im Programm eingebunden wird. Das passiert mit: rbuic4 gui.ui -o ui_gui.rb Die erzeugte ui_gui.rb-Datei wird dann wir gewohnt im Ruby-Skript „required“ und die enthaltenen Objekte können ganz normal verwendet werden:
      [sourcecode language=“ruby“]
      require ‚rubygems‘
      require ‚Qt4‘
      require ‚ui_gui.rb’&nbsp;

      class AForm &lt; Qt::MainWindow
      slots ‚button_clicked()‘

      def initialize(parent = nil)
      super(parent)
      @ui = Ui_Gui.new
      @ui.setupUi(self)
      @ui.spinBox.setMinimum(1)
      @ui.spinBox.setMaximum(20)
      Qt::Object.connect(@ui.pushButton, SIGNAL(‚clicked()‘), self, SLOT(‚button_clicked()‘))
      end

      def button_clicked()
      puts "button_clicked executed.."
      end
      end

      def run_precompiled()
      app = Qt::Application.new(ARGV)
      f = AForm.new
      f.show
      app.exec
      end
      [/sourcecode]

  • Wie auch immer man die Qt-UI einbindet, am Ende treffen sich die Wege wieder, wenn man eine exe erzeugen will. Das ist auch wieder super-einfach mit dem Rubytool ocra. Dazu muss man nämlich nur aufrufen: ocra myform.rb Daraufhin wird ocra das Skript scheinbar ganz normal ausführen, um beim Beenden alles zusammenzusuchen, was das Skript so zum Laufen gebraucht hat und es alles in eine exe reinpackt (diese kann dann schon mal gut 20MB groß sein, weil eben die kompletten Qt-Bibliotheken direkt reinkopiert werden..). Damit die (für viele) nervige DOS-Box wegzukriegen, muss man entweder das flag -window beim Aufruf von ocra angeben ocra -window myform.rb oder sein Skript nicht als *.rb sondern als *.rbw speichern.

HTH!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.