Umzeichnen einer Kurve mit coords- method

Fragen zu Tkinter.
Antworten
rashury
User
Beiträge: 16
Registriert: Dienstag 19. Januar 2010, 13:09
Wohnort: Wien
Kontaktdaten:

Hallo alle liebe Leute :)

ich versuche eine Kurve mit Hilfe der Methode "Coods" um zu zeichnen, dazu habe ich ein keines Testprogramm,
das Problem ist, wenn ich die Umzeichnung in einer Schleife aufnehme, wird es nicht mehr gezeichnet, ich habe mit Hilfe einer Zeitverzeugerungsschleife, aber leider hat es nicht funktioniert, wer kann sagen, warum nicht?
Python- Funktion folgt:

Code: Alles auswählen


import os
import string

import Tkinter
import Canvas
import math
import sys
from Tkconstants import *
import time

f = 0
ff = []
root = Tkinter.Tk()
root.title("Start- Test")

f = Tkinter.Canvas(root, relief = RIDGE , bd = 2 , bg = "white" , width = 1000 , height = 100)
f.pack()

for ii in range (900):
 ff.append(f.create_line (ii, 20 , ii+1, 20,  fill = 'green'))

while -1:
 for ii in range (900):
  f.coords (ff[ii] , ii , 20 , ii +1 , 20)
 time.sleep( 1)
 for ii in range (900):
  f.coords (ff[ii] , ii , 80 , ii +1 , 80)

root.mainloop()




Hallo Leute,
BlackJack

@rashury: Damit die GUI aktualisiert wird muss entweder die `mainloop` laufen, oder Du musst selber dafür sorgen, dass sie aktualisiert wird. Bei GUI-Programmierung hat man den Kontrollfluss in der Regel nicht mehr selber in der Hand, sondern gibt ihn an die Hauptschleife der GUI ab, die bei bestimmten Ereignissen Rückruffunktionen aufruft, die man bekannt macht. Zum Beispiel eine Funktion die aufgerufen werden soll, wenn eine Schaltfläche angeklickt wird. Oder für so etwas was Du machen möchtest, eine Funktion die nach einer abgelaufenen Zeit aufgerufen wird, die Koordinaten *einmal* aktualisiert und dann wieder die Kontrolle an die GUI abgibt, bis sie das nächste mal aufgerufen wird. Funktionen von der GUI nach einer Zeit aufrufen zu lassen geht mit der `after()`-Methode auf `Tkinter`-Widgets.

Und Du solltest vielleicht anfangen in Python zu programmieren und nicht welche Sprache Du auch immer vorher verwendet hast, in Python-Syntax zu zwängen. Das sieht nicht besonders "pythonisch" aus. Man kann über Elemente in Listen direkt, ohne Umweg über einen Index iterieren. Wenn man den *zusätzlich* benötigt, gibt es `enumerate()`.

`f`, `ff`, und `ii` sind nichtssagende Namen. -1 ist zwar als Wahrsheitswert gesehen "richtig" aber ein ``while True:`` ist um Längen deutlicher.

Warum wird `f` an 0 gebunden!?
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Aktuell mit teilweise ähnlicher Problematik: http://www.python-forum.de/topic-21917.html

Und: Thread sollte ins Tkinter-Subforum verschoben werden ...
rashury
User
Beiträge: 16
Registriert: Dienstag 19. Januar 2010, 13:09
Wohnort: Wien
Kontaktdaten:

Hallo BlackJack,

Du hast Recht, diese Callback- Funktion habe ich in meinem Hauptprogramm schon drinnen,
das Testprogramm habe ich nur zu einem Testzweck geschrieben (ich wollte Hauptprogramm, das lang ist, nicht hineinkopieren),
in meinem Hauptprogramm wird die Callback- Funktion angesprochen, wenn Mssdaten durch die Socket hinein kommen (TCP- Protokolle),
also wie Du sagst, iund richtig ist, habe ich gemacht, und ich sehe, wann die Datan kommen, wird Callbach angeprochen, soweit ist es ok,
aber,
ich will mit diiesen Daten, die hineinkommen, eine Kurve aktualisieren,
dazuverwende ich coodrs - met5hod,
und diese hat leider nicht funktioniert?
ic dachte mir, ich wende vielleicht coords nichgt richtig,
deshalb habe ich dieses Testprogtramm geschrieben,
ich sehe das es Tatsächlich mit coords nicht dynamisch gut funktioniert,
und ich versuche die Ursache zu verstehen,

(f = 0 ist nur eine statische Initialiesierung,)

Gruß und schönen Abend wünsche ich dir,
Hallo Leute,
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

rashury hat geschrieben:(f = 0 ist nur eine statische Initialiesierung,)
Kannst du das erklären?
rashury
User
Beiträge: 16
Registriert: Dienstag 19. Januar 2010, 13:09
Wohnort: Wien
Kontaktdaten:

Ich versuche,

ich habe eine Lösung gefunden (ob diese Lösung die beste Lösung ist, weiss ich zur Zeit noch nicht): Wenn ich nach coords die Update- method aufrufe, dann wird im Canvas gezeichnet, :)
ABER :?:
ich frage mich, wenn ich create_line verwende, braucht das System kein Update, wieso für coord braucht das schon?
was ist hier andres als create_line?
und wieso soll man hier Update ausführen? welche Auswirkungen hat das?

ich wünsche einen schönen Abend,

Gruß,
rashury.
Hallo Leute,
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo rashury

Hier eine Lösung zum ausprobieren:

Code: Alles auswählen

# wuf_ref: canvas_curve_01_01.py

import os
import string

import Tkinter
import math
import sys

def animate():

    if root.toggle:
        root.toggle = False
        for ii in range (900):
            f.coords (root.ff[ii] , ii , 80 , ii +1 , 80)
    else:
        root.toggle = True
        for ii in range (900):
            f.coords (root.ff[ii] , ii , 20 , ii +1 , 20)

    root.after(1000, animate)

root = Tkinter.Tk()
root.title("Start- Test")

root.f = 0
root.ff = []
root.toggle = False

f = Tkinter.Canvas(root, relief = 'ridge' , bd = 2 , bg = "white" ,
    width = 1000 , height = 100)
f.pack()

for ii in range (900):
    root.ff.append(f.create_line (ii, 20 , ii+1, 20,  fill = 'green'))

animate()

root.mainloop()
while-Schleifen in einer tkinter-mainloop() machen manchmal Problem. Sollte wie BlackJack vorgeschlagen hat mit der .after()-Methode gelöst werden. Bei mir macht dein Skript z.B. Selbstjustiz und hängt sich ohne etwas zu tun auf.

Bitte noch die Tipps von BlackJack beachten.

Gruss wuf
Take it easy Mates!
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo rashury

Hier noch etwas zum probieren und abändern:

Code: Alles auswählen

# wuf_ref: canvas_curve_01_02.py

import os
import string

import Tkinter
import math
import sys
import random

root = Tkinter.Tk()
root.title("Start- Test")

NUM_DATA_POINTS = 900

PLOT_XORG = 10
PLOT_YORG = 400
PLOT_WIDTH = 900
PLOT_HEIGHT = PLOT_YORG - 20

PEN_COLOR = 'red'
PEN_WIDTH = 1

AXIS_COLOR = 'black'
AXIS_WIDTH = 1

MAX_XPLOT_DIM = PLOT_XORG + NUM_DATA_POINTS + 10
MAX_YPLOT_DIM = PLOT_YORG + 10

plot_data = []

canvas = Tkinter.Canvas(root, relief='ridge', bd=2 , bg="white",
    width=MAX_XPLOT_DIM , height=MAX_YPLOT_DIM)
canvas.pack()

canvas.create_line(PLOT_XORG-1, PLOT_YORG+1, PLOT_XORG+NUM_DATA_POINTS,
    PLOT_YORG+1, width=AXIS_WIDTH, fill=AXIS_COLOR, tag='xaxis')

canvas.create_line(PLOT_XORG-1, PLOT_YORG+1, PLOT_XORG-1, PLOT_YORG-PLOT_HEIGHT,
    width=AXIS_WIDTH, fill=AXIS_COLOR, tag='yaxis')

for xpos in range (NUM_DATA_POINTS):
    plot_data.append(
        (PLOT_XORG+xpos, PLOT_YORG-random.randint(0, PLOT_HEIGHT)))

canvas.create_line(plot_data, width=PEN_WIDTH, fill=PEN_COLOR)

root.mainloop()
Gruss wuf :wink:
Take it easy Mates!
Antworten