Seite 1 von 1
Text zeilenweise ausgeben
Verfasst: Dienstag 9. Mai 2006, 13:01
von Unr3al
Hallo,
ich habe eine Datei, aus der ich Text in einem Label zeilenweise ausgeben will. Geschehen soll das Ganze nach dem man auf den Button "Nächste Zeile" gedrückt hat. Wenn das Dateiende erreicht ist, soll "Dateiende erreicht" ausgegeben werden.
Das habe ich bis jetzt hinbekommen:
Code: Alles auswählen
from Tkinter import *
def dateilesen():
datei = open('text.txt','r')
while 1:
line = datei.readline()
if not line:
print "Ende der Datei erreicht"
break
ausgabe.configure(text=line),
break
datei.close()
fenster = Tk()
fenster.title('Test 4')
fenster.label = Label(master=fenster, text='Zeilenleser',
font=('Arial',16, 'bold underline'),fg='blue')
fenster.label.pack()
fenster.button = Button(master=fenster,text='Naechste Zeile',
font=('Arial',12,'bold'),command=dateilesen)
fenster.button.pack(side=RIGHT,padx=5)
ausgabe = Label(master=fenster,font=('Arial',12),
fg='blue',bg='yellow',height='2', width='50', relief='sunken')
ausgabe.pack(padx='10',pady='10')
fenster.mainloop()
Das Problem dabei ist, dass momentan nur die erste Zeile ausgegeben wird. Mir ist bewusst, dass meine dateilesen()-Funktion wohl nicht richtig ist, finde aber keine Lösung. Außerdem würde ich gerne wissen, wie ich die Zeilen linksbündig ausgegeben bekommen. Für jede Hilfe bin ich im Voraus sehr dankbar.
Viele Grüße,
Unr3al
Verfasst: Dienstag 9. Mai 2006, 13:05
von mr.hide
So weit ich das sehe, hast du ein break zuviel... in der while schleife
Verfasst: Dienstag 9. Mai 2006, 13:20
von Buell
Das Hauptproblem ist, dass deine Methode dateilesen gar nicht weiß, welche Zeile die nächste sein soll. So wie ich deinen Code verstehe, soll auf einen Button gedrückt werden und dann soll die nächste Zeile ausgegeben werden. Dabei solltest du der Methode eben sagen welches die nächste Zeile ist. Ich würde das komplett anders lösen. Ich würde die Methode nur 1x aufrufen und dann wenn möglich alle Zeilen (natürlich ist dies abhängig von der Dateigröße) in eine Liste schreiben und dann in dieser Liste nur "weiterwandern" für die Ausgabe, etwa so:
Code: Alles auswählen
from Tkinter import *
dateiinhalt = []
CurLine = 0
MaxLine = 0
def dateilesen():
datei = open('text.txt','r')
while 1:
dateiinhalt.Append(datei.readline())
MaxLine += 1
if not line:
print "Ende der Datei erreicht"
break
datei.close()
def NextRowOut():
CurLine += 1
if(CurLine < MaxLine):
ausgabe.configure(text=dateiinhalt[CurLine])
else print "keine weitern Zeilen"
dateilesen()
fenster = Tk()
fenster.title('Test 4')
fenster.label = Label(master=fenster, text='Zeilenleser',
font=('Arial',16, 'bold underline'),fg='blue')
fenster.label.pack()
fenster.button = Button(master=fenster,text='Naechste Zeile',
font=('Arial',12,'bold'),command=NextRowOut)
fenster.button.pack(side=RIGHT,padx=5)
ausgabe = Label(master=fenster,font=('Arial',12),
fg='blue',bg='yellow',height='2', width='50', relief='sunken')
ausgabe.pack(padx='10',pady='10')
fenster.mainloop()
PS: ungetesteter Quelltext
Verfasst: Dienstag 9. Mai 2006, 13:56
von Unr3al
Erst einmal vielen Dank für Hilfe. Der Interpreter spuckt ein Paar Fehler aus, mit manchen werde ich nicht fertig und zwar:
UnboundLocalError: local variable 'MaxLine' referenced before assignment
UnboundLocalError: local variable 'CurLine' referenced before assignment
Wie kann ich sie umgehen?
Viele Grüße,
Unr3al
Verfasst: Dienstag 9. Mai 2006, 15:14
von gerold
Hi Unr3al!
Bitte erwarte nicht zu viel. Ich wollte nur eine kleine Übung machen, damit ich nicht alles vergesse, bevor ich es zum ersten Mal brauche. Da ist mir deine Aufgabenstellung gerade recht gekommen. Dein Beispiel war mit
Tkinter meines ist mit
wxPython. Und als Anfänger gleich mit mehreren GUI-Toolkits konfrontiert zu werden ist auch nicht toll. Sorry!
Wenn du mit meinem Beispiel nicht zurecht kommst --> einfach ignorieren. Es gibt auch andere Möglichkeiten um dein Problem zu lösen. Man muss nicht Yield nehmen.
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
"""
Liest Zeile für Zeile
"""
import wx
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "Zeilenleser", size = (300, 200))
panel = wx.Panel(self)
self.box = wx.BoxSizer(wx.VERTICAL)
self.label = wx.StaticText(panel, -1, "Seavas")
self.label.SetBackgroundColour("white")
self.box.Add(self.label, 1, wx.ALL | wx.EXPAND, 6)
self.button = wx.Button(panel, -1, u"Nächste Zeile")
self.box.Add(self.button, 0, wx.ALL | wx.EXPAND, 3)
self.button.Bind(wx.EVT_BUTTON, self.on_button)
panel.SetSizer(self.box)
self.lines = self.read_lines()
self.label.SetLabel(self.lines.next())
def read_lines(self):
"""
Liest die Datei Zeilenweise aus.
"""
f = file("hallo.txt", "rU")
for line in f:
yield line
f.close()
def on_button(self, event):
"""
Schreibt den Text in das Label
"""
try:
line = self.lines.next()
except StopIteration:
line = "Fertig!!!\n"
self.button.Enable(False)
self.label.SetLabel(
self.label.GetLabel() + line
)
self.box.Layout()
app = wx.PySimpleApp()
frame = MyFrame()
frame.Show()
app.MainLoop()
mfg
Gerold

Verfasst: Dienstag 9. Mai 2006, 16:37
von Unr3al
Hallo gerold,
ich danke dir, da ich aber wxPython noch gar nicht kenne, bleibe ich erst einmal bei Tkinter.
Ich habe den Code jetzt bearbeitet und es funktioniert nur noch eine Sache nicht, und zwar die Liste dateiinhalt hat in der Funktion dateilesen() richtigen Inhalt, in der Funktion NextRowOut() ist die Liste leer. Ich vermute, dass es irgendwas mit Sichtbarkeiten zu tun hat, kann den Fehler aber trotzdem nicht finden, vielleicht kann jemand mit mehr Erfahrung mir helfen.
Hier ist noch einmal der Code der beide Funktionen:
Code: Alles auswählen
from Tkinter import *
dateiinhalt = []
CurLine = 0
MaxLine = 0
def dateilesen():
global MaxLine
datei = open('test.txt','r')
while 1:
dateiinhalt = datei.readline()
#dateiinhalt.append(datei.readline())
MaxLine += 1
print MaxLine
print dateiinhalt
if not dateiinhalt:
break
datei.close()
def NextRowOut():
global CurLine
CurLine += 1
print dateiinhalt
if(CurLine < MaxLine):
ausgabe.configure(text=dateiinhalt[CurLine])
else: ausgabe.configure(text="Ende der Datei erreicht")
dateilesen()
Verfasst: Dienstag 9. Mai 2006, 16:48
von Buell
versuchs mal so:
Code: Alles auswählen
dateiinhalt = []
CurLine = 0
MaxLine = 0
def dateilesen():
global MaxLine
datei = open('test.txt','r')
inhalt = []
while 1:
inhalt.append(datei.readline())
MaxLine += 1
print MaxLine
if not inhalt[MaxLine-1]:
break
datei.close()
return inhalt
def NextRowOut():
global CurLine
CurLine += 1
print dateiinhalt[CurLine]
if(CurLine < MaxLine):
ausgabe.configure(text=dateiinhalt[CurLine])
else: ausgabe.configure(text="Ende der Datei erreicht")
dateiinhalt = dateilesen()
Verfasst: Dienstag 9. Mai 2006, 22:15
von gerold
Unr3al hat geschrieben:Hallo gerold, ich danke dir, da ich aber wxPython noch gar nicht kenne, bleibe ich erst einmal bei Tkinter.
Hi Unr3al!
Kein Problem. Das habe ich mir schon gedacht. Hier noch mein Tkinter-Beispiel:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
import Tkinter as tk
class MeinFenster(tk.Tk):
def __init__(self):
"""
Baut das Fenster auf und zeigt es an.
"""
# Fenster initialisieren
tk.Tk.__init__(self)
# Fenstertitel
self.title("Test 4")
# Überschrift
self.label = tk.Label(
self, text = 'Zeilenleser',
font = ('Arial',16, 'bold underline'), fg = 'blue'
)
self.label.pack()
# Button
self.button = tk.Button(
master = self, text = 'Naechste Zeile',
font = ('Arial', 12, 'bold'), command = self.read_line
)
self.button.pack(side = tk.RIGHT, padx = 5)
# Ausgabefeld
self.ausgabe = tk.Label(
self, font = ('Arial',12), fg='blue', bg = 'yellow',
height = '2', width = '50', relief = 'sunken'
)
self.ausgabe.pack(padx = '10', pady = '10')
# Datei komplett in Liste einlesen lassen
self.read_file()
def read_file(self):
"""
Datei komplett einlesen
"""
f = file("hallo.txt", "rU")
self.lines = f.readlines()
f.close()
def read_line(self):
"""
Bei jedem Aufruf dieser Methode wird der erste Eintrag aus der
Liste entfernt und in das Ausgabe-Label geschrieben.
"""
if len(self.lines) > 0:
line = self.lines.pop(0)
else:
line = "Ende der Datei erreicht\n"
self.ausgabe.configure(text = line)
if __name__ == "__main__":
mein_fenster = MeinFenster()
tk.mainloop()
Der Nachteil dieses Code ist, dass das Textfile komplett eingelesen und im Speicher gehalten wird. Das ist bei so einem Beispiel natürlich kein Problem, aber wenn die Textdatei groß ist, dann wird der Speicher komplett zugemüllt. Dann würde ich eine Methode wählen, die die Datei offen hält und immer nur bei Bedarf eine einzelne Zeile ausliest.
mfg
Gerold

Verfasst: Mittwoch 10. Mai 2006, 16:30
von Unr3al
Hallo gerold,
vielen Dank, dein Code funktioniert einwandfrei.
Viele Grüße,
Unr3al
Verfasst: Mittwoch 10. Mai 2006, 16:50
von gerold
Unr3al hat geschrieben:dein Code funktioniert einwandfrei.
Hi Unr3al!
Das war mir klar.
Die Frage ist -- Verstehst du den Code und kannst du daraus etwas lernen?
mfg
Gerold
