Perl und Tk-Erweiterung


Perl and the Tk Extension
Copyright © By lehigh.edu
For original English text, go to: http://www.lehigh.edu/~sol0/ptk/tpj1.html


Verwenden von X aus Perl
Steve Lidie

Na, hallo! Dies ist die erste von mehreren Artikeln auf der Tk-Toolkit,
eine wunderbare objektorientierte Perl-Erweiterung, die eine umfassende bietet
Widget-Sammlung für alle Arten von schicke grafische Anwendungen.
Tk wurde von John K. Ousterhout entwickelt und angepasst und erweitert für Perl
von Nick Ing-Simmons.

Die Tk-Erweiterung für Perl wird als Perl / Tk bezeichnet wird, und läuft unter
das X Window System auf den meisten Unix-Computern gefunden. X verwendet ein
Client / Server-Modell, bei dem Kunden (wie die, die Sie sind etwa
zu) kommunizieren mit einem Server sehen , die dem Computer-Monitor verwaltet,
Tastatur und Maus. Für jeden gibt es eine Anzeige Fenster
Manager
das stellt eine einheitliche “Look and Feel”, zumindest auf einem hohen
Niveau, für alle Client-Sharing im Geräte-Display. Es gibt
vielen verschiedenen Window-Manager, aber sie alle bieten ähnliche Einrichtungen,
wie Icon darzustellen, Verschieben, Skalieren Fenster, und Framing sie in dekorativen
Grenzen. Sie Window-Manager-Befehle in Spalten später sehen werden.

Dieser Artikel enthält eine sanfte Einführung in die Grundlagen von Perl / Tk,
nach dem es sich entwickelt, Schritt, ein richtiger Anwendung fort. Wie es typisch
von meinem Schreibstil habe ich oft mehr Fragen als ich beantworten, so dass Sie
wird beibehalten möchten diese URL bereit:

Dies ist der Ort der Perl / Tk FAQ, das Repository von fast allem

Immer Über Perl / Tk, nachdenklich wird verwaltet von Peter Prymmer.

Die aktuelle Version von Perl / Tk ist Tk800.012 und baut erfolgreich
gegen Perl 5.004_04 oder 5,005. erhalten Sie das neueste Tk Verteilung Link
zu einem CPAN-Site in Ihrer Nähe durch Visting http://www.perl.com.

Perl / Tk-Programme werden geschrieben mit dem objektorientierten Syntax $ object-> Methode,
, wo $ object bezieht sich auf eine Tk-Widget, vielleicht ein Buttom oder Menü,
und Methode Namen eine Aktion durchgeführt werden soll. Wir werden erfahren Sie mehr über
Objekte und solche in der nächsten Spalte, aber jetzt, ohne weitere Umschweife, hier
wird Ihr prototypische “Hallo Welt”-Programm in Perl / Tk, geklaut
von der Tk-Verteilung:

#! / Usr / local / bin / perl-w

#

# Simple Tk-Skript zur Erstellung einer Schaltfläche, die "Hallo Welt" druckt.
Klicken Sie auf

# Die Taste, um das Programm zu beenden.

#

# Die erste Zeile unterhalb importiert die Tk-Objekte in der Anwendung,
die

# Zweite Zeile erzeugt das Hauptfenster, das dritte bis fünfte
Linien erstellen

Die Taste # und definieren Sie den Code, der ausgeführt ist, wenn die Taste
gedrückt, wird das

# Sechste Zeile fragt den Packer zu Schrumpffolie das Hauptfenster der Anwendung
Fenster

# Um den Knopf, und die siebte Zeile beginnt das Event-Schleife.

Verwendung Tk;

$ MW = MainWindow-> new;

$ Hallo = $ mw-> Button (

-Text => 'Hallo Welt',

-Command => sub {print STDOUT "Hallo Welt \ n";
exit;});

$ Hallo-> pack;

MainLoop;

Wenn das Programm ausgeführt wird, erscheint dieses Fenster:


Das Programm kann oder auch nicht selbsterklärend sein! Die Hauptfenster
$ MW , ist das Programm das erste Toplevel-Fenster – das primäre
“Behälter” für die meisten, wenn nicht alle, Nachkomme Widgets, die eine Hierarchie bilden
(Jedes Widget hat immer ein Elternteil, und vielleicht Kinder sowie zu haben).

Dies insbesondere Toplevel-Widget hat eine einzelne Kind Objekt gehörenden
auf den Button Klasse . Alle Widgets sind Objekte aus einer Basis abgeleitet
Klasse,
erben ihre Eigenschaften. Sie müssen möglicherweise mehrere Instanzen
der Schaltfläche Objekte, die ganz anders aussehen, aber teilen sich die Unterscheidungsmerkmale
Merkmale der Klasse Button: sie zeigen eine Beschriftung oder Bitmap und
“Etwas tun”, wenn sie ausgewählt. Wenn der Knopf im Beispiel gedrückt wird
die anonyme Subroutine wird ausgeführt, druckt “Hallo, Welt” und wird beendet.
Das Unterprogramm aufgerufen wird, weil es auf die Schaltfläche klicken gebunden.
Fast alle Widget-Klassen verfügen über Standard-Schaltfläche und Tastendruck Bindungen etabliert
von Perl / Tk, und man kann hinzufügen, löschen oder ändern Bindings für eine Klasse
oder pro-Widget Grundlage wie Sie sehen, passen.

Die Aussage:

$ Hallo = $ mw-> Button (...);

ist ein Widget Schöpfung -Befehl: ein Objekt der Klasse Button wird gebaut
und mit den angegebenen Optionen, die ein Nachkomme wird konfiguriert
Widget $ MW, das Hauptfenster. Die Variable $ hallo ist mit einem initialisiert
Objektreferenz auf die neu erstellte Schaltfläche Widget. In Perl ein
Objekt-Referenz ist ein ganz normaler Referenz, die auf “etwas”, betont
Das war “Blessed” (mit dem Perl bless () -Funktion) in ein
gewisse Klasse. Der “etwas” ist ein Hash oder eine Liste, und der Akt des
segnet ein Objekt bindet sie an einer bestimmten Klasse. Perl / Tk Widget-Objekte
Hashes sind, wie in diesem Debug-Durchlauf gezeigt:

Dandy :/ home/bug/perl/tpj1/perl-de 0

Geladen DB-Routinen aus perl5db.pl Version 1.02

Emacs-Unterstützung zur Verfügung.

Geben Sie h oder `h h 'für Hilfe.

Main :: (-e: 1): 0

DB Verwendung Tk

DB $ ref = {}

DB $ MW = MainWindow-> neue

DB = $ $ oref MW-> Button

DB p $ ref

HASH (0x200f78c8)

DB p $ oref

Tk :: Button = HASH (0x2021c780)

Die Variable $ ref ist eine einfache Bezugnahme auf einen anonymen Hash, während
$ Oref ist ein Objekt, Referenz auf einen Hash der Klasse Tk :: Button .
Aber von jetzt an werde ich auf Variablen wie $ Hallo und $ oref beziehen
einfach als Objekte oder Widgets. (Wenn Sie nicht mit dem Perl vertraut
Debugger, das Idiom perl-de 0 startet eine interaktive Instanz
Perl, wo Sie debuggen kann oder geben Sie einfach Perl-Befehle – ein großer Prototyping
Umwelt.)

Die Aussage:

$ Hallo-> pack;

ist ein Methodenaufruf -Befehl: die Tk-Geometrie-Manager als bekannt
die Packer wird aufgerufen, um eine Größe und Position an die $ Hallo zuweisen
Objekt und dann auf “Karte” ist. Ein Widget muss kartiert (oder realisiert) werden, bevor
es wird auf dem Display sichtbar. Mit dem Standard-Widgets sind immer brechend voll
innen der Eltern, und wenn Sie nicht angeben, da sonst die Packer richtet
sie in einer Spalte, von oben nach unten.

Perl / Tk-Programme sind ereignisgesteuert , was bedeutet, dass Sie nicht zu schreiben
“Main-Schleife” in der Standard-Sinne, sondern delegieren diese Arbeit an Tk.
Stattdessen schreiben Sie kleine Code-Abschnitte, die so genannte Rückrufe,
ein ausgefallener Name für eine Subroutine, um diese Ereignisse und das Verfahren
Tk ruft nach Bedarf. Es gibt viele Tk Ereignisse, die verarbeitet werden müssen
in einer zeitgemäßen Weise: Timer, Datei-und Ausgang, sowie Bewegungs-und
Schaltfläche Ereignisse, die von der Maus erzeugt. Sie aktivieren die Tk-Ereignis-Schleife mit
ein MainLoop () -Anweisung, die die letzte Zeile heißt durch sein sollte
Ihr Programm.

Zusammenfassend teilen die meisten Perl / Tk-Anwendungen diese gemeinsame Merkmale:

  • Ein Verwendung Tk -Anweisung am Anfang der
    Programm, das die Basis Tk Definitionen importiert .
  • Eine primäre MainWindow als die Wurzel des Widget-Hierarchie.
  • Eine Reihe von Widget Schöpfung -Befehle.
  • Optional verbindlich und Callback Schöpfung und
    Anmeldung
    -Befehle. (Mehr über diese bald.)
  • Eine Reihe von Befehlen zur Geometrie Pack Widgets in einem
    ansprechende und benutzerfreundliche Art und Weise.
  • Ein MainLoop () -Befehl, den Programmablauf zu beginnen. (Tatsächlich
    es gibt Zeiten, wenn Sie bei der Verarbeitung selbst kontrollieren müssen, wir werden
    ein Beispiel dafür sehen dies in einem späteren Spalte.)

Tk bietet 15 Standard-Widgets, Perl / Tk bietet zusätzliche Composite
Widgets wie ColorEditor, Dial, FILESELECT, LabEntry und Tabelle. Composite-
Widgets, auch genannt megawidgets, sind komplexe Objekte von diesen gebaut
Standard-Widgets.

  • Button Widgets auszuführen, wenn eine Callback aufgerufen. Sie sind
    abgeleitet aus dem Label-Widget.
  • Leinwand Widgets bieten eine Zeichnung Oberfläche für Text
    und Grafiken.
  • Checkbutton Widgets wählen Sie ein oder mehrere Elemente aus
    eine Liste. Sie sind aus dem Label-Widget abgeleitet.
  • Eintrag Widgets können Benutzer zur Eingabe und Bearbeitung eines einzelnen
    Text-String.
  • Rahmen Widgets werden in erster Linie als Container verwendet
    Gruppe andere Widgets, zum Beispiel beim Verpacken. Frames können angeordnet werden
    innerhalb einer Anwendung das Hauptfenster, mit anderen Widgets in ihnen. Frames
    werden auch als Abstandshalter verwendet und auf farbige Ränder hinzufügen.
  • Label Widgets zeigen eine Text-oder Bild-Label. Button,
    Checkbutton und RadioButton Widgets werden von der Label-Widget abgeleitet.
  • Listbox Widgets zeigt eine Liste von Strings und erlauben
    Benutzer, einen auszuwählen, ein Bereich oder eine verstreute Gruppe von den Saiten.
  • Menü Widgets sind spezielle Widgets, die in Verbindung arbeiten
    mit Menubuttons. Das Aufrufen eines Menübutton zeigt die damit verbundenen Menü. Dort
    gibt verschiedene Arten von Menüpunkten, wie Knöpfe, Checkbuttons, Radiobuttons,
    Separatoren und Kaskaden.
  • Menübutton Widgets zeigen ein Etikett (wie Buttons)
    aber wenn sie ausgewählt ein Menü angezeigt.
  • Nachricht Widgets sind ähnlich wie Etiketten, außer sie
    mehrzeilige Strings.
  • Radiobutton Widgets wählen Sie ein einzelnes Element aus einer Liste aus.
    Sie sind aus dem Label-Widget abgeleitet.
  • Skala Widgets bestehen aus einem Schieber, der Benutzer erlaubt
    um einen Wert mit dem Schieberegler festlegen.
  • Scrollbar Widgets steuern Sie den Blick auf weitere Widgets,
    wie Leinwand, kann Eintrag, ListBox und Text. Benutzer scrollen Sie das Widget
    indem Sie den Schieberegler.
  • Text Widgets angezeigten Zeilen für bearbeitbaren Text. Charaktere
    in einem Text-Widget kann gefärbt werden, da bestimmte Schriftarten, Abstände, Ränder
    und vieles mehr.
  • Toplevel Widgets sind im wesentlichen sekundären MainWindows.
    Sie ähneln Frames, indem sie fungieren als Container-Widgets, außer sie
    sind nicht interne Widgets.

Die Perl / Tk-Anwendung, die ich entwickeln werde mich heißt Plotprogramm ,
oder plop für kurz-, mit Button, Canvas, Dialog, Frame, Label,
LabEntry, Menü, Menübutton, Scrollbar-und Text-Widgets. Plop Grundstücke
eine Liste von mathematischen Funktionen der Form $ y = f (x $ ), wo $ x
iteriert aus dem Diagramm die X-Minimum auf X-Maximum. Jede Funktion wird ausgewertet
wiederum für einen bestimmten Wert von $ x , ein Y-Wert wird berechnet und
dann wird ein Punkt auf der Leinwand gemalt. ( Plop betont die Leinwand
Widget, weil ich habe bemerkt, dass neue Benutzer Tk, nachdem ich um 2000
Linien der Leinwand Dokumentation Rolle durch, neigen zu platzieren “die Erkundung der Leinwand
Widget “am Ende ihrer To-do-Liste! Ich glaube, Sie werden feststellen, dass mit großem Funktionsumfang
bedeutet nicht, schwierig zu bedienen.)

Erinnerung, dass ein Canvas-Widget kann als der Künstler-Leinwand gedacht werden
für Freihandzeichnen von Grafiken und Text, werden wir es als eine klassische Behandlung
Kartesischen Koordinatensystem. Ein wesentlicher Unterschied ist, dass die Leinwand Herkunft,
Koordinatenposition (0,0), ist definiert als die linke obere Ecke der sein
Leinwand-Fenster, und dass X-Koordinaten Leinwand Anstieg beim Bewegen rechts
(Wie erwartet) und Y-Koordinaten Anstieg beim Bewegen unten (wie
ihr habt nicht gewollt). Darüber hinaus können Koordinaten Leinwand keine negativen Werte.
Aus diesen Gründen verwenden wir eine Gleichung zwischen Leinwand und transformieren
Kartesischen Koordinaten.

Hier ist die allererste Version des Programms:

    #! / Usr / local / bin / perl-w

    Use strict;

    Verwendung Tk;

    My ($ o, $ s) = (250, 20);

    My ($ pi $ x, $ y) = (3,1415926, 0);

    My $ mw = MainWindow-> new;

    My $ c = $ mw-> Canvas (-width => 500,-height => 500);

    $ C-> pack;

    $ C-> createLine (50, 250, 450, 250);

    $ C-> CreateText (10, 250,-fill => 'blue',-text => 'X');

    $ C-> createLine (250, 50, 250, 450);

    $ C-> CreateText (250, 10,-fill => 'blue',-text => 'Y');

    For ($ x = - (3 * $ pi); $ x <= + (3 * $ pi); $ x + = 0,1) {

    $ Y = sin ($ x);

    $ C-> CreateText ($ x * $ s + $ o, $ y * $ s + $ o,-fill =>
    '.' 'Rot',-text =>);

    $ Y = cos ($ x);

    $ C-> CreateText ($ x * $ s + $ o, $ y * $ s + $ o,-fill =>
    '.' 'Grün',-text =>);

    }

    MainLoop;

Zugegeben, das ist wirklich hässlich Code, stillos, aber es ist ein “proof
of concept “. Wie Sie sehen werden, werde ich diesen Code in die richtige Form pronto Peitsche!
Bevor ich es erklären, hier ist was es ist, wenn ausgeführt aussieht:

Einige globale Variablen initialisiert, das Hauptfenster, $ MW und
ein Canvas-Widget, $ c , erstellt werden und die Leinwand realisiert wird. Die
nächsten vier Anweisungen erstellen zwei Leinwand Linie Elemente (für den Graphen
Achsen) und zwei Text Elemente (für die Achsen-Etiketten). Andere Leinwand
Item-Typen sind Bogen , Bitmap , Bild , oval , Polygon ,
Rechteck und Fenster .

Die Aussagen:

    $ C-> createLine (50, 250, 450, 250);

    $ C-> CreateText (10, 250,-fill => 'blue',-text => 'X');

zeichnen und kommentieren Sie die X-Achse. Die Leinwand-Methode CreateType schafft
eine Leinwand Item vom Typ Typ: Ich erstelle hier ein Posten
und ein Text-Element. Da ist die Leinwand 500×500 Pixel Ich habe bewusst angeordnet
für Leinwand Koordinatenposition (250.250), um mit dem kartesischen zusammenfallen
Ursprung (0,0). Ich wollte auch 50-Pixel breite oben / unten und haben
Ränder links / rechts. Angesichts dieser contraints die X-Achse beginnt bei Zeile (50250)
und erstreckt sich horizontal an (450.250), mit einem blauen Buchstaben “X” gemalt in
der linke Rand auf (10.250). In ähnlicher Weise wird die Y-Achse senkrecht strich
von oben nach unten und markiert mit einem blauen “Y”. Jetzt alles, was bleibt ist
tatsächlich Graphen einige Funktionen.

Die für -Anweisung unterscheidet sich von -3 P
bis + 3 P Radiant und selbst alte Biologie-Typen
wie ich weiß, dass Sinus () und Cosinus () einen Wert zurückgeben
im Bereich [1,1]. Solche kleinen Werte sind nicht besonders nützlich, es sei denn, du bist
Suche nach einem Graphen ein Pixel hoch, so dass eine Transformation ist erforderlich:

    $ Y = sin ($ x);

    $ C-> CreateText ($ x * $ s + $ o, $ y * $ s + $ o,-fill => 'rot',-text => '.');

Wir wollen unsere $ y -Werte, die, was der Ausdruck $ y * $ s + $ o ist zu skalieren
tut: der Y-Wert ist 20-mal vergrößert und übersetzt auf die Leinwand
Ursprungs. Dann wird ein roter Punkt auf die Leinwand aufgebracht. (Es gibt tatsächlich eine
Fehler, ist die Transformation Gleichung, können Sie vor Ort das? Tipp, versuchen Sie die grafische Darstellung
Exp () -Funktion.)

So viel zum häßlichen plop -Prototyp, mit viel Arbeit kann ich
drehen Sie diesen Code in einem erstklassigen Perl / Tk-Anwendung. Für den Anfang möchte ich
jeden einzelnen codierten Wert und Gebrauch Variablen anstatt zu beseitigen. Dann
Ich füge die folgenden Funktionen:

  • Ein Menü am oberen Rand. Wie alle angesehenen Anwendungen,
    es wird die Datei-und Hilfe menubuttons.
  • CTITEL für die Grafik.
  • Einstellbare minimale und maximale X-und Y-Werte.
  • eine editierbare Liste der Funktionen.
  • die Option für die Funktionen aus einer Datei eingelesen. Heck,
    lasst es einfach tun:. eval {require "plop.fnc";} Bewahren Sie Ihre
    Private Funktionen in der Datei plop.fnc und sie werden zur Verfügung stehen
    zum Plotten. Zum Beispiel plop.fnc enthält vielleicht diese Zeilen
    Um die den hyperbolischen Arcustangens wollte:

      Sub atanh {

      Rückkehr undef if ($ _ [0] 1);

      0,5 * log ((1 + $ _ [0]) / (1 - $ _ [0]));

      }

Unten sehen Sie eine Probe des neuen plop laufen . Die komplette
Programm ist auf TPJ Website verfügbar:


Das Hauptfenster ist in drei große Regionen, ein Top-Rahmen mit geteilt
menubuttons (mit der Datei-und Help-Menüs), die Leinwand in der Mitte
(Einschließlich des Titels und Grenzwerte) und einen unteren Bereich mit
eine Reihe von anderen Widgets (inklusive einem bildlauffähigen Text-Widget mit der
Liste der Funktionen). Der Perl-Code wurde modularisiert und sieht etwas
wie folgt aus:

    My $ MW = MainWindow-> new;

    Initialize_dialogs;

    Initialize_menus;

    Initialize_canvas;

    Initialize_functions;

Unterprogramm initialize_dialogs () schafft Dialog Widgets, die
sind nicht Teil des Hauptfensters richtige, aber Popup zu bestimmten Zeiten, warten
für den Benutzer zu intervenieren, und dann weggehen. In der Regel bestehen sie für
die Lebensdauer der Anwendung, damit sie einmal in Programm erstellt
Initialisierung und werden dann durch Abziehen , bis es verborgen
Zeit, um “Show” ihnen; Show () ist ein Dialog-Methode, dass deiconifies
Das Widget, wartet der Benutzer eine Taste wählen, um Dialog und kehrt dann
Auf dem Etikett der gewählten Taste auf dem Programm. Hier ist, wie plop ‘s
“Über”-Dialog-Widget erstellt wird:

    DIALOG_ABOUT $ = $ mw-> Dialog (

    -Title => 'Info',

    -Text => "plot_program $ VERSION \ n \ n
    95/12/04 ",

    -Bitmap => 'info',

    -Tasten => ['dismiss']);

Wie alle Widget-Erstellung Befehle, $ mw-> Dialog () gibt einen Verweis
auf ein Objekt. Die Tasten -Attribut ist ein Liste von Strings
dass, angeben des Dialogs Schaltfläche Etiketten. In diesem Fall gibt es nur einen
Schaltfläche “Schließen”, die zurückzieht den Dialog, nachdem Sie gelesen haben
die wirklich informativ “Über”-Informationen!

Die plop erstellen -Menüs, initialize_menus () wiederverwendet einige
alten Code, der menubuttons aus einer Datenstruktur erzeugt, vor allem, weil
Ich bin faul und Menüs immer die Zeit nehmen, genau das Richtige. Meiner nächsten Kolumne geht
ins Detail auf Menüs, Kaskaden, etcetera, aber für jetzt prüfen diesen Code ein:

    $ MBF = $ mw-> Frame (-relief => 'erhöht',-borderwidth => 1);

    $ MBF-> pack (-fill => 'x');

    Make_menubutton ($ MBF, 'Datei', 0, 'left', [['Quit', \ & Exit,
    0]]);

    Make_menubutton ($ MBF, 'Hilfe', 0, 'rechts', [

    ['Über', [$ DIALOG_ABOUT => 'Show'], 0],

    ['',
    0],

    ['Verwendung', [$ DIALOG_USAGE => 'Show'], 0]]);

Die erste Anweisung erstellt das Container-Rahmen um die menubuttons halten,
mit einem Relief von angehoben und ein borderwidth von einem.
Das Relief-Attribut gibt den Widget-3D-Look, aber Sie müssen einen von Null verschiedenen
borderwidth es zu sehen. Beachten Sie, dass der Rahmen mit seinen füllen ist gepackt
Attribut auf “x”, die der Packer Geometrie-Manager erweitern das macht gesetzt
Rahmen in der X-Richtung zu füllen den gesamten verfügbaren Platz. Andernfalls wird die Datei
und Hilfe menubuttons würde Seite-an-Seite abgebildet werden und zentriert in dem Rahmen.
Erstellen der menubuttons und die entsprechenden Menüpunkte bringt Anrufe
zu make_menubutton () , mit diesen 5 Parametern:

  • Die Elternteil Widget .
  • Die menubutton Label .
  • Die Verknüpfung Charakter Index. Alle unsere menubuttons
    eine Verknüpfung Zeichenindex von Null. Zum Beispiel, das 0-te (erste)
    Charakter der “File” ist ‘f’, was bedeutet, dass Benutzer können geben Sie Alt-f bedeutet
    um das Menü Datei zu aktivieren.
  • Die Seite des Menüs, um den Rahmen menubutton packen.
  • Eine Liste von Listen beschreiben die Menüpunkte . Jeder innere
    Liste besteht aus drei Komponenten, ein Label, einen Rückruf, der ausgeführt wird, wenn die
    Menüpunkt aufgerufen wird und eine Verknüpfung Unterstrich. Null-Etiketten sind
    behandelt als Trennzeichen -. do-nothing Menüpunkte, die als Linien erscheinen

Rückrufe kommen in verschiedenen Geschmacksrichtungen, und wir werden mehr von ihnen in später sehen
Spalten, aber in plop ‘s Fall gibt es nur zwei: eine explizite Bezugnahme
zu einem Unterprogramm (auch als Codereferenz) , und ein Verweis
auf ein Array
. Ein Beispiel der ersten Form ist die Beenden Menüpunkt, die
Anrufe exit () . Die Hilfe Menüpunkte die zweite Form, wo die
erste Array-Element ist ein Objekt (Widget Referenz) und die zweite ist die
Name der Methode, die aufgerufen. Somit wird, wenn der Benutzer wählt “Über” die über
Dialog-Widget angezeigt. Beachten Sie, dass Widgets in Callbacks verwendet werden, müssen vor existieren
sie werden auch genannt – das ist genau, warum die Dialog-Widgets erstellt wurden
zuerst.

Unterprogramm initialize_canvas () erzeugt den mittleren Bereich der plop ‘s
Hauptfenster, aber ist etwas anders als der Prototyp-Version da
es hat eine Titelzeile, eingebettete Widgets mit editierbaren X-und Y-Werte und
Achsen bewegt, um die Grenzen des Gebietes um eine übersichtlichere Darstellung zu reduzieren.

    $ CANV = $ mw-> Canvas (

    -Width => $ + $ MAX_PXL Marge * 2,

    -Height => $ MAX_PXL,

    -Relief => 'versunkenen');

    $ CANV-> pack;

    $ CANV-> CanvasBind ('

Der obige Code erzeugt die Leinwand, sondern nutzt den globalen “Konstanten” und nicht als
hartcodierten Werte: $ MAX_PXL ist natürlich die Größe der Leinwand,
in Pixel. Hier ist unser erster Registrierung von Callback -Befehl, der
bindet die Subroutine display_coordinates () , um Maustaste 1.

    $ CANV-> CreateText (325, 25,

    -Text => 'Der Plot Continuous Funktionen der Form
    y = f (x $) ',

    -Fill => 'blau');

Nichts Neues gibt, was? Aber halt, etwas Neues folgt, die Leinwand Element
Typ genannt Fenster !

    # Erstellen Sie die Linie, um die X-Achse darstellen und beschriften Sie sie. Dann Etikett
    die

    # Minimalen und maximalen X-Werte und zeichnen Sie Markierungen, um anzuzeigen,
    wo sie

    # Fallen. Die Achse Grenzen sind LabEntry Widgets in Canvas eingebettet
    Fenstern.

    $ CANV-> createLine (

    MIN_PXL $ + $ MARGIN, MAX_PXL $ - $ MARGIN,

    MAX_PXL $ - $ MARGIN, MAX_PXL $ - $ Rand);

    $ CANV-> createWindow (

    MIN_PXL $ + $ MARGIN, MAX_PXL $ - $ label_offset,

    -Fenster => $ mw-> LabEntry (

    -Textvariable => \ $ X_MIN,

    -Label
    => 'X Minimum'));

    $ CANV-> createLine (

    MIN_PXL $ + $ MARGIN, MAX_PXL $ - $-Marge - $ tick_length,

    MIN_PXL $ + $ MARGIN, MAX_PXL $ - $ $ tick_length Rand +);

    $ CANV-> createWindow (

    MAX_PXL $ - $ MARGIN, MAX_PXL $ - $ label_offset,

    -Fenster => $ mw-> LabEntry (

    -Textvariable => \ $ x_max,

    -Label
    => 'Maximale X'));

    $ CANV-> createLine (

    MAX_PXL $ - $ MARGIN, MAX_PXL $ - $-Marge - $ tick_length,

    MAX_PXL $ - $ MARGIN, MAX_PXL $ - $ $ tick_length Rand +);

Die erste Leinwand Posten ist einfach die horizontale X-Achse, und die beiden
restlichen Zeilen sind die Markierungen an jedem Ende. Die beiden Artikel sind Fenster
Container, in denen andere Aufgaben gefüllt, in diesem Fall werden zwei zusammengesetzten
LabEntry Widgets, die, wie Sie sich vorstellen können, kombinieren die Funktionen
von Etiketten-und Einreise-Widgets. Ihre textvariable Attribute sind Referenzen
zu Skalaren $ X_MIN und $ x_max , wenn das Programm ändert die
den Wert einer Variablen auf der Anzeige reflektiert wird, und wenn der Benutzer editiert
ein LabEntry die damit verbundene textvariable aktualisiert wird. Die Y-Achse behandelt wird
in ähnlicher Weise.

Unterprogramm initialize_functions () Erstellt plop ‘s noch
Widgets, das sind in Top-to-Bottom-Packung bestellen, ein Abstandhalterrahmen, ein Label
Bereitstellung von rudimentären Anweisungen, ein Text-Widget mit einem angehängten Scrollbalken,
und schließlich ein weiterer Container-Rahmen zu halten, einen Knopf oder so.

    $ Mw-> Frame (-height => 20) -> pack;

    $ Mw-> Label (

    -Text =>
    'Geben Sie Ihre Funktionen hier',

    -Vordergrund => 'blau') -> pack;

    # Erstellen Sie einen Rahmen mit einem bildlauffähigen Text-Widget, dass die Displays
    Funktion

    # Liste, und eine Schaltfläche zum Plot-Aktivitäten zu initiieren.

    My $ functions_frame = $ mw-> Frame;

    $ Functions_frame-> pack;

    $ Text = $ functions_frame-> Scrolled (qw / Text-Höhe 6-Scrollbalken
    e /);

    $ Text-> pack;

    Update_functions;

    My $ buttons_frame = $ mw-> Frame;

    $ Buttons_frame-> pack (-padx => 10,-pady => 5,-expand => 1,-fill
    => 'X');

    My @ pack_attributes = qw /-Side-links-fill x-expand 1 /;

    $ Buttons_frame-> Button (

    -Text => 'Plot',

    -Command => \ & plot_functions) -> pack (@ pack_attributes);

Ho hum, einem 20 Pixel hohen Frame (so viel für das Verbot der einprogrammierte Konstanten!)
um Platz und einige Hinweistext in blau eingefärbt zu besetzen. (Aber haben Sie
wissen, dass überall, wo Sie eine Dimension zu geben, wie eine Integer-Pixel-Wert, den Sie
können auch die Zeichen Suffix i, c, m oder p , um anzuzeigen,
Zoll, Zentimeter, Millimeter oder Punkte ?) Dann gibt es noch
der Text-Widget mit einem Scrollbalken verankert “Osten”, und schließlich eine große “Plot”
Taste. Beachten Sie die bequeme Methode Scrolled () für die Befestigung Scrollbalken
zu dem Text-Widget. Das Text-Widget enthält die Funktion Mailingliste, was ist
besonders geeignet, da jeder Zeile können markiert und zugeordnet werden eine andere
Farbe. Die Funktion Punkte werden dann in dieser Farbe gezeichnet.

Die grafische Oberfläche in nun abgeschlossen, und wenn der Benutzer ruft die
“Plot”-Button, der Rückruf plot_functions () ausgeführt wird. Vor
tatsächlich Plotten der Funktion Liste plop bringt Ordnung auf dem Textfenster
und sorgt dafür, dass jede Funktion ihre richtige Farbe zugeordnet ist. Plop
bietet für bis zu neun gleichzeitige Funktionen vor dem Farben-Zyklus.
Hier ist der Code:

    $ TEXT-> delete ('0 .0 ',' end ');

    My $ i = 0;

    Foreach (@ Funktionen) {

    $ Text-> insert ('end', "$ _ \ n", [$ i]);

    $ Text-> tagConfigure ($ i,

    -Vordergrund => $ farben [$ i
    % $ NUM_COLORS],

    -Font => '9 x15 ');

    $ I + +;

    }

    $ Text-> yview ('end');

Zuerst wird alles gelöscht, aus der Leitung Null Zeichen Null bis zum Ende
der Text-Widget. Dann wird jede Funktion aus den @ Funktionen Array
eingesetzt ist und ein Tag, der nur zufällig in seiner Ordnungszahl zugeordnet sein
der Text-Widget. Ein Tag ist einfach eine Identifizierung String als Referenz verwendet
in anderen Widget-Kommandos. In diesem Fall werden die markierten Text Elemente konfiguriert
mit ihrem einzigartigen Vordergrundfarbe und einen festen Platz zugewiesen Schriftart.

Nun, da der Text-Widget synchron mit der Funktionsliste ist, lassen Sie uns Plot
Einige Funktionen:

    $ CANV-> delete ('plot');

    Canv_x $ = $ + $ MIN_PXL Rand; # X minimun

    $ DX = $ x_max - $ X_MIN;
    # Update Delta-X

    DY $ = $ Y_MAX - $ Y_MIN;
    # Update Delta-Y

    ALL_X_VALUES:

    For ($ x = $ X_MIN; $ x <= $ x_max; $ x + = ($ x_max - $ X_MIN) / $ ALEN)
    {

    ALL_FUNCTIONS:

    Foreach (0 .. $ #-Funktionen) {

    $ Y = eval $-Funktionen [$ _];

    $ Canv_y = (($ Y_MAX -
    $ Y) / $ dy) * $ + $ ALEN Rand;

    $ CANV-> CreateText ($ canv_x,
    Canv_y $,

    -Fill
    => $ Farben [$ _% $ NUM_COLORS],

    -Tags
    => ['Plot'],

    -Text
    =>), Wenn $ canv_y> $ MIN_PXL + $ und $ MARGIN canv_y <$ MAX_PXL - $ MARGE '.';

    } # Stulp ALL_FUNCTIONS

    $ Canv_x + +; # nächste Pixel X

    } # Stulp ALL_X_VALUES

Nach all dem sind wir wieder da, wo wir angefangen haben, außer dass der Code hat
gemacht worden allgemeinere und die Transformation Gleichung wurde behoben. $ X_MIN
und $ x_max werden dynamisch zugeordnet, da sie Teil der sind
LabEntry Widgets, und die X-Inkrementierungsausgabe, wird dynamisch berechnet
diese Werte und die Achsenlänge. Y Punkte auf der Leinwand gemalt
werden automatisch die richtigen Farben zugeordnet. Und jeder Punkt wird markiert
mit der Zeichenfolge “Handlung”, können so alle aktuellen Graphen problemlos gelöscht werden, die
beim nächsten Mal die “Plot”-Taste gedrückt wird, das ist, was die $ CANV-> delete (‘plot ')
Feststellung gilt für .

Aber es gibt einen unversucht gelassen: die Schaltfläche Bindung etabliert
während Leinwand Schöpfung. Da wir bereits wissen, wie man ein kartesisches konvertieren
koordinieren, um eine Leinwand-Koordinate, dachte ich, es würde Spaß machen, das zu tun
Gegenteil: Klicken Sie irgendwo auf der Leinwand, um ein kartesisches Koordinatensystem anzuzeigen.
Der folgende Code veranschaulicht, wie ein Ereignis X-Struktur zu behandeln, in
in diesem Fall eine Taste drücken:

    Sub display_coordinates {

    Nbsp; my ($ Leinwand) = @ _;

    My $ e = $ Leinwand-> XEvent;

    My ($ canv_x, canv_y $) = ($ e-> x, $ e-> y);

    My ($ x, $ y);

    $ X = $ + $ X_MIN DX * (($ canv_x - $ MARGIN) / $ ALEN);

    $ Y = $ Y_MAX - DY $ * (($ canv_y - $ MARGIN) / $ ALEN);

    Print "\ n Canvas X = $ canv_x, Leinwand y = $ canv_y \ n".;

    Print "Plot x = $ x, y = Plot $ y \ n".;

    } # End display_coordinates

Wenn ein verbindlicher Rückruf wird ausgeführt, das Unterprogramm übergeben wird implizit
ein Verweis auf seine Widget – hier die Leinwand. Mit XEvent (), die
Variable $ e ist nun eine Referenz auf das Event-Struktur zugeordnet.
Zwei der $ e ‘s Methoden, x () und y (), Rückkehr der
relativen Leinwand Koordinatenposition der Maus, wenn die Taste 1 gedrückt wurde.
Sobald die Koordinaten bekannt sind, es ist einfach eine Frage der Verwendung der vorhandenen
Transformation Gleichung Lösung für X und Y, und Ausdrucken der Ergebnisse.

Das war es für diese Zeit, wenn Sie Fragen zu diesem Artikel haben, oder
Ideen für die kommenden diejenigen, zögern Sie nicht mich zu kontaktieren. Nächstes Mal werden wir schauen
mehr zu Objekten, den Aufbau eines Composite-Widget und untersuchen Menüs im Detail.


Steve Lidie ist ein Systemprogrammierer
an der Lehigh University.