Canvas + Scrollbars + Skalieren

Fragen zu Tkinter.
Daniel_SGe
User
Beiträge: 28
Registriert: Montag 8. September 2008, 19:39

Beitragvon Daniel_SGe » Donnerstag 2. Oktober 2008, 21:54

Hi!

Der Ansatz sieht schonmal ganz nett aus.
Du hast ja jetzt pack verwendet. Ich überlege, ob ich nicht vll. doch komplett auf pack umsteigen soll. Dann müsstest du mir eventuell allerdings noch sagen, wie ich einen Befehl wie

Code: Alles auswählen

cv.config(scrollregion=cv.bbox(ALL))


hinbekomme. Das Fenster muss sich nämlich dynamisch an eine Eingabe anpassen können.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Donnerstag 2. Oktober 2008, 22:18

Daniel_SGe hat geschrieben:Dann müsstest du mir eventuell allerdings noch sagen, wie ich einen Befehl wie

Code: Alles auswählen

cv.config(scrollregion=cv.bbox(ALL))


hinbekomme.


Wo sollte da das Problem sein?

Daniel_SGe hat geschrieben:Das Fenster muss sich nämlich dynamisch an eine Eingabe anpassen können.


Inwiefern: Soll der sichtbare Ausschnitt dann in den Bereich wechseln, wo gerade ein neues Item eingefügt wurde?
Daniel_SGe
User
Beiträge: 28
Registriert: Montag 8. September 2008, 19:39

Beitragvon Daniel_SGe » Freitag 3. Oktober 2008, 04:48

Wo sollte da das Problem sein?


Ich bekomm die Fehlermeldung:


cv.config(scrollregion=cv.bbox(ALL))
NameError: name 'ALL' is not defined


Inwiefern: Soll der sichtbare Ausschnitt dann in den Bereich wechseln, wo gerade ein neues Item eingefügt wurde?


Der sagen wir mal "Graph" ist je nach Eingabe größer oder kleiner. So dann auch das Canvas. Diese maximale Größe soll dann auch als maximaler Scrollbereich genommen werden...
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Freitag 3. Oktober 2008, 06:55

Naja sicher bekommst du einen NameError, weil ALL eine Tkinter-Konstante ist, du Tkinter mittels Sternchenimport eingebunden hast und ich nicht.

Also muss es - für meinen Code - heißen tk.ALL oder zu verwendest stattdessen eine Zeichenkette "all".

Das Ändern des maximalen Scrollbereichs ist völlig unproblematisch.
Du musst nur die scrollregion neu setzen, wenn du ein neues Item auf das Canvas platzierst. Das heißt: Nachdem das Item hinzugefügt wurde, genügt deine Zeile mit dem bbox("all").
Daniel_SGe
User
Beiträge: 28
Registriert: Montag 8. September 2008, 19:39

Beitragvon Daniel_SGe » Samstag 4. Oktober 2008, 20:56

Hmm. Dummer Fehler. Hab jetzt allerdings ein weiteres Problem. Der Graph, den ich zeichnen möchte fängt bei einem bestimmten y-Wert an. Da der Graph so nie von Anfang an im Fenster auftaucht, würde ich den Graphen gerne auch dynamisch je nach maximaler Höhe des Graphen zeichnen lassen. Da die maximale Höhe jedoch von einem Parameter und einem Zufallswert abhängt, wäre die einzige Möglichkeit, die mir einfällt den ganzen Code in eine Funktion zu packen und diese dann das 2. Mal mit dem Höhenparameter aufzurufen. (Neuzeichnen kommt wohl eher nicht in Betracht, je nachdem sind es über 1000 Elemente.

Wenn dies dann funktioniert sollte der 1. Ausschnitt den man sieht, nicht links oben sein, sondern rechts oben. Lässt sich das einfach realisieren?

Noch ein kleiner "Schönheitsfehler": Beim Scrollen bleiben die x und Y-Achse zwar am Rand der Graph "schiebt" sich aber auch durch diese hindurch. Eine Option um dies abzustellen?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Samstag 4. Oktober 2008, 21:46

Allmählich habe ich den Eindruck, du solltest dich einmal intensiver mit der Tkinter-Doku (speziell Canvas) beschäftigen. Meine Empfehlung dazu:

http://infohost.nmt.edu/tcc/help/pubs/tkinter/canvas.html

Ich weiß ja nicht genau, was du mit "Graph" meinst. Sollte es sich um einen Streckenzug handeln, dann brauchst du dafür nicht 1000 Elemente, sondern kannst es als EIN line-Objekt zeichnen. Dann ist das Neuzeichnen auch kein Akt. Das Neusetzen der Grenzen für die Scrollregion ist aber auch kein Ding.

Dass die Achsen den Graphen überlagern ist klar. Da sie immer wieder neu gezeichnet werden, haben sie eine höhere ID als der Graph und werden zu oberst gezeichnet. Mittels tag_raise() bzw. tag_lower() kannst du das wie gewünscht einstellen.

Und das mit rechts oben statt links oben bekommst du auch allein noch hin ... :wink:
Alberich
User
Beiträge: 1
Registriert: Donnerstag 16. Oktober 2008, 12:27
Kontaktdaten:

Beitragvon Alberich » Donnerstag 16. Oktober 2008, 12:28

Danke für die Code-Snippets, das erleichtert die Sache ganz immens.
Früher hatten wir Handystrahlung, jetzt UMTS Internet, strahlt mehr, geht aber auch schneller.
Daniel_SGe
User
Beiträge: 28
Registriert: Montag 8. September 2008, 19:39

Beitragvon Daniel_SGe » Freitag 17. Oktober 2008, 02:43

Sry, dass ich mich so lang nicht gemeldet hab, aber ich hatte nicht allzuviel Zeit und in dieser musste ich mich schließlich auch durch diverse Tkinter-Dokumentationen kämpfen;) .

Trotz allem sind noch ein paar Fragen offengeblieben:



Dass die Achsen den Graphen überlagern ist klar. Da sie immer wieder neu gezeichnet werden, haben sie eine höhere ID als der Graph und werden zu oberst gezeichnet. Mittels tag_raise() bzw. tag_lower() kannst du das wie gewünscht einstellen.


Der Graph (ja, ein Streckenzug ;) ) sollte ja nicht nur nicht die Achsen überlagern, sondern auch ab diesem Punkt abgeschnitten sein, sprich, nach dem Überschreiten nicht mehr sichtbar sein.
Ich hab mir jetzt damit beholfen, zusätzlich farbneutrale Rechtecke einzufügen, durch die dann der Graph nicht mehr durchgeht. Wäre solch eine Lösung "unschön", wenn Ja, wie würde man es "richtig" machen?


Und das mit rechts oben statt links oben bekommst du auch allein noch hin ...


Die einzige Möglichkeit, die mir eingefallen ist, ist die Y-Scrollbar nach ganz unten zu setzen.
Laut Dokumentation geschieht dies mit der Methode set(lo, hi).
Leider passiert überhaupt nichts wenn ich setze set(0.0, 1.0).
Lasse ich mir mittels "get" die Werte anzeigen, erscheint je nach Y-Länge "(0.x, 1.0)".
Setze ich ein solches Wertepaar mit set, funktioniert das ganze allerdings wieder ohne Probleme, jedenfalls so lang bis man die Y-Länge wieder ändert.
Ich versteh nicht, warum das ganze nicht mit (0.0, 1.0) funktioniert...

Weiteres Problem:

Da für kleine Y-Gesamtlängen des Graphen die Beschriftung beim Vergrößern des Fensters ins Negative geht, habe ich eine vom Graphen abhängige Maximalgröße des Root-Fensters festgelegt (geht dies eventuell auch über Framegröße? ). Wenn jedoch das Fenster schon größer als der Maximalbereich ist, wird es nicht automatisch verkleinert. Kann man dies irgendwie errreichen?


Zum Skalieren:

Ich hatte mir überlegt, dass man einfach nur den Graphen und die Beschriftung der Achsen mit angepassten Werten neuzeichnen müsste, wenn das Scrollrad bewegt wird. In der Dokumentation kann ich leider kein passendes Event finden. Gibt es wirklich keins?



Danke für die Code-Snippets, das erleichtert die Sache ganz immens.


Angemeldet dafür?!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Freitag 17. Oktober 2008, 17:13

Daniel_SGe hat geschrieben:Ich hab mir jetzt damit beholfen, zusätzlich farbneutrale Rechtecke einzufügen, durch die dann der Graph nicht mehr durchgeht. Wäre solch eine Lösung "unschön", wenn Ja, wie würde man es "richtig" machen?


Naja, eine "schöne" Lösung ist es in meinen Augen nicht. Halt so hingefrickelt, bis es passt. Andererseits halte ich das hier aber für legitim und ausreichend. Alternativen wären, die Zeichenintervalle für den Graphen entsprechend zu beschränken oder aber mit einer Extra-Canvas zu arbeiten: Die äußere Canvas nimmt das Koordinatensystem auf; in diese Canvas hinein wird dann eine zweite platziert, die den Graphen aufnimmt. Beides dürfte aber deutlich komplizierter werden als das Überdecken mit einem Rechteck und darum: Lass es so.

Was die anderen Punkte angeht, so wird es immer schwieriger, hier Lösungshilfen zu geben ohne konkreten Code zu sehen. Wenn du den aktuellen Code einmal posten könntest, mit entsprechenden Beispielgraphen, an denen du exemplarisch zeigen kannst, wie sich das Programm derzeit verhält und wie du es gerne anders hättest, dann wäre das hilfreich.
Daniel_SGe
User
Beiträge: 28
Registriert: Montag 8. September 2008, 19:39

Beitragvon Daniel_SGe » Samstag 18. Oktober 2008, 04:35

Hier der gewünschte Beispielcode:


Ich hab als Beispiel 2 dreieckige Graphen benutzt. Einmal mit der Höhe 10 und einmal mit der Höhe 7.
Der 1. Graph wird am Anfang gezeichnet. Der zweite wird durch einen Druck auf Enter gezeichnet.

Gleich am Anfang wird so auch gleich das 1. Problem sichtbar. Die Y-Scrollbar befindet sich weder in der einen noch in der anderen Position. eigentlich sollte sie ganz unten liegen, damit man so auch den Koordinatenursprung sieht.

Klicke ich nun auf maximieren, passt der Graph wunderbar ins Bild (ausreichende Bildschirmauflösung sei vorausgesetzt ;) ). Lasse ich nun durch einen Druck auf Enter den 2. Graph zeichnen, tritt zuallererst wieder Problem Nummer 1 auf.
Weiterhin ist das Fenster nach wie vor maximiert, dabei hat sich die "maxsize" doch verschoben. Durch Aufheben und anschließendes Maximieren wird dieser Effekt zwar "behoben", schön ist das aber auch nicht. Problematisch ist außerdem, dass der maximal einsehbare Bereich plötzlich bei 11 liegt, dabei müsste er doch gerade bei der maximalen Höhe von 7 liegen.
Lasse ich die beiden Graphen andersherum zeichnen und gehe nach genau demselben Schema vor, habe ich letzeres Problem nicht, da der zuletztgezeichnete Graph "größer" ist.

Meine Frage ist daher: Kann ich einen solchen Resize erzwingen, damit maximal immer nur der Graph zu sehen ist?

Die Frage zum Skalieren bleibt die gleiche. Gibt es ein solches Event, Scrollrad-Hoch bzw. Scrollrad-Runter?
Zuletzt geändert von Daniel_SGe am Mittwoch 5. November 2008, 20:06, insgesamt 1-mal geändert.
Benutzeravatar
wuf
User
Beiträge: 1409
Registriert: Sonntag 8. Juni 2003, 09:50

Beitragvon wuf » Samstag 18. Oktober 2008, 10:58

Hallo Daniel_SGe

Kannst du das folgende einmal ausprobieren:

[Code ausgelagert]

Gruss wuf :wink:
Take it easy Mates!

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder