Python error; graph hangs;Tkinter

Thread Starter

Vindhyachal Takniki

Joined Nov 3, 2014
594
1. I am trying to plot two graph in Tkinter canvas.
2. Problem is after few plots of data, graph gets hanged.
It takes up huge resources of window, then i have to kill it forcefully.
3. Since I have to plot the graph continuously like that in CRO/DSO so I have to go line by line rather than using any library. Didn't find any lib where graph is printed continuously.
4. I am using python 2.7 on window 8 64 bit.
5. But in the end I have to shift the code to Raspberry pi board.

Edit: code

Code:
from Tkinter import *
import Tkinter
import time
from random import randint
import math

#global vars
hor_pixel = 5                      #starting point of horizontal pixel
old_ver_pixel_1 = 0                #last pixel value of graph 1
old_ver_pixel_2 = 0                #last pixel value of graph 2
new_ver_pixel_1 = 0                #new pixel value of graph 1
new_ver_pixel_2 = 0                #new pixel value of graph 2
y0_1 = 0                           # y cordinate of graph 1 & 2
y1_1 = 0
y0_2 = 0
y1_2 = 0

def pixel(C):
    global hor_pixel
    global old_ver_pixel_1
    global old_ver_pixel_2    
    global new_ver_pixel_1
    global new_ver_pixel_2
    global y0_1
    global y1_1
    global y0_2
    global y1_2    
   
    if(new_ver_pixel_1 == old_ver_pixel_1):
        new_ver_pixel_1 = new_ver_pixel_1 + 1
    if(new_ver_pixel_2 == old_ver_pixel_2):
        new_ver_pixel_2 = new_ver_pixel_2 + 1            
       
    if(new_ver_pixel_1 > old_ver_pixel_1):
        y0_1 = old_ver_pixel_1
        y1_1 = new_ver_pixel_1
    else:
        y0_2 = old_ver_pixel_2
        y1_2 = new_ver_pixel_2        
       
    coord = hor_pixel, y0_1, hor_pixel, y1_1
    coord2 = hor_pixel, y0_2, hor_pixel, y1_2        
    hor_pixel = hor_pixel + 1

    if(hor_pixel > 400):
        hor_pixel = 5;
       
    old_ver_pixel_1 = new_ver_pixel_1
    old_ver_pixel_2 = new_ver_pixel_2

    C.create_line(hor_pixel , 0 , hor_pixel , 500, fill = 'black')
    C.create_line(coord, fill = 'red')
    C.create_line(coord2, fill = 'yellow')
    C.pack()
    #print(new_ver_pixel_1 , new_ver_pixel_2)



def graph():
    global new_ver_pixel_1
    global new_ver_pixel_2
   
    screen = Tkinter.Tk()
    screen.title("Analog Channel")
    screen.geometry("800x800")
    C = Tkinter.Canvas(screen , bg = "black" , height = 800, width = 800)
    C.pack()

    while True:
        var = 0
        var = var + 1
        new_ver_pixel_1 = randint(0,200) + 200;
        new_ver_pixel_2 = randint(0,200) + 400;
        #print(new_ver_pixel_1 , new_ver_pixel_2)
        #pixel(C)
        screen.after(100,pixel(C))
        screen.update_idletasks()

    screen.mainloop()


graph()
 

Attachments

Last edited:

strantor

Joined Oct 3, 2010
6,798
Problem #1 - You're using too many global variables. Global variables are bad juju. Only use them when you know for sure for some good reason that you really need to use them. Otherwise utilize Python's Class() to establish variable shared between objects, as I have shown below.

Problem #2 - screen.update_idletasks() ... Why did you use this? Should be simply screen.update()

Try this:

Python:
import Tkinter
from random import randint

class pixelTron():

    def __init__(self):
        self.hor_pixel = 5                      #starting point of horizontal pixel
        self.old_ver_pixel_1 = 0                #last pixel value of graph 1
        self.old_ver_pixel_2 = 0                #last pixel value of graph 2
        self.new_ver_pixel_1 = 0                #new pixel value of graph 1
        self.new_ver_pixel_2 = 0                #new pixel value of graph 2
        self.y0_1 = 0                           # y cordinate of graph 1 & 2
        self.y1_1 = 0
        self.y0_2 = 0
        self.y1_2 = 0


    def pixel(self, C):
        nP1 = self.new_ver_pixel_1
        oP1 = self.old_ver_pixel_1
        nP2 = self.new_ver_pixel_2
        oP2 = self.old_ver_pixel_2
        hP = self.hor_pixel
        if(nP1 == oP1):
            nP1 = nP1 + 1
        if(nP2 == oP2):
            nP2 = nP2 + 1

        if(nP1 > oP1):
            self.y0_1 = oP1
            self.y1_1 = nP1
        else:
            self.y0_2 = oP2
            self.y1_2 = nP2

        coord = hP, self.y0_1, hP, self.y1_1
        coord2 = hP, self.y0_2, hP, self.y1_2
        hP = hP + 1

        if(hP > 400):
            hP = 5;

        self.old_ver_pixel_1 = nP1
        self.old_ver_pixel_2 = nP2

        C.create_line(hP , 0 , hP , 500, fill = 'black')
        C.create_line(coord, fill = 'red')
        C.create_line(coord2, fill = 'yellow')
        C.pack()
        self.hor_pixel = hP



    def graph(self):

        screen = Tkinter.Tk()
        screen.title("Analog Channel")
        screen.geometry("800x800")
        C = Tkinter.Canvas(screen , bg = "black" , height = 800, width = 800)
        C.pack()
        pixel = self.pixel

        while True:
            self.new_ver_pixel_1 = randint(0,200) + 200;
            self.new_ver_pixel_2 = randint(0,200) + 400;
            screen.after(100,pixel(C))
            screen.update()

        screen.mainloop()

PT = pixelTron()
PTG = PT.graph
PTG()
 

Thread Starter

Vindhyachal Takniki

Joined Nov 3, 2014
594
One error after I had below changes :)

1. I had made a main.py n which I keep on calling this graph. In actual code I have superloop which have other functions also.
When first time code is run, graph is printed. But as soon as I close the window of graph to return to main error comes.

main.py
Code:
#this is main file

import graph

while True:
    graph.my_graph()
    print("DONE")
   #do other things

graph.py
Code:
import Tkinter
from random import randint

class pixelTron():

    def __init__(self):
        self.hor_pixel = 5                      #starting point of horizontal pixel
        self.old_ver_pixel_1 = 0                #last pixel value of graph 1
        self.old_ver_pixel_2 = 0                #last pixel value of graph 2
        self.new_ver_pixel_1 = 0                #new pixel value of graph 1
        self.new_ver_pixel_2 = 0                #new pixel value of graph 2
        self.y0_1 = 0                           # y cordinate of graph 1 & 2
        self.y1_1 = 0
        self.y0_2 = 0
        self.y1_2 = 0


    def pixel(self, C):
        nP1 = self.new_ver_pixel_1
        oP1 = self.old_ver_pixel_1
        nP2 = self.new_ver_pixel_2
        oP2 = self.old_ver_pixel_2
        hP = self.hor_pixel
        if(nP1 == oP1):
            nP1 = nP1 + 1
        if(nP2 == oP2):
            nP2 = nP2 + 1

        if(nP1 > oP1):
            self.y0_1 = oP1
            self.y1_1 = nP1
        else:
            self.y0_2 = oP2
            self.y1_2 = nP2

        coord = hP, self.y0_1, hP, self.y1_1
        coord2 = hP, self.y0_2, hP, self.y1_2
        hP = hP + 1

        if(hP > 400):
            hP = 5;

        self.old_ver_pixel_1 = nP1
        self.old_ver_pixel_2 = nP2

        C.create_line(hP , 0 , hP , 500, fill = 'black')
        C.create_line(coord, fill = 'red')
        C.create_line(coord2, fill = 'yellow')
        C.pack()
        self.hor_pixel = hP



    def graph(self):

        screen = Tkinter.Tk()
        screen.title("Analog Channel")
        screen.geometry("800x800")
        C = Tkinter.Canvas(screen , bg = "black" , height = 800, width = 800)
        C.pack()
        pixel = self.pixel

        while True:
            self.new_ver_pixel_1 = randint(0,200) + 200;
            self.new_ver_pixel_2 = randint(0,200) + 400;
            screen.after(100,pixel(C))
            screen.update()

        screen.mainloop()

def my_graph():
    PT = pixelTron()
    PTG = PT.graph
    PTG()


Error code is:
Code:
Traceback (most recent call last):
  File "C:\Users\main.py", line 6, in <module>
    graph.my_graph()
  File "C:\Users\graph.py", line 74, in my_graph
    PTG()
  File "C:\Users\graph.py", line 66, in graph
    screen.after(100,pixel(C))
  File "C:\Users\graph.py", line 46, in pixel
    C.create_line(hP , 0 , hP , 500, fill = 'black')
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 2317, in create_line
    return self._create('line', args, kw)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 2305, in _create
    *(args + self._options(cnf, kw))))
TclError: invalid command name ".43840856"
 

strantor

Joined Oct 3, 2010
6,798
The error is because there is no "destructor" handler (google that).

This works with no errors:

Python:
__author__ = 'chuck'
import Tkinter
from random import randint

class pixelTron():

    def __init__(self):
        self.hor_pixel = 5                      #starting point of horizontal pixel
        self.old_ver_pixel_1 = 0                #last pixel value of graph 1
        self.old_ver_pixel_2 = 0                #last pixel value of graph 2
        self.new_ver_pixel_1 = 0                #new pixel value of graph 1
        self.new_ver_pixel_2 = 0                #new pixel value of graph 2
        self.y0_1 = 0                           # y cordinate of graph 1 & 2
        self.y1_1 = 0
        self.y0_2 = 0
        self.y1_2 = 0
        self.screen = Tkinter.Tk()
        self.running = 1
        self.screen.protocol("WM_DELETE_WINDOW", self.suicide)

    def pixel(self, C):
        nP1 = self.new_ver_pixel_1
        oP1 = self.old_ver_pixel_1
        nP2 = self.new_ver_pixel_2
        oP2 = self.old_ver_pixel_2
        hP = self.hor_pixel
        if(nP1 == oP1):
            nP1 = nP1 + 1
        if(nP2 == oP2):
            nP2 = nP2 + 1

        if(nP1 > oP1):
            self.y0_1 = oP1
            self.y1_1 = nP1
        else:
            self.y0_2 = oP2
            self.y1_2 = nP2
        coord = hP, self.y0_1, hP, self.y1_1
        coord2 = hP, self.y0_2, hP, self.y1_2
        hP = hP + 1
        if(hP > 400):
            hP = 5;
        self.old_ver_pixel_1 = nP1
        self.old_ver_pixel_2 = nP2

        C.create_line(hP , 0 , hP , 500, fill = 'black')
        C.create_line(coord, fill = 'red')
        C.create_line(coord2, fill = 'yellow')
        C.pack()
        self.hor_pixel = hP

    def graph(self):
        screen = self.screen
        screen.title("Analog Channel")
        screen.geometry("800x800")
        C = Tkinter.Canvas(screen , bg = "black" , height = 800, width = 800)
        C.pack()
        pixel = self.pixel
        while self.running:
            self.new_ver_pixel_1 = randint(0,200) + 200;
            self.new_ver_pixel_2 = randint(0,200) + 400;
            screen.after(100,pixel(C))
            screen.update()
        screen.mainloop()

    def suicide(self):
        print "DONE"
        self.running = 0
        self.screen.destroy()

def my_graph():
    PT = pixelTron()
    PTG = PT.graph
    PTG()
and for the program that calls it:
Python:
__author__ = 'chuck'
import graph

#NO NEED FOR "WHILE TRUE" HERE
graph.my_graph()
 
Top