Canvas feste Grösse geben

Fragen zu Tkinter.
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Canvas feste Grösse geben

Beitragvon Pü-Ton » Dienstag 24. Juni 2008, 11:37

Hallo@all,

ich komm einfach nicht weiter...

Ich lese aus einem XML-Flie Daten aus, die dann untereinander in einem Canvas aufgelistet werden.
Ich habe jetzt auch schon eine scrollbar eingefügt, weil ich will, dass das Canvas die feste Grösse behält, selbst wenn mehr Elemente aufgelistet werden, die in das Canvas "passen". Dann soll eben die Scrollbar in action treten.

Ich verwende grid und tkinter.

Das Problem ist, dass sich das Canvas immer der Anzahl und damit dem benötigten Platz der XML-Elemente anpasst. Kann man das verhindern?

Es soll quasi so sein, wie dieses Eingabefenster hier, in das ich gerade schreibe. Sobald der Text grösser wird, wie das Fenster, erscheint die Scrollbar aber das Fenster bleibt in seiner grösse.

Hier etwas Code:

Code: Alles auswählen

    Window1 = Label(roots)
    Window1.config(background="#CCCCCC", relief="groove")
    Window1.grid(sticky=E, row=6, column=0)
   

    Row6 = Canvas(Window1, height=517, width=590)
    Row6.config(background="#CCCCCC")
    Row6.grid(row=1, sticky=N)

    wScrollV = Scrollbar(Window1, orient=VERTICAL, command=Row6.yview)
    wScrollV.grid(sticky=E+N+S, row=1, column=0)

    update_scrollregion()

...

    for elems in variables.findall("Bla"):
        for elem in elems.findall("Blub"):
            #print elem.text
            i = i+1
            DummyVar = Label(Row6, text=elem.text, bg="#CCCCCC").grid(row=i, column=0, sticky=W+N, padx=5, pady=5)


Also Row6 ist das Canvas innerhalb vom Frame Window1, dass wiederum in der GUI eingebettet ist...

--> Row6 soll seine Grösse nicht verändern, egal wieviel über die for-Schleife aus dem XML ausgelesen wird...

- Liegt das am grid?
- gibt es einen Befehl für das festlegen der Canvasgrösse?

Danke
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Dienstag 24. Juni 2008, 12:50

Das dürfte wohl am Grid liegen. Probier doch einmal

Code: Alles auswählen

Window1.rowconfigure(6, minsize=590)
Da hierbei die Option weight nicht benutzt wird, sollte die Zeile sich nicht ausdehnen (ungetestet).
MfG
HWK
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Beitragvon Pü-Ton » Dienstag 24. Juni 2008, 13:11

hmmm, das ist gut soweit, nur bräucht ich eher was wie maxsize=
...
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Dienstag 24. Juni 2008, 13:28

Übrigens: Wenn Du das Canvas nur für Text benutzt, wäre dann ein ScrolledText-Widget nicht sinnvoller?
Und: Der Effekt von Zeile 22 auf den Inhalt von DummyVar (PEP8: dummy_var) ist Dir hoffentlich klar.
MfG
HWK
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Beitragvon Pü-Ton » Dienstag 24. Juni 2008, 13:46

Es ist so, dass aus dem XML zum einen Die Namen ausgelesen werden - das sind wirklich nur Texte und daneben (rechts davon) kommen Entrys hin, in denen ein defaultwert steht. Ich kann also kein reines Textwidget nehmen...

Was genau meinst Du mit dem Ihnalt von DummyVar?
Hab ich was übersehen? :?: :?: :?:
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Dienstag 24. Juni 2008, 14:43

Mir ist noch nicht so recht klar, was genau du vorhast und warum du dafür ein Canvas-Widget brauchst.

Hilfreich wäre es auch, wenn man nicht nur ein Code-Fragment, sondern ein für sich lauffähiges Stück Code hätte.
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Beitragvon Pü-Ton » Dienstag 24. Juni 2008, 15:00

Hi pütone,
einen ausführbaren Code kann ich hier nicht posten... ist zu verschachtelt...

Im Grunde gehts wirklich "nur" darum, dass ich ein Canvas-Fenster in seinen Abmessungen fest zu begrenzen, auch wenn ich Daten (Text und Entrys) hineinschreiben lasse.

Es gibt also ein Fenster, in diesem Fenster sind (von oben nach unten) ein Frame, ein Canvas und ein Frame eingebunden.

In das Canvas kommen jetzt die Daten aus einem XML-File. Dieses Canvas soll seine äusseren Masse nicht verändern.
Wenn es mehr Daten werden, wie in die Abmessungen hineinpassen, soll nur über einen scrollbalken der untere (nicht sichtbare) Teil anzeigbar werden.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Dienstag 24. Juni 2008, 16:33

Normalerweise ist das kein Problem.
Guckst du hier (das mit dem "global" bitte nicht nachmachen!):

Code: Alles auswählen

import Tkinter as tk
from random import randrange

def write_more():
    global y
    y += 20
    canv.create_text(20,y,anchor=tk.NW,text=str(randrange(100000,1000000)))

root = tk.Tk()
y = 0
frame_top = tk.Frame(root)
frame_bottom = tk.Frame(root)
button = tk.Button(frame_bottom,text="Schreib mehr",command=write_more)
canv = tk.Canvas(root,width=160,height=400,bg="white")
frame_top.pack()
canv.pack()
frame_bottom.pack()
button.pack()
root.mainloop()


Insofern ist es schwer, dir zu helfen.
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Beitragvon Pü-Ton » Mittwoch 25. Juni 2008, 08:49

Das ist gar nicht so schlecht, jedoch verwende ich grid statt pack und darin liegt wohl auch das Problem. Ich habe hier von Michael Schneider was gefunden, dass mich ein gutes Stück weitergebracht hat:

--> Der ist ausführbar, dann seht ihr in etwa wie das aussehen soll !!!

Code: Alles auswählen

import Tkinter as TK
import Canvas

tk = TK.Tk()
yscroll = TK.Scrollbar(tk, orient = TK.VERTICAL)
yscroll.grid(row = 1, column = 2, sticky = TK.NS)

xscroll = TK.Scrollbar(tk, orient = TK.HORIZONTAL)
xscroll.grid(row = 2, column = 1, sticky = TK.EW)

canvas = TK.Canvas(tk,
                   width = 200,
                   height = 200,                       
                   scrollregion = "0 0 400 400",        ##  Scrollregion im Bereich 0,0 - 400, 400
                   yscrollcommand = yscroll.set,        ##  Canvashoehe an yscroll uebergeben
                   xscrollcommand = xscroll.set)        ##  Canvasbreite an xscroll uebergeben
canvas.grid(row = 1, column = 1)

rect = Canvas.Rectangle(canvas, (40, 40), (280, 380), fill="#9999ff")   ##  um was zu sehen

yscroll.config(command = canvas.yview)                  ##  yscrollwerte an canvas uebergeben
xscroll.config(command = canvas.xview)                  ##  xscrollwerte an canvas uebergeben

tk.mainloop()


Jetzt liegt mein Problem nur noch daran, dass ich in das Lila-Fenster meine Daten reinschreiben will.

Also in rect !

Wenn ich das versuche kommt der Fehler:

Code: Alles auswählen

Rectangle instance has no attribute 'tk'


mein code:

Code: Alles auswählen

from Tkinter import*
from xml.dom.minidom import*
import xml.etree.ElementTree as et
import Tkinter as TK
import Canvas

    yscroll = TK.Scrollbar(Window1, orient=TK.VERTICAL)
    yscroll.grid(row=1, column=0, sticky=TK.E+N+S)

    canvas = TK.Canvas(Window1,
                       width=560,
                       height=516,
                       scrollregion="0 0 1500 1500",      ##  Scrollregion im Bereich 0,0 - 400, 400
                       bg="#CCCCCC",
                       yscrollcommand=yscroll.set)        ##  Canvashoehe an yscroll uebergeben

    canvas.grid(row=1, sticky=W, padx=5)

    rect = Canvas.Rectangle(canvas, (0, 0), (560, 1499), fill="#990000")   

#    rect.minsize=(500, 520)
#    rect.maxsize=(1499, 560)
    yscroll.config(command=canvas.yview)

    for elems in variables.findall("Bla"):
        for elem in elems.findall("Blubb"):
            #print elem.text
            i = i+1
            DummyVar = Label(rect, text=elem.text, bg="#CCCCCC").grid(row=i, column=0, sticky=W+N, padx=5, pady=5)


"Window1" ist ein Frame, in dem das ganze drin steckt.

Was kann ich tun, damit ich nicht Rectangle (was ja kein Attribut tk hat) benutzen muss, sondern etwas equivalentes, benutzbares ???

Hat jm eine Idee ???
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Mittwoch 25. Juni 2008, 12:19

Pü-Ton hat geschrieben:Was genau meinst Du mit dem Ihnalt von DummyVar?
Hab ich was übersehen? :?: :?: :?:
DummyVar enthält den Rückgabewert von Label(...).grid(...). Ich glaube nicht, dass Du den brauchst. Du willst doch wahrscheinlich den Rückgabewert von Label(...) speichern. Wozu brauchst Du denn DummyVar? Der PEP8-konforme Name wäre übrigens dummy_var.
Pü-Ton hat geschrieben:Was kann ich tun, damit ich nicht Rectangle (was ja kein Attribut tk hat) benutzen muss, sondern etwas equivalentes, benutzbares ???
Ich denke, Canvas ist nicht das richtige Widget. Nimm doch einfach einen Frame und speichere da alles drin ab. In diesem Frame verwendest Du einen neuen Frame statt des Rectangles.
MfG
HWK
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Beitragvon Pü-Ton » Mittwoch 25. Juni 2008, 12:39

...ursprünglich wollte ich ja auch ein Frame nehmen, jedoch kann ich das doch nicht über einen scrollbalken bewegen...oder? Dachte das geht nur mit Canvas und Text-widges ???!!!

Es stimmt, dass ich nur den Rückgabewert von Label haben will, aber ich muss den doch einer Variable ---> DummyVar übergeben oder nicht?

Wie ist denn dann die Syntax ??


Code: Alles auswählen

    for elems in variables.findall("Bla"):
        for elem in elems.findall("Blubb"):
            #print elem.text
            i = i+1
            DummyVar = Label(rect, text=elem.text, bg="#CCCCCC").grid(row=i, column=0, sticky=W+N, padx=5, pady=5)

            Return Label


Oder lautet die DummyVar-Zeile dann ganz anders?

--> dies ist mir ein noch unbekanntes Gebiet <-- aber Danke für Deine Hilfe...
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Beitragvon HWK » Mittwoch 25. Juni 2008, 12:58

Code: Alles auswählen

dummy_var = tk.Label(rect, text=elem.text, bg="#CCCCCC")
dummy_var.grid(row=i, column=0, sticky=tk.W+tk.N, padx=5, pady=5)
MfG
HWK
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Mittwoch 25. Juni 2008, 13:04

Du brauchst überhaupt keine Variable, wenn du später nicht noch einmal darauf zugreifen willst:

Code: Alles auswählen

tk.Label(rect, text=elem.text, bg="#CCCCCC").grid(row=i, column=0, sticky=tk.W+tk.N, padx=5, pady=5)
Pü-Ton
User
Beiträge: 67
Registriert: Donnerstag 8. Mai 2008, 07:52

Beitragvon Pü-Ton » Mittwoch 25. Juni 2008, 13:04

o-ha, ja klar, jetzt weiss ich auch was Du gemeint hast...

Manchmal sieht man halt vor lauter Zeilen den Monitor nicht mehr :))))

Also gut, soweit gefixt, nur leider bleibt das Problem mit dem Scrollbalken an einem Canvas mit Inhalt...

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

Beitragvon numerix » Mittwoch 25. Juni 2008, 13:14

Pü-Ton hat geschrieben:Hat jm eine Idee ???


Also, wenn ich deinen import-Block sehe, dann gruselt es mich.

Meine Idee: Lies erst mal etwas zu den Grundlagen von Tkinter. Wenn dir die Grundlagen klar(er) sind, dann wird dein Code vermutlich auch klarer und die Lösung deines Problems wird sich dann auch finden.

Empfehlen könnte ich: http://www.ferg.org/thinking_in_tkinter/all_programs.html

Hat zwar ein sch*-Layout, ein gründliches Durcharbeiten kann aber sehr hilfreich sein.

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder