Code-Beispiel
gtkcommand - GTK/Glade-Beispiel zum Ausführen von Betriebssystembefehlen
Lizenz: | Erster Autor: | Letzte Bearbeitung: |
GPLv3 | ksiebke | 26.10.2010 |
Dies ist ein kleines GTK/Glade-Beispiel, welches diverse Codeschnipsel enthält, die für andere Entwicklungen verwendet werden können.
U.a. wird gezeigt, wie man einen Betriebssystembefehl absetzt, die ausgebenen Zeilen einliest und diese in einem GTK Textview anzeigt. Ausserdem wird demonstriert, wie man verschiedene Farben und Schriftarten verwendet und eine Codepagewandlung durchgeführt werden kann. Schließlich wird noch gezeigt, wie einfach ein Meldungsdialog mittels GTK realisiert wird.
Hier nun der Programmcode (die ebenfalls benötigte glade-Datei folgt weiter unten):
'******************************************************************************
'* Program name: gtkcommand
'*
'* Version: 1.0
'*
'* Author: Copyright (c) 2010 Klaus Siebke
'* Siebke Unternehmensberatung
'* URL http://www.siebke.com
'*
'* Description:
'* -----------
'*
'* This program executes OS commands and writes the output to a textview
'*
'* Used components:
'* ---------------
'*
'* FreeBasic
'* Gtk
'* glade (for graphical GUI design)
'*
'* As program editor I recommend geany 0.12 or higher with FreeBasic
'* syntax highlighting and compile/run "out of the box"
'*
'*
'* License:
'* -------
'*
'* Program provided under GNU GENERAL PUBLIC LICENSE. Pls. refer to:
'* http://gplv3.fsf.org/
'*
'* Short summary:
'* Permission to use, copy, modify, distribute and sell this software
'* and its documentation for any purpose is hereby granted without fee,
'* provided that the above copyright notice appear in all copies and
'* that both that copyright notice and this permission notice appear
'* in supporting documentation.
'* It is provided "as is" without express or implied warranty.
'*
'******************************************************************************
'* Programmname: gtkcommand
'*
'* Version: 1.0
'*
'* Autor: Copyright (c) 2010 Klaus Siebke
'* Siebke Unternehmensberatung
'* URL http://www.siebke.com
'*
'* Beschreibung:
'* ------------
'*
'* Das Programm führt Betriebssystemkommandos aus und schreibt das Ergebnis
'* in einen Textview
'*
'* Verwendete Komponenten:
'* ----------------------
'*
'* FreeBasis
'* Gtk
'* glade (fuer den grafischen GUI-Entwurf/Erstellung der xml-Datei)
'*
'* Als Editor empfehle ich geany 0.12 oder ein hoeheres Release mit FreeBasic
'* Syntax-Hervorhebung und Kompilieren/Ausfuehren direkt aus dem Editor
'*
'* Lizenz:
'* ------
'*
'* Das Programm steht unter der GNU GENERAL PUBLIC LICENSE. Vgl. hierzu:
'* http://gplv3.fsf.org/
'*
'* Kurze Zusammenfassung:
'* Sie erhalten die Erlaubnis, dieses Programm und die zugehoerige Dokumentation
'* fuer beliebige Zwecke kostenlos zu benutzen, zu kopieren, zu veraendern,
'* weiterzugeben oder zu verkaufen, unter der Voraussetzung, dass Sie diese
'* Lizenzbestimmung und diesen Text auch in Ihre daraus erstellten Programme bzw.
'* Dokumentationen uebernehmen.
'* Dieses Werk wird Ihnen so ueberlassen "wie es ist", auf eigene Gefahr und ohne
'* jegliche Gewaehrleistung.
'*
'******************************************************************************
'******************************************************************************
'* Include to be compatible with some VB commands / Ermoeglichen VB Befehle
'******************************************************************************
#include "vbcompat.bi"
'******************************************************************************
'* Includes for Gtk / Definitionen fuer Gtk
'******************************************************************************
#include "gtk/gtk.bi"
#include "gtk/libglade/glade-xml.bi"
#define NULL 0
'******************************************************************************
'* Subroutines (callbacks) or "events" in Visual Basic notation
'******************************************************************************
'1) corresponding to the signals in the glade xml file / analog zu den Signalen
' in der glade xml Datei
declare sub on_window_delete_event cdecl alias "on_window_delete_event" (byval object as GtkObject ptr, byval user_data as gpointer )
declare sub on_execute_button_clicked cdecl alias "on_execute_button_clicked" (byval object as GtkObject ptr, byval user_data as gpointer )
'2) own routines / Eigene Routinen
declare sub get_userid()
Declare Function timer_func Cdecl (Byval NotUsed As Any Ptr) as integer
Declare Function toUTF8( Byval src As String ) As String
'******************************************************************************
'* Data definitions / Datendefinitionen
'******************************************************************************
dim shared xml as GladeXML ptr
dim shared toplevel as GtkWidget ptr
dim shared dlgQuit as GtkWidget ptr
dim shared messagedialog as GtkWidget ptr
dim shared status_bar as GtkWidget ptr
dim shared entry as GtkWidget ptr
dim shared textview as GtkWidget ptr
dim shared inLName as GtkWidget ptr
dim shared parent as GtkWindow ptr
dim shared inFName as string
dim shared starttime as double
dim shared contextid as Integer
dim shared msgbuffer as string
dim shared retcd as Integer
dim shared userid as string
dim shared answer as Integer
dim shared puffer as GtkTextBuffer ptr
dim Shared ErrMsg as Zstring Ptr
dim shared Farbe as GdkColor
'******************************************************************************
'*
'* =========================
'* START OF THE MAIN PROGRAM
'* BEGINN DES HAUPTPROGRAMMS
'* =========================
'*
'******************************************************************************
'******************************************************************************
'* Initialize Gtk / GUI (Gtk) initialisieren
'******************************************************************************
gtk_init( NULL, NULL )
'******************************************************************************
'* Specify the windows to be shown / Anzuzeigende Fenster spezifizieren
'******************************************************************************
xml = glade_xml_new( "gtkcommand.glade", NULL, NULL )
'******************************************************************************
'* Reference some widgets / Fenster+Felder referenzieren
'******************************************************************************
toplevel = glade_xml_get_widget( xml, "window" )
entry = glade_xml_get_widget( xml, "execute_entry" )
textview = glade_xml_get_widget( xml, "output_textview" )
' Initialize r/g/b components, they are 16-bit values
' 8 bit RGB Werte mit 257 multipliziert ergibt den 16 bit Wert,
' weil 255 * 257 = 65535
Farbe.red = 255 * 257
Farbe.green = 255 * 257
Farbe.blue = 181 * 257
gtk_widget_modify_base (entry, GTK_STATE_NORMAL, @Farbe)
' Background / Hintergrund
' Initialize r/g/b components, they are 16-bit values
' 8 bit RGB Werte mit 257 multipliziert ergibt den 16 bit Wert,
' weil 255 * 257 = 65535
Farbe.red = 206 * 257
Farbe.green = 222 * 257
Farbe.blue = 254 * 257
gtk_widget_modify_base (textview, GTK_STATE_NORMAL, @Farbe)
' other examples:
' gtk_widget_modify_fg (textview, GTK_STATE_NORMAL, @Farbe)
' gtk_widget_modify_fg (textview, GTK_STATE_ACTIVE, @Farbe)
' gtk_widget_modify_fg (textview, GTK_STATE_PRELIGHT, @Farbe)
' gtk_widget_modify_fg (textview, GTK_STATE_SELECTED, @Farbe)
' gtk_widget_modify_bg (textview, GTK_STATE_NORMAL, @Farbe)
' gtk_widget_modify_bg (textview, GTK_STATE_ACTIVE, @Farbe)
' gtk_widget_modify_bg (textview, GTK_STATE_PRELIGHT, @Farbe)
' gtk_widget_modify_bg (textview, GTK_STATE_SELECTED, @Farbe)
' gtk_widget_modify_base (textview, GTK_STATE_ACTIVE, @Farbe)
' gtk_widget_modify_base (textview, GTK_STATE_PRELIGHT, @Farbe)
' gtk_widget_modify_base (textview, GTK_STATE_SELECTED, @Farbe)
' gdk_color_parse ("yellow", @Farbe)
'******************************************************************************
'* Display main window / Hauptfenster anzeigen
'******************************************************************************
gtk_widget_show_all( toplevel )
glade_xml_signal_autoconnect( xml )
'******************************************************************************
'* The main loop starts / Hier beginnt die eigentliche GUI-Verarbeitung
'******************************************************************************
gtk_main( ) 'to be terminated by function gtk_main_quit (see below)
'wird durch gtk_main_quit beendet (siehe unten)
'******************************************************************************
'* Wrap up / Abschliessende Schritte
'******************************************************************************
' a) unattach xml reference / xml Referenz abbauen
g_object_unref( xml )
' b) Finish program with return code 0 / Programm mit Returncode 0 beenden
end 0
'******************************************************************************
'*
'* =======================
'* END OF THE MAIN PROGRAM
'* ENDE DES HAUPTPROGRAMMS
'* =======================
'*
'******************************************************************************
'------------------------------------------------------------------------------
' now the sub programs start ... /ab hier Unterprogramme ...
'------------------------------------------------------------------------------
sub on_window_delete_event cdecl (byval object as GtkObject ptr, byval user_data as gpointer ) export
'******************************************************************************
'* Close main window + end program (via 'X' button at the top right)
'* Hauptfenster schliessen+Programm beenden (Ueber den 'X' Button rechts oben)
'******************************************************************************
messagedialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "Wollen sie wirklich beenden?")
parent = GTK_WINDOW (toplevel)
gtk_window_set_transient_for (GTK_WINDOW(messagedialog), parent)
answer = gtk_dialog_run (GTK_DIALOG (messagedialog))
gtk_widget_destroy (messagedialog)
if answer = GTK_RESPONSE_YES then
gtk_main_quit () 'quits the GUI processing / beendet die GUI-Verarbeitung
else
gtk_widget_show_all( toplevel ) 'show the destroyed window again
end if
end sub
sub on_execute_button_clicked cdecl (byval object as GtkObject ptr, byval user_data as gpointer ) export
'******************************************************************************
'* React on execute button
'* Auf den "Ausführen"-Knopf reagieren
'******************************************************************************
dim Ausgabe as zstring ptr
dim ausg as zstring ptr
dim Kommando as string
dim ausgzeile as zstring ptr
dim as Zstring Ptr returncode
dim as GError Ptr ptr subrc
dim font_desc as PangoFontDescription ptr
dim s as string
dim cmdline as zstring ptr
dim stdout as zstring ptr ptr
dim stderr as zstring ptr ptr
dim exitstat as gint ptr
dim errcode as gerror ptr
dim err2 as gerror
dim outbuff as string
dim widgetbuff as GtkTextBuffer ptr
' const komm = "dir"
Kommando = *gtk_entry_get_text (GTK_ENTRY (entry))
outbuff = ""
Dim text As String
Open Pipe Kommando For Input As #1
Do While Not EOF(1)
Line Input #1, text
outbuff = outbuff + text + chr(13) + chr(10)
Loop
close #1
' for linux possible as well / für Linux auch möglich:
' ----------------------
' g_spawn_command_line_sync (Kommando, @stdout, NULL, NULL, @errcode)
' err2 = *errcode
' print err2.code
' print *err2.message
' Change font into fixed / Schrift in fixed ändern
font_desc = pango_font_description_from_string ("monospace 10")
' other font examples:
' font_desc = pango_font_description_from_string ("monospace underline=single 10")
' font_desc = pango_font_description_from_string ("Helvetica Bold single 10")
gtk_widget_modify_font (textview, font_desc)
pango_font_description_free (font_desc)
' Output with red font / Ausgabe in roter Schrift
gdk_color_parse ("red", @Farbe)
gtk_widget_modify_text(textview, GTK_STATE_NORMAL, @Farbe)
if outbuff <> "" then
widgetbuff = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview))
' gtk_text_buffer_set_text (widgetbuff, outbuff, -1)
gtk_text_buffer_set_text (widgetbuff, toUTF8(outbuff), -1)
end if
end sub
Function toUTF8( Byval src As String ) As String
'******************************************************************************
'* Codepage Conversion
'* Zeichensatzkonvertierung
'******************************************************************************
Dim As Zstring Ptr buff
Function = ""
' Umwandeln von Windows-Zeichensatz in UTF-8
' buff = g_convert( src, Len( src ), "UTF-8", "ISO-8859-1", NULL, NULL, NULL )
' Umwandeln von DOS-Zeichensatz in UTF-8
buff = g_convert( src, Len( src ), "UTF-8", "IBM850", NULL, NULL, NULL )
Function = *buff
g_free( buff )
End Function
Und hier die .glade-Datei (unter gtkcommand.glade speichern):
<?xml version="1.0"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy toplevel-contextual -->
<widget class="GtkWindow" id="window">
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">10</property>
<property name="title" translatable="yes">Execute OS command</property>
<property name="default_width">560</property>
<property name="default_height">380</property>
<signal name="destroy" handler="gtk_main_quit"/>
<signal name="delete_event" handler="on_window_delete_event"/>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="spacing">5</property>
<child>
<widget class="GtkEntry" id="execute_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
</widget>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkButton" id="execute_button">
<property name="label" translatable="yes">gtk-execute</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_execute_button_clicked"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</widget>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="border_width">2</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">etched-in</property>
<child>
<widget class="GtkTextView" id="output_textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="editable">False</property>
</widget>
</child>
</widget>
<packing>
<property name="position">1</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface>
Viel Spaß damit!
Zusätzliche Informationen und Funktionen |
- Das Code-Beispiel wurde am 26.10.2010 von ksiebke angelegt.
- Die aktuellste Version wurde am 26.10.2010 von ksiebke gespeichert.
|
|