GUI in Programm integrieren

Fragen zu Tkinter.
BlackJack

@klaus: Die Funktion hat immer ein Argument `self`, das steht da als erstes in der Argumentliste. Das innerhalb der Methode `self` nicht definiert ist, ist einfach nicht möglich. Und `self` wird auch übergeben wenn man die Funktion von der Instanz holt und dabei eine gebundene Methode bekommt. Da ist absolut kein Unterschied ob man das nun bei `bind` oder beim Button als `command` übergibt.
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Oh, ich hab meinen Fehler gemerkt. Ich dachte die Funktion erhält als Argument das Event, aber das wird gar nicht übergeben wenn man sie mit command aufruft. :oops:
Habs schon umgeschrieben und es funktioniert.

Übrigens, seh ich des richig, das ich Variablen in der Klasse zwar lesen kann, wenn sie außerhalb definiert sind, wenn ich sie aber ändern will, muss ich sie als global deklarieren?
BlackJack

Ja, aber Du willst sie nicht ändern. Oder zumindest solltest Du das nicht wollen.
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Wie meinst du das? Ich ändere doch z.B. switch und counter.

edit: Ich glaub ich mach für heute Schluss. Ich programmier erst morgen weiter.
http://klausweidinger.kl.funpic.de
BlackJack

Ich meine man will keine "globalen" Variablen ändern, das ist unsauber. Du könntest sie zum Beispiel an das Objekt binden.
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Ok, das stimmt, das ich eigentlich keine verwenden will. Wie ich es sonst machen könnte hab ich mir noch nicht überlegt, eine Variable an ein Objekt binden kann ich noch nicht, schau ich mir aber gleich mal an.

edit: hab die globalen Variablen ersetzt (habs dummerweise nicht mit replace gemacht, deswegen hats ein bisschen gedauert, bis ich alle gefunden hab, aber das Programm läuft jetzt soweit.)
Zuletzt geändert von klaus am Donnerstag 27. September 2007, 20:16, insgesamt 1-mal geändert.
http://klausweidinger.kl.funpic.de
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Ich bin gerade dabei, die Benotung einzubauen, aber ich hab da ein ganz komisches Problem:

bei mir ergibt 1/4, 2/4 und 3/4 immer 0, normalerweise müssten aber 0.25, 0.5 und 0.75 rauskommen (aber nur, wenn ich ein Skript ausführe, in der IDLE funktionierts).

Ich habe Python nach den Installationsanweisungen von "Python4kids" installiert, deshalb müsste der Operator / eigentlich immer die Gleitkommadivision ausführen. Bei mir rechnet er aber in diesem Skript die Ganzzahldivision.
Kann mir jemand weiterhelfen.
http://klausweidinger.kl.funpic.de
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Entweder du schreibst das an den Anfang:

Code: Alles auswählen

from __future__ import division
Oder du dividierst Gleitkommazahlen:

Code: Alles auswählen

>>> 3/4.0
0.75
>>> 3/float(4)
0.75
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Danke für den Tipp. Ich werds versuchen und meld mich wieder wenns funktioniert.

edit: funktioniert

Allerdings hab ich immer noch keine Antwort auf die Frage von vor ein paar Tagen bekommen: Kann man Entry-Widgets resetten, also dass sie wieder leer sind?

Außerdem würde mich interessieren, warum ich in einer Klasse

Code: Alles auswählen

self.entry = Entry(...)
mit self. aber

Code: Alles auswählen

frame = Frame(...)
ohne self. schreiben muss.
http://klausweidinger.kl.funpic.de
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

Hi,

Code: Alles auswählen

import Tkinter 

def lerreEntry(xWidget):
    xWidget.delete(0, Tkinter.END)
    
def widgetSetText():
    lerreEntry(entry)
    
rt = Tkinter.Tk()

entry = Tkinter.Entry(rt)
entry.pack()
b = Tkinter.Button( rt, 
                text='Leere Entry',
                command=widgetSetText)
                
""" oder, command=lambda e=entry: e.delete(0, Tkinter.END)) """

b.pack()

rt.mainloop()
ich hoffe das hilft dir weiter.

Gruss
pyStyler
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

wenn ich das richtig sehe, resetted die Zeile
xWidget.delete(0, Tkinter.END)
das Entry-Widget.
In meinem Programm heißt die Zeile dann so:
self.entry.delete(0, END)
(Tkinter mit from importiert.)
http://klausweidinger.kl.funpic.de
pyStyler
User
Beiträge: 311
Registriert: Montag 12. Juni 2006, 14:24

klaus hat geschrieben:wenn ich das richtig sehe, resetted die Zeile
xWidget.delete(0, Tkinter.END)
ja richtig.
klaus hat geschrieben: das Entry-Widget.
In meinem Programm heißt die Zeile dann so:
self.entry.delete(0, END)
(Tkinter mit from importiert.)
wann das eine frage sein soll, dann ist deine vermutung auch hier richtig.
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Hab mal wieder ein Problem, das ich nicht verstehe:

Ich möchte 2 Gruppen von Radioboxen machen, eine die für den Stoff der Abfrage zuständig ist, und die andere soll den Modus festlegen.
Jetzt hab ich des schon mal grob entworfen, aber obwohl ich den beiden Gruppen verschiedene Variablen gegeben habe, beeinflussen sie sich gegenseitig.

edit: bin jetzt auf .grid umgestiegen. Des is ja viel leichter anzuordnen.

Hier mal der neue Code:

Code: Alles auswählen

from __future__ import division
import Tkinter as tk
import math
index = [["1", "2", 0], ["2", "3", 0], ["3", "5", 0], ["4", "7", 0]]

class I:
    question, solve, stat = "default", "default", "default"
    points, counter, switch = 0, 0, 0
    topic, von, bis, modus, dauer = "", 0, 0, "", 0
    def __init__(self, master):
        I.question, I.solve, I.stat = index[0]
        self.label = tk.Label(master, text=I.question, pady=10)
        self.label.grid(row=0, column=0)
        self.entry = tk.Entry(master, width=100)
        self.entry.bind("<Return>", self.correct)
        self.entry.grid(row=1, column=0)
        self.button = tk.Button(master, text="-------", width=97, command=self.next)
        self.button.grid(row=2, column=0)
        self.top_()
        
    def top_(self):
        top = tk.Toplevel()
        tk.Label(top, text="Stoff:").grid(row=0, rowspan=2)
        tk.Label(top, text="Lektionen:").grid(row=2, rowspan=2)
        tk.Label(top, text="Modus:").grid(row=4)
        tk.Label(top, text="Dauer:").grid(row=5)

        self.radio11 = tk.Radiobutton(top, text="Roma", variable=I.topic, value="rom")
        self.radio11.grid(row=0, column=1)
        self.radio12 = tk.Radiobutton(top, text="Prima", variable=I.topic, value="prm")
        self.radio12.grid(row=0, column=2)
        self.radio13 = tk.Radiobutton(top, text="Felix", variable=I.topic, value="flx")
        self.radio13.grid(row=0, column=3)
        self.radio14 = tk.Radiobutton(top, text="Ratio", variable=I.topic, value="zus")
        self.radio14.grid(row=1, column=1)
        self.radio15 = tk.Radiobutton(top, text="Grammatik", variable=I.topic, value="grm")
        self.radio15.grid(row=1, column=2, columnspan=2)

        self.scale1 = tk.Scale(top, from_=1, to=120, orient=tk.HORIZONTAL, sliderlength=10, command=self.sc1)
        self.scale1.grid(row=2, column=1, columnspan=3)
        self.scale2 = tk.Scale(top, from_=1, to=120, orient=tk.HORIZONTAL, sliderlength=10, command=self.sc2)
        self.scale2.grid(row=3, column=1, columnspan=3)

        self.radio21 = tk.Radiobutton(top, text="Lern", variable=I.modus, value="lrn")
        self.radio21.grid(row=4, column=1)
        self.radio22 = tk.Radiobutton(top, text="Abfr.", variable=I.modus, value="abf")
        self.radio22.grid(row=4, column=2)
        self.radio23 = tk.Radiobutton(top, text="Wdh.", variable=I.modus, value="wdh")
        self.radio23.grid(row=4, column=3)

        self.scale3 = tk.Scale(top, from_=1, to=500, orient=tk.HORIZONTAL, sliderlength=10)
        self.scale3.grid(row=5, column=1, columnspan=3)

        self.confirm = tk.Button(top, text="OK", width=38, command=self.select)
        self.confirm.grid(row=6, column=0, columnspan=4)

    def sc1(self, value):
        if self.scale1.get() > self.scale2.get():
            self.scale2.set(self.scale1.get())

    def sc2(self, value):
        if self.scale1.get() > self.scale2.get():
            self.scale1.set(self.scale2.get())

    def select(self):
        pass
##        I.von = self.scale1.get()
##        I.bis = self.scale2.get()
##        I.dauer = self.scale3.get()

    def correct(self, event):
##...
        
    def next(self):
##...

    def evaluate(self, err, von):
        mark = int(math.floor(1+(7.142*(1-(err/von)))))
        if mark > 5:
            mark = 6
        print "Du hast",err,"von",von,"Punkten! Note",mark
        
root = tk.Tk()
iface = I(root)
root.mainloop()
Zuletzt geändert von klaus am Montag 8. Oktober 2007, 16:23, insgesamt 3-mal geändert.
http://klausweidinger.kl.funpic.de
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Auch wenn das jetzt ein Doppelpost ist. Ich wüsste schon gerne wieso die beiden Radiobutton-Gruppen sich beeinflussen. Dieses Problem hält mich jetzt seit einer Woche auf und ich kann nicht weiterprogrammieren.
http://klausweidinger.kl.funpic.de
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Poste doch mal den kompletten Code des Stücks. Von wo kommen denn die Variablen? Wieso kommen sie nicht von self? Was ist I?
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

"I" ist die Klasse. Ich hab sie zuerst Iface genannt, da ich aber so viele Variablen habe, die an sie gebunden sind, habe ich den Namen abgekürzt.

edit: wieso kann ich eig. ältere Beiträge nicht mehr löschen?
http://klausweidinger.kl.funpic.de
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

1. Check- und Radiobuttons und alle anderen TkWidgets die Variablen erwarten, erwarten tk-Variablen, also tk.StringVar, tk.IntVar, ...
In deinem Fall tk.StringVar.
2. wieso ist das ne klassenvariable?
3. -> machs über self!
4. kommt bestimmt gleich von jmd. anderem

@edit: ua. weil dann der Rest keinen sinn mehr ergibt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

klaus hat geschrieben:edit: wieso kann ich eig. ältere Beiträge nicht mehr löschen?
Du kannst sie löschen, solange noch niemand drauf geantwortet hat. Wenn jemand drauf antwortet, zum Beispiel auf deinen Text bezug nimmt und du den Post dann löscht, dann steht der Antwortende doch ziemlich blöd da, wenn er auf etwas antwortet, was von dir gelöscht wurde und daher nicht mehr lesbar ist.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Dann solltest Du nicht so viele Namen daran binden, bzw. an die *Klasse* sowieso nicht. Da es zwei Fenster sind, könnte man das Ganze auch auf eine Klasse/Objekt pro Fenster aufteilen.

Zum eigentlichen Problem: Soweit ich weiss müssen die Argumente für `variable` vom Typ `Tkinter.StringVar`, `Tkinter.IntVar`, `Tkinter.DoubleVar` oder `Tkinter.BooleanVar` sein.
Benutzeravatar
klaus
User
Beiträge: 88
Registriert: Samstag 23. Juni 2007, 09:33
Wohnort: Kaufbeuren
Kontaktdaten:

Ok, dann mach ich zwei Klassen.

Ich hab die Beiden Variablen in tk.topic und tk.modus umbenannt und es klappt trotzdem nicht. Wie müssen die Variablen genau heißen und wie kann ich dann später auf sie zugreifen.
(Tkinter mit "as tk" importiert)
http://klausweidinger.kl.funpic.de
Antworten