kleines Rechenprogramm

Fragen zu Tkinter.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

kleines Rechenprogramm

Beitragvon mathi » Freitag 24. Oktober 2008, 16:28

Hallo allerseits,
ich habe mich die letzten Jahre nur mit non-GUI programmen begnügt, und bitte um hilfe beim Umstieg:
nachdem die Grenzen erreicht sind:
http://www.python-forum.de/topic-16449.html

möchte ich als Einstieg mein kleines Interpolationsprogramm mit einer GUI versehen:

Code: Alles auswählen

from Tkinter import *

root = Tk()

textfenster = Text(root)
textfenster.pack()
def hole():
    textfenster.insert(END, '\n' + eingabe.get())
   
textfenster.insert(END,u'gegeben: x | gesucht: y ')
X1=u'Wert X1 mit X1<x: '
lab=Label(root,text=X1)
# ... hier fehlt etwas damit der eingabewert der Variablen X1 zugewiesen wird und im oberen Fenster erscheint
X2=u'Wert X2 mit X2>x: '
lab=Label(root,text=X1)
# ... hier fehlt etwas
Y1=u'Wert Y1 mit y=?: '
lab=Label(root,text=Y1)
# ... hier fehlt etwas
Y2=u'Wert Y2 mit y=?: '
lab=Label(root,text=Y2)
# ... hier fehlt etwas
x=u'Wert x: '
lab=Label(root,text=x)

lab.pack(side = LEFT)

eingabe = Entry(root,width=60)
eingabe.pack(side=LEFT)


   
but = Button(root,text='Hole', command = hole)
but.pack(side = LEFT)
root.mainloop()

#y=(x-X1)*(Y2-Y1)/(X2-X1)+Y1
#print u'Ergebnis y= ',y



Das ist nmein bisheriges Ergebnis, ich möchte oben alle Infos sammeln und unten Eingaben machen, wobei immer die aktuell gefragte Variable als Label erscheint, daneben der zugehörige Wert eingegeben wird,
nach Enter sollte dann im oberen Fenster als bestätigung erscheinen z.B.
gegeben: x | gesucht: y
X1= 15
X2=20
Y1=10
Y2=50
x=17
Ergebnis: y= ...

Nur sieht man ja, dass ich es erst mal zum Gerüst geschaft habe und jetzt bitte ich um Denkanstöße, denn ich stehe im Momment ein bissel auf dem Schlauch :-(
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Freitag 24. Oktober 2008, 17:50

Zum Verstehen von Tkinter empfehle ich folgende Lektüre:
http://www.ferg.org/thinking_in_tkinter/all_programs.html

Leider ein Sch* Layout, aber inhaltlich wirklich hilfreich, um zu verstehen, wie es grundsätzlich funktioniert. Dein Code und deine Probleme damit zeigen, dass du das noch nicht verstanden hast.

Danach helfen dann:
http://effbot.org/tkinterbook/tkinter-index.htm#introduction
http://infohost.nmt.edu/tcc/help/pubs/tkinter/

Ich denke, wenn du dir etwas Zeit für die Lektüre genommen hast, bekommst du deinen GUI-Aufbau samt Funktionalität - vielleicht bis auf etwas Kosmetik - selbst hin.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Freitag 24. Oktober 2008, 18:33

numerix hat geschrieben:Dein Code und deine Probleme damit zeigen, dass du das noch nicht verstanden hast.


Die Vermutung stimmt.

numerix hat geschrieben:Ich denke, wenn du dir etwas Zeit für die Lektüre genommen hast, bekommst du deinen GUI-Aufbau samt Funktionalität - vielleicht bis auf etwas Kosmetik - selbst hin.


Danke erstmal,
das werde ich tun.

Aber eine Frage sei gestattet: Generell ist es möglich, mit erträglichem Aufwand, meine Vorstellung umzusetzen??
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Beitragvon yipyip » Freitag 24. Oktober 2008, 19:19

Da ich grad' die passenden Bausteine zur
Hand hatte, war der Aufwand in der Tat ertraeglich.
:)

Wenn Du willst, kannst Du hier mal gucken.

http://paste.pocoo.org/show/88994/
(Als Anregung)

:wink:
yipyip
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Freitag 24. Oktober 2008, 19:23

mathi hat geschrieben:Aber eine Frage sei gestattet: Generell ist es möglich, mit erträglichem Aufwand, meine Vorstellung umzusetzen??


Absolut, ist keine große Sache.
Wenn du mal die Anleitung von Ferg (erster Link oben) durchgehst, wirst du schon auf den ersten Seiten einige Aha-Erlebnisse haben und dein Programm alleine schreiben können. Bis auf die ein oder andere kosmetische Feinheit vielleicht - aber das ist für den Anfang nicht so wichtig. Gegenüber deiner Konsolenfassung wird es auf jeden Fall ein optischer Fortschritt sein .. :wink:
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Montag 27. Oktober 2008, 12:13

Hallo allerseits,
vielen Dank für Eure Hilfe, aber irgendwie finde ich keinen Zugang. ich bin schon ein Stück weiter:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

from Tkinter import *
   
root = Tk()
root.wm_title(u'Bemessung')
menuobj=Menu(root) # Menükonstruktor
root.config(menu=menuobj)
progmenu=Menu(menuobj)

menuobj.add_cascade(label=u'Programm', menu=progmenu)

def interpol():
    root.wm_title(u'Interpolation')
    textfenster.insert(END,u'\ngegeben: x | gesucht: y ')
    eingabe.focus_force()
   
    #lab('Wert X1 mit X1<x: ')
   
    #def X1(*event):
        #X1=eingabe.get()
        #print X1
        #textfenster.insert(END, '\n X1 ='+eingabe.get())
       
    #X2=u'Wert X2 mit X2>x: '

    #Y1=u'Wert Y1 mit y=?: '

    #Y2=u'Wert Y2 mit y=?: '

    #x=u'Wert x: '

    #y=(x-X1)*(Y2-Y1)/(X2-X1)+Y1
    #print u'Ergebnis y= ',y
   
progmenu.add_command(label=u'Interpolation',command=interpol)
progmenu.add_separator()

textfenster = Text(root)
textfenster.pack()

labeltext=Label(root,text=u'Programmhinweise')
labeltext.pack()

variable=u'variable= '

lab=Label(root,text=variable)
lab.pack(side = LEFT)
def Ok(*event):
    xGet=eingabe.get()
    #if xGet==0:
    #    interpol()
    print xGet
    textfenster.insert(END, '\n' +variable+ eingabe.get())
eingabe = Entry(root,width=60)
eingabe.pack(side=LEFT)
eingabe.bind("<Return>", Ok)
eingabe.focus_force()

but = Button(root,text=u'Ok', command = Ok)
but.pack(side = LEFT)

root.mainloop()


aber: wenn ich das Programm starte, kann ich oben das Programm "Interpolation" auswählen, dann erscheint im Textfenster eine Info, ich kann nun unten eine Variable eingeben und ENTER: der Wert wird xGet zugewiesen und oben als variable=... ausgegeben.

Was ich möchte ist: das Label "Programmhinweise" während der Laufzeit des Programms "Interpolation" ändern, und die "variable" nach jeder eingabe durch die nächste erforderliche ändern, sodass als Anzeige im textfeld:

gegeben: x | gesucht: y
X1= 15
X2=20
Y1=10
Y2=50
x=17
Ergebnis: y= ...

erscheint. Wie kann ich die Label ändern?

nebenbei:
MUß ich wirklich Objektorientiert arbeiten, denn ich begreife den Sinn auch nach lektüre o.g. Links für speziell dieses Progamm nicht.
BlackJack

Beitragvon BlackJack » Montag 27. Oktober 2008, 12:22

IMHO ist OOP für GUI-Programmierung wichtig, ohne bekommt man schnell unübersichtliche Programme.

Mir scheint auch, Du willst immer noch den linearen Programmierstil von dem Konsolenprogramm erzwingen -- das ist keine gute Idee. Präentiere dem Benutzer alle Eingabefelder auf einmal. Die kann er dann ausfüllen und beim Druck auf einen 'Ok'- oder 'Berechnen'-Knopf werden dann die Werte ausgelesen und die Berechnung durch geführt.

Hast Du Dir die Lösung mit EasyGui mal angeschaut?
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Montag 27. Oktober 2008, 12:45

BlackJack hat geschrieben:
Mir scheint auch, Du willst immer noch den linearen Programmierstil von dem Konsolenprogramm erzwingen -- das ist keine gute Idee. Präentiere dem Benutzer alle Eingabefelder auf einmal. Die kann er dann ausfüllen und beim Druck auf einen 'Ok'- oder 'Berechnen'-Knopf werden dann die Werte ausgelesen und die Berechnung durch geführt.


Das Prinzip meines Programmes ist es, ALLES nur mit dem Numpad einzugeben also nur Zahlen und ENTER. Da ich möglichst schnell zu einem verwertbaren Ergebnis kommen möchte. Des Weiteren die Textausgabe um per copy and paste die Ausgabe weiterzuverwenden (-> mit griechischen Buchstaben :-))
Das ist eine Grundbedingung des Programmes. Alle Eingabefelder auf einmal scheidet aus.

BlackJack hat geschrieben:Hast Du Dir die Lösung mit EasyGui mal angeschaut?


Ja, aber ich möchte nicht alle Eingabefelder auf einmal und wollte mich bei der Gelegenheit ein wenig in TKInter einarbeiten. Die o.g. GUI ist für meine Zwecke richtig, wenn ich das noch richtig einbauen könnte.

Über diese GUI sind dann am Ende 16 Programme lauffähig, die alle dem selben Prinzip folgen, das Programm "Interpolation" ist nur zur Erarbeitung des Prinzips.
BlackJack

Beitragvon BlackJack » Montag 27. Oktober 2008, 12:55

Die Numpad-Eingabe und Anzeige aller Eingabefelder schliessen sich ja nicht gegenseitig aus. Du kannst die Eingabetaste ja an die `Entry`-Exemplare binden und mit "gehe zum nächsten `Entry`" belegen.

Wenn da 16 einzelne Berechnungsprogramme unter einer GUI zusammen gefasst werden sollen, spricht das übrigens auch für OOP.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Montag 27. Oktober 2008, 13:06

ich würde gerne diesen linearen Verlauf beibehalten, wenn das irgendwie geht, nur bin ich da ohne ein wenig Hilfe (zur Selbsthilfe) aufgeschmissen.
Im grunde haben alle Programme gemeinsam:
1. gib eine Zahl ein
2. reche etwas, vergleiche etwas
3. gib einen Hinweis aus
4. gib noch eine Zahl ein
5. gib das Ergebnis aus

Ich werde also erst einmal schauen, das obige Programm auf OOP umzuschreiben und mich dann wieder melden??
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Montag 27. Oktober 2008, 16:19

ich frage einfach hier weiter weil es dazugehört:

Wie kann ich den Labeltext

Code: Alles auswählen

labeltext=tk.Label(root,text=u'Programmhinweise')
labeltext.pack()
nachträglich, also im laufenden Programm ändern?

gefunden: label.config(text='...')
abgdf

Beitragvon abgdf » Montag 27. Oktober 2008, 20:03

Hi,
Wie kann ich den Labeltext nachträglich, also im laufenden Programm ändern?

Dazu habe ich mal geschrieben:
6. Changes of Variable-Values at Application-Runtime and the "Tkinter.Variable"-Object

Some widgets like "Tkinter.Label" accept a "textvariable"-argument instead of the "text"-argument.
With it, the displayed text can be changed while the main-loop of the program is running.

While you can pass an ordinary Python-string with the "text"-argument like in

text = "Hello"

this isn't enough for "textvariable".

For this a special object called "Tkinter.Variable" is needed.

This object isn't difficult to use, but you have to know, when you need it.

If a Tkinter-main-window is already defined, you can get an instance of a "Tkinter.Variable" just like this:

mytkvar = Tkinter.Variable()

Then its value can be set with:

mytkvar.set("Hello")

Then, the label can be defined with the "textvariable"-argument and the "Tkinter.Variable"-object:

label = Tkinter.Label(mainwindow, textvariable = mytkvar)

Later, when the program is running, the text displayed in the label can be dynamically changed just doing:

mytkvar.set("World")

The value stored in the "Tkinter.Variable"-object can be accessed as a Python-datatype any time doing:

myPythonVariable = mytkvar.get()

(There are some flavours of "Tkinter.Variable" called "Tkinter.StringVar", "Tkinter.IntVar", "Tkinter.DoubleVar" and "Tkinter.BooleanVar".)

Basically, "Tkinter.Variable"-objects must be used in widget-arguments instead of Python-strings or -integers, when the variable-values can change dynamically at application-runtime.

This is typically the case, when

* the "textvariable"-argument,
* the Radiobutton-widget,
* the Checkbutton-widget.

is used.

There's another way of changing the resource-options of some widgets at application-runtime manually by using their ".configure()"-method.

HTH
ich würde gerne diesen linearen Verlauf beibehalten, wenn das irgendwie geht

Nein, das geht nicht: Bei

Code: Alles auswählen

root.mainloop()

ist es vorbei mit jeder Art von linearem Verlauf.
Gewöhn' Dich dran !

Gruß
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Dienstag 28. Oktober 2008, 07:37

na ok, dann sehen wir mal wo der Weg mich hinführt.

Jetzt habe ich alles objektorientiert Programmiert, leider gibt es beim Aufruf des Programmes Interpolation eine Fehlermeldung, die ich nicht beseitigen kann...
Ist mein Code sonst soweit ok??

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

#from Tkinter import *
import Tkinter as tk

class Main:
    def Ok(self,*events):
        xGet=eingabe.get()
        #if xGet==0:
        #    interpol()
        print xGet
        textfenster.insert(tk.END, '\n' +text+ eingabe.get())
       
    def __init__(self,root):
        self.myRoot=root
       
        self.menuobj=tk.Menu(root) # Menükonstruktor
        root.config(menu=self.menuobj)
        self.progmenu=tk.Menu(self.menuobj)

        self.menuobj.add_cascade(label=u'Programm', menu=self.progmenu)
        self.progmenu.add_command(label=u'Interpolation',command=interpolation)
        self.progmenu.add_separator()

        self.textfenster = tk.Text(root)
        self.textfenster.pack()

        self.labeltext=tk.Label(root,text=u'Programmhinweise')
        self.labeltext.pack()

        self.lab=tk.Label(root,text='   ')
        self.lab.pack(side = tk.LEFT)
       
        self.eingabe = tk.Entry(root,width=60)
        self.eingabe.pack(side=tk.LEFT)
        self.eingabe.bind("<Return>", self.Ok)
        self.eingabe.focus_force()

        self.but = tk.Button(root,text=u'Ok', command = self.Ok)
        self.but.pack(side = tk.LEFT)     

class interpolation:
    def __init__(self):
        root.wm_title(u'Interpolation')
        self.textfenster.insert(tk.END,u'\ngegeben: x | gesucht: y ')
        self.eingabe.focus_force()
        self.labeltext.config(text=u'Gib den Wert ein')
        self.lab.config(text=u'Wert X1 mit X1<x: ')
        text=u'X1='
        #self.Ok()
        #eingabe.insert(0,u'15')   
        #item.get_child().set_text('Spam')
        #def X1(*event):
            #X1=eingabe.get()
            #print X1
            #textfenster.insert(END, '\n X1 ='+eingabe.get())
           
        #X2=u'Wert X2 mit X2>x: '

        #Y1=u'Wert Y1 mit y=?: '

        #Y2=u'Wert Y2 mit y=?: '

        #x=u'Wert x: '

        #y=(x-X1)*(Y2-Y1)/(X2-X1)+Y1
        #print u'Ergebnis y= ',y

root = tk.Tk()
root.wm_title(u'Bemessung')

myapp=Main(root)
root.mainloop()
BlackJack

Beitragvon BlackJack » Dienstag 28. Oktober 2008, 08:27

`interpolation` ist kein Programm sondern eine Klasse. Und die Fehlermeldung dürfte wahrscheinlich sein, dass es `self.textfenster` nicht gibt. Woher auch. Das ist nicht OOP, denn anscheinend hast Du das mit den Objekten noch nicht verstanden, wenn Dir nicht klar ist, warum das nicht funktioniert.

`root` wird von beiden Klassen aus direkt auf Modulebene angesprochen, ist also ein globales Objekt. Das sollte nicht sein. Am besten hat man auf Modulebene nur Konstanten, Klassen und Funktionen, dann kommt man gar nicht erst in die Versuchung so etwas zu tun.
mathi
User
Beiträge: 314
Registriert: Dienstag 27. November 2007, 14:30

Beitragvon mathi » Dienstag 28. Oktober 2008, 08:55

ja das stimmt wohl, ich begreife das einfach nicht. Hab zwar noch ein schönes Beispiel vorliegen, aber ich steige nicht hinter den Sinn und die Funktion des Ganzen :cry:

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder