MVC

Fragen zu Tkinter.
lulumagulu
User
Beiträge: 4
Registriert: Donnerstag 14. Juni 2007, 15:20

MVC

Beitragvon lulumagulu » Donnerstag 14. Juni 2007, 15:30

Hallo,
ich bin neu in der Community und habe auch schon gleich das erste Problem.
Wie gesagt, ich habe ein kleines Problem und drehe mich irgendwie immer im kreis. Ich möchte eine Graphische Oberfläche bauen, die mir die Primzahlen zwischen 2 bestimmten Werten ausgibt.
Ich habe eine Klasse Primzahlen die mir die Primzahlen berechnet, jedoch weiß ich nicht, wie ich sie in die Oberfläche integriere.

Vielleicht könntet ihr mir ja helfen und mir ein paar Tipps geben um meinen Programmierstil zu verbessern. Bin noch Anfänger.

Code: Alles auswählen



from Tkinter import *

class Primzahlen():
    def __init__(self,obergrenze,untergrenze):
        self.obergrenze = obergrenze
        self.untergrenze = untergrenze

    def berechne(self):
        for n in range(self.obergrenze, self.untergrenze):
            for x in range(2, n):
                if n % x == 0:
                    break
            else:
                print n
               
fenster = Tk(className="Primzahlengenerator")
frame1 = Frame(fenster)
frame2 = Frame(fenster)
label1 = Label(frame1,text="Obere Grenze")
label2 = Label(frame1, text="Untere Grenze")
scrollbar = Scrollbar(frame1)
scrollbar.pack(side=RIGHT, fill=Y)
text = Text(frame1,
            width=40, height=20,
            yscrollcommand=scrollbar.set)
entry1 = Entry(frame1)
entry2 = Entry(frame1)
button = Button(frame1, text="Berechne Primzahlen",)

       
frame1.pack()
frame2.pack()
label1.pack()
entry1.pack()
label2.pack()
entry2.pack()
button.pack()
text.pack()
fenster.mainloop()
BlackJack

Beitragvon BlackJack » Donnerstag 14. Juni 2007, 17:04

Die Primzahlberechnung in eine Klasse zu stecken macht nicht viel Sinn. Das könnte eine einfache Funktion sein, die Unter- und Obergrenze als Argumente beim Aufruf bekommt.

Und sie muss natürlich das Ergebnis in irgendeiner Form, zum Beispiel in einer Liste, zurückgeben und nicht mit ``print`` ausgeben. Das sieht man ja nicht in der GUI.

Um beides zu verbinden brauchst Du eine Funtkion oder Methode, die beim `Button` als `command` angegeben wird, die Grenzen aus der GUI ausliest, die Primzahlberechnung aufruft und das Ergebnis wieder in ein GUI-Element schreibt.
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Donnerstag 14. Juni 2007, 17:13

class Foo(): ist eine schlechte Idee. Entweder class Foo(object): (mit python2.2 und größer, aber kleiner als Python3 eine gute Idee) oder class Foo: (mit Python < 2.5 eine Idee, und solange du kein MI machst auch keine schlechte) oder class Foo: mit python3.

So. Jetzt hab ich jemanden verwirrt ;)

Sinn der Übung: class Foo(): geht nur mit python2.5 und höher.
TUFKAB – the user formerly known as blackbird
lulumagulu
User
Beiträge: 4
Registriert: Donnerstag 14. Juni 2007, 15:20

Beitragvon lulumagulu » Freitag 15. Juni 2007, 14:38

Hi,
danke erstmal für die Infos. Hab das jetzt so implementiert wie ihr das meintet.

Bekomme allerdings folgende Fehlermeldung:

Code: Alles auswählen


Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python25\lib\lib-tk\Tkinter.py", line 1403, in __call__
    return self.func(*args)
  File "C:\Dokumente und Einstellungen\Ismail Serin\Desktop\test.py", line 14, in berechne
    for n in range(c,d):
NameError: global name 'c' is not defined





Wie kann ich diesen Fehler beheben?
Wie kann ich Listen in einem textfeld ausgeben?


Code: Alles auswählen


# -*- coding: cp1252 -*-

from Tkinter import *



primzahlen= []
def berechne():
    for n in range(c,d):
        for x in range(2, n):
            if n % x == 0:
                break
        else:
                liste.append(n)
                print n

               
fenster = Tk(className="Primzahlengenerator")
frame1 = Frame(fenster)
frame2 = Frame(fenster)
label1 = Label(frame1,text="Obere Grenze")
label2 = Label(frame1, text="Untere Grenze")
scrollbar = Scrollbar(frame1)
scrollbar.pack(side=RIGHT, fill=Y)
text = Text(frame1,
            width=40, height=20,
            yscrollcommand=scrollbar.set)

entry1 = Entry(frame1)
entry2 = Entry(frame1)

a = entry1.get()
b = entry2.get()

if a != b:
    c = int(a)
    d = int(b)
else:
    pass

button = Button(frame1, text="Berechne Primzahlen", command=berechne)


frame1.pack()
frame2.pack()
label1.pack()
entry1.pack()
label2.pack()
entry2.pack()
button.pack()
text.pack()
fenster.mainloop()


[/code]
Zuletzt geändert von lulumagulu am Freitag 15. Juni 2007, 16:20, insgesamt 1-mal geändert.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Freitag 15. Juni 2007, 14:52

lulumagulu hat geschrieben:

Code: Alles auswählen

#...
a = entry1.get()
b = entry2.get()
#...

Hi, tk.Entry.get() liefert den Inhalt des Entrys immer als str, wie auch in der Fehlermeldung zu erkennen ist.
Wandel diesen einfach mit int() um.

Code: Alles auswählen

#...
a = int(entry1.get())
b = int(entry2.get())
#...


Gruß, jj
lulumagulu
User
Beiträge: 4
Registriert: Donnerstag 14. Juni 2007, 15:20

Beitragvon lulumagulu » Freitag 15. Juni 2007, 14:54

Danke,

habe das jetzt gemacht.
Bekomme aber jetze eine neue Fehlermeldung, die ich nicht verstehe.
Siehe oben.
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Freitag 15. Juni 2007, 15:13

Sind vlt. a und b gleich? Wenn du das schon während der Initialisierung testest, ist ja klar, dass der Inhlat der beiden Entrys gleich ist (beide sind ja leer). Verschiebe am Besten alles in die Funktion:

Code: Alles auswählen

def berechne(c, d):
    for n in range(c,d):
        for x in range(2, n):
            if n % x == 0:
                break
        else:
                liste.append(n)
                print n
#...
button = Button(frame1, text="Berechne Primzahlen", \
command=lambda: berechne(int(entry1.get()), int(entry2.get()))

ok, is nicht die beste lösung, aber ist ja auch nur en bsp...
_____
Außerdem solltest du deine probleme in den alten Beiträgen nicht durch neue ersetzen, das verwirrt.
lulumagulu
User
Beiträge: 4
Registriert: Donnerstag 14. Juni 2007, 15:20

Beitragvon lulumagulu » Freitag 15. Juni 2007, 15:28

Hey cool.
Dankesehr!

Muss mir jetzt nur noch anschaun, was das Lambda eigentlich genau macht.

Kann mir villeicht noch jemand bitte sagen wie ich listen in Tkinter ausgeben kann?

Muss ich vll. zuerst die Listen in Strings umwandeln?

Code: Alles auswählen



    for i in range(1,len(primzahlen)):
        werte += str(primzahlen[i])
        print werte
        if i != len(primzahlen)-1:
            werte += ","
        else:
            pass






EDIT:
Ich habe das Problem jetzt mit einer Listbox realisiert. Das Problem allerdings ist, dass wenn die Liste zu lang ist, dass der Zeilenumbruch fehlt?

Wie bekomme ich einen Zeilenumbruch in der Listebox hin?

Code: Alles auswählen

   

    fenster2= Tk()
    liste = Listbox(fenster2)
    liste.insert(END, primzahlen)
    liste.pack()
    fenster2.mainloop()

Zizibee
User
Beiträge: 166
Registriert: Donnerstag 12. April 2007, 08:36

Beitragvon Zizibee » Montag 18. Juni 2007, 07:29

lulumagulu hat geschrieben:Wie bekomme ich einen Zeilenumbruch in der Listebox hin?


Suchst du so etwas in der Art?

Code: Alles auswählen

liste.insert(END, '\n' + primzahlen)


[EDIT:]
Ich hab noch mal darüber nachgedacht, das löst dein Problem wohl nicht. Allerdings bin ich mir nicht so ganz sicher, wo genau dein Problem eigentlich ist, bei mir hat er am Zeilenende immer automatisch eine neue Zeile begonnen...
Zuletzt geändert von Zizibee am Montag 18. Juni 2007, 08:06, insgesamt 1-mal geändert.
BlackJack

Beitragvon BlackJack » Montag 18. Juni 2007, 08:03

lulumagulu hat geschrieben:

Code: Alles auswählen

    for i in range(1,len(primzahlen)):
        werte += str(primzahlen[i])
        print werte
        if i != len(primzahlen)-1:
            werte += ","
        else:
            pass


Diese gesamte Schleife kann man durch eine Zeile ersetzen:

Code: Alles auswählen

        werte = ','.join(map(str, primzahlen))
Benutzeravatar
Michael Schneider
User
Beiträge: 566
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Beitragvon Michael Schneider » Mittwoch 20. Juni 2007, 22:33

Hi Lulumagulu,

BlackJack hat geschrieben:Diese gesamte Schleife kann man durch eine Zeile ersetzen:

Code: Alles auswählen

        werte = ', '.join(map(str, primzahlen))

... und diesen String packst Du dann in Dein (angepasstes) Textwidget:

Code: Alles auswählen

text = Text(frame1, wrap=WORD,
            width=40, height=20,
            yscrollcommand=scrollbar.set)
text.delete("1.0", END)
text.insert("1.0", werte)

Erläuterung:
wrap=WORD -> Zeilenumbruch an Wortende
text.delete -> entfernt den Inhalt von Zeile 1, Spalte 0 (oben links) bis zum Ende
text.insert -> fügt den String werte oben links ins Textfeld ein

Grüße,
der Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder