Python error; graph hangs;Tkinter

Discussion in 'Programmer's Corner' started by Vindhyachal Takniki, Jul 14, 2015.

  1. Vindhyachal Takniki

    Thread Starter Member

    Nov 3, 2014
    349
    6
    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 (Text):
    1.  
    2. from Tkinter import *
    3. import Tkinter
    4. import time
    5. from random import randint
    6. import math
    7.  
    8. #global vars
    9. hor_pixel = 5                      #starting point of horizontal pixel
    10. old_ver_pixel_1 = 0                #last pixel value of graph 1
    11. old_ver_pixel_2 = 0                #last pixel value of graph 2
    12. new_ver_pixel_1 = 0                #new pixel value of graph 1
    13. new_ver_pixel_2 = 0                #new pixel value of graph 2
    14. y0_1 = 0                           # y cordinate of graph 1 & 2
    15. y1_1 = 0
    16. y0_2 = 0
    17. y1_2 = 0
    18.  
    19. def pixel(C):
    20.     global hor_pixel
    21.     global old_ver_pixel_1
    22.     global old_ver_pixel_2    
    23.     global new_ver_pixel_1
    24.     global new_ver_pixel_2
    25.     global y0_1
    26.     global y1_1
    27.     global y0_2
    28.     global y1_2    
    29.    
    30.     if(new_ver_pixel_1 == old_ver_pixel_1):
    31.         new_ver_pixel_1 = new_ver_pixel_1 + 1
    32.     if(new_ver_pixel_2 == old_ver_pixel_2):
    33.         new_ver_pixel_2 = new_ver_pixel_2 + 1            
    34.        
    35.     if(new_ver_pixel_1 > old_ver_pixel_1):
    36.         y0_1 = old_ver_pixel_1
    37.         y1_1 = new_ver_pixel_1
    38.     else:
    39.         y0_2 = old_ver_pixel_2
    40.         y1_2 = new_ver_pixel_2        
    41.        
    42.     coord = hor_pixel, y0_1, hor_pixel, y1_1
    43.     coord2 = hor_pixel, y0_2, hor_pixel, y1_2        
    44.     hor_pixel = hor_pixel + 1
    45.  
    46.     if(hor_pixel > 400):
    47.         hor_pixel = 5;
    48.        
    49.     old_ver_pixel_1 = new_ver_pixel_1
    50.     old_ver_pixel_2 = new_ver_pixel_2
    51.  
    52.     C.create_line(hor_pixel , 0 , hor_pixel , 500, fill = 'black')
    53.     C.create_line(coord, fill = 'red')
    54.     C.create_line(coord2, fill = 'yellow')
    55.     C.pack()
    56.     #print(new_ver_pixel_1 , new_ver_pixel_2)
    57.  
    58.  
    59.  
    60. def graph():
    61.     global new_ver_pixel_1
    62.     global new_ver_pixel_2
    63.    
    64.     screen = Tkinter.Tk()
    65.     screen.title("Analog Channel")
    66.     screen.geometry("800x800")
    67.     C = Tkinter.Canvas(screen , bg = "black" , height = 800, width = 800)
    68.     C.pack()
    69.  
    70.     while True:
    71.         var = 0
    72.         var = var + 1
    73.         new_ver_pixel_1 = randint(0,200) + 200;
    74.         new_ver_pixel_2 = randint(0,200) + 400;
    75.         #print(new_ver_pixel_1 , new_ver_pixel_2)
    76.         #pixel(C)
    77.         screen.after(100,pixel(C))
    78.         screen.update_idletasks()
    79.  
    80.     screen.mainloop()
    81.  
    82.  
    83. graph()
    84.  
    85.  
     
    Last edited: Jul 14, 2015
  2. strantor

    AAC Fanatic!

    Oct 3, 2010
    4,302
    1,988
    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:

    Code (Python):
    1.  
    2. import Tkinter
    3. from random import randint
    4.  
    5. class pixelTron():
    6.  
    7.     def __init__(self):
    8.         self.hor_pixel = 5                      #starting point of horizontal pixel
    9.         self.old_ver_pixel_1 = 0                #last pixel value of graph 1
    10.         self.old_ver_pixel_2 = 0                #last pixel value of graph 2
    11.         self.new_ver_pixel_1 = 0                #new pixel value of graph 1
    12.         self.new_ver_pixel_2 = 0                #new pixel value of graph 2
    13.         self.y0_1 = 0                           # y cordinate of graph 1 & 2
    14.         self.y1_1 = 0
    15.         self.y0_2 = 0
    16.         self.y1_2 = 0
    17.  
    18.  
    19.     def pixel(self, C):
    20.         nP1 = self.new_ver_pixel_1
    21.         oP1 = self.old_ver_pixel_1
    22.         nP2 = self.new_ver_pixel_2
    23.         oP2 = self.old_ver_pixel_2
    24.         hP = self.hor_pixel
    25.         if(nP1 == oP1):
    26.             nP1 = nP1 + 1
    27.         if(nP2 == oP2):
    28.             nP2 = nP2 + 1
    29.  
    30.         if(nP1 > oP1):
    31.             self.y0_1 = oP1
    32.             self.y1_1 = nP1
    33.         else:
    34.             self.y0_2 = oP2
    35.             self.y1_2 = nP2
    36.  
    37.         coord = hP, self.y0_1, hP, self.y1_1
    38.         coord2 = hP, self.y0_2, hP, self.y1_2
    39.         hP = hP + 1
    40.  
    41.         if(hP > 400):
    42.             hP = 5;
    43.  
    44.         self.old_ver_pixel_1 = nP1
    45.         self.old_ver_pixel_2 = nP2
    46.  
    47.         C.create_line(hP , 0 , hP , 500, fill = 'black')
    48.         C.create_line(coord, fill = 'red')
    49.         C.create_line(coord2, fill = 'yellow')
    50.         C.pack()
    51.         self.hor_pixel = hP
    52.  
    53.  
    54.  
    55.     def graph(self):
    56.  
    57.         screen = Tkinter.Tk()
    58.         screen.title("Analog Channel")
    59.         screen.geometry("800x800")
    60.         C = Tkinter.Canvas(screen , bg = "black" , height = 800, width = 800)
    61.         C.pack()
    62.         pixel = self.pixel
    63.  
    64.         while True:
    65.             self.new_ver_pixel_1 = randint(0,200) + 200;
    66.             self.new_ver_pixel_2 = randint(0,200) + 400;
    67.             screen.after(100,pixel(C))
    68.             screen.update()
    69.  
    70.         screen.mainloop()
    71.  
    72. PT = pixelTron()
    73. PTG = PT.graph
    74. PTG()
    75.  
     
    Vindhyachal Takniki likes this.
  3. Vindhyachal Takniki

    Thread Starter Member

    Nov 3, 2014
    349
    6
    strantor likes this.
  4. Vindhyachal Takniki

    Thread Starter Member

    Nov 3, 2014
    349
    6
    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 (Text):
    1.  
    2. #this is main file
    3.  
    4. import graph
    5.  
    6. while True:
    7.     graph.my_graph()
    8.     print("DONE")
    9.    #do other things
    10.  

    graph.py
    Code (Text):
    1.  
    2. import Tkinter
    3. from random import randint
    4.  
    5. class pixelTron():
    6.  
    7.     def __init__(self):
    8.         self.hor_pixel = 5                      #starting point of horizontal pixel
    9.         self.old_ver_pixel_1 = 0                #last pixel value of graph 1
    10.         self.old_ver_pixel_2 = 0                #last pixel value of graph 2
    11.         self.new_ver_pixel_1 = 0                #new pixel value of graph 1
    12.         self.new_ver_pixel_2 = 0                #new pixel value of graph 2
    13.         self.y0_1 = 0                           # y cordinate of graph 1 & 2
    14.         self.y1_1 = 0
    15.         self.y0_2 = 0
    16.         self.y1_2 = 0
    17.  
    18.  
    19.     def pixel(self, C):
    20.         nP1 = self.new_ver_pixel_1
    21.         oP1 = self.old_ver_pixel_1
    22.         nP2 = self.new_ver_pixel_2
    23.         oP2 = self.old_ver_pixel_2
    24.         hP = self.hor_pixel
    25.         if(nP1 == oP1):
    26.             nP1 = nP1 + 1
    27.         if(nP2 == oP2):
    28.             nP2 = nP2 + 1
    29.  
    30.         if(nP1 > oP1):
    31.             self.y0_1 = oP1
    32.             self.y1_1 = nP1
    33.         else:
    34.             self.y0_2 = oP2
    35.             self.y1_2 = nP2
    36.  
    37.         coord = hP, self.y0_1, hP, self.y1_1
    38.         coord2 = hP, self.y0_2, hP, self.y1_2
    39.         hP = hP + 1
    40.  
    41.         if(hP > 400):
    42.             hP = 5;
    43.  
    44.         self.old_ver_pixel_1 = nP1
    45.         self.old_ver_pixel_2 = nP2
    46.  
    47.         C.create_line(hP , 0 , hP , 500, fill = 'black')
    48.         C.create_line(coord, fill = 'red')
    49.         C.create_line(coord2, fill = 'yellow')
    50.         C.pack()
    51.         self.hor_pixel = hP
    52.  
    53.  
    54.  
    55.     def graph(self):
    56.  
    57.         screen = Tkinter.Tk()
    58.         screen.title("Analog Channel")
    59.         screen.geometry("800x800")
    60.         C = Tkinter.Canvas(screen , bg = "black" , height = 800, width = 800)
    61.         C.pack()
    62.         pixel = self.pixel
    63.  
    64.         while True:
    65.             self.new_ver_pixel_1 = randint(0,200) + 200;
    66.             self.new_ver_pixel_2 = randint(0,200) + 400;
    67.             screen.after(100,pixel(C))
    68.             screen.update()
    69.  
    70.         screen.mainloop()
    71.  
    72. def my_graph():
    73.     PT = pixelTron()
    74.     PTG = PT.graph
    75.     PTG()
    76.  
    77.  


    Error code is:
    Code (Text):
    1.  
    2. Traceback (most recent call last):
    3.   File "C:\Users\main.py", line 6, in <module>
    4.     graph.my_graph()
    5.   File "C:\Users\graph.py", line 74, in my_graph
    6.     PTG()
    7.   File "C:\Users\graph.py", line 66, in graph
    8.     screen.after(100,pixel(C))
    9.   File "C:\Users\graph.py", line 46, in pixel
    10.     C.create_line(hP , 0 , hP , 500, fill = 'black')
    11.   File "C:\Python27\lib\lib-tk\Tkinter.py", line 2317, in create_line
    12.     return self._create('line', args, kw)
    13.   File "C:\Python27\lib\lib-tk\Tkinter.py", line 2305, in _create
    14.     *(args + self._options(cnf, kw))))
    15. TclError: invalid command name ".43840856"
    16.  
     
  5. strantor

    AAC Fanatic!

    Oct 3, 2010
    4,302
    1,988
    The error is because there is no "destructor" handler (google that).

    This works with no errors:

    Code (Python):
    1.  
    2. __author__ = 'chuck'
    3. import Tkinter
    4. from random import randint
    5.  
    6. class pixelTron():
    7.  
    8.     def __init__(self):
    9.         self.hor_pixel = 5                      #starting point of horizontal pixel
    10.         self.old_ver_pixel_1 = 0                #last pixel value of graph 1
    11.         self.old_ver_pixel_2 = 0                #last pixel value of graph 2
    12.         self.new_ver_pixel_1 = 0                #new pixel value of graph 1
    13.         self.new_ver_pixel_2 = 0                #new pixel value of graph 2
    14.         self.y0_1 = 0                           # y cordinate of graph 1 & 2
    15.         self.y1_1 = 0
    16.         self.y0_2 = 0
    17.         self.y1_2 = 0
    18.         self.screen = Tkinter.Tk()
    19.         self.running = 1
    20.         self.screen.protocol("WM_DELETE_WINDOW", self.suicide)
    21.  
    22.     def pixel(self, C):
    23.         nP1 = self.new_ver_pixel_1
    24.         oP1 = self.old_ver_pixel_1
    25.         nP2 = self.new_ver_pixel_2
    26.         oP2 = self.old_ver_pixel_2
    27.         hP = self.hor_pixel
    28.         if(nP1 == oP1):
    29.             nP1 = nP1 + 1
    30.         if(nP2 == oP2):
    31.             nP2 = nP2 + 1
    32.  
    33.         if(nP1 > oP1):
    34.             self.y0_1 = oP1
    35.             self.y1_1 = nP1
    36.         else:
    37.             self.y0_2 = oP2
    38.             self.y1_2 = nP2
    39.         coord = hP, self.y0_1, hP, self.y1_1
    40.         coord2 = hP, self.y0_2, hP, self.y1_2
    41.         hP = hP + 1
    42.         if(hP > 400):
    43.             hP = 5;
    44.         self.old_ver_pixel_1 = nP1
    45.         self.old_ver_pixel_2 = nP2
    46.  
    47.         C.create_line(hP , 0 , hP , 500, fill = 'black')
    48.         C.create_line(coord, fill = 'red')
    49.         C.create_line(coord2, fill = 'yellow')
    50.         C.pack()
    51.         self.hor_pixel = hP
    52.  
    53.     def graph(self):
    54.         screen = self.screen
    55.         screen.title("Analog Channel")
    56.         screen.geometry("800x800")
    57.         C = Tkinter.Canvas(screen , bg = "black" , height = 800, width = 800)
    58.         C.pack()
    59.         pixel = self.pixel
    60.         while self.running:
    61.             self.new_ver_pixel_1 = randint(0,200) + 200;
    62.             self.new_ver_pixel_2 = randint(0,200) + 400;
    63.             screen.after(100,pixel(C))
    64.             screen.update()
    65.         screen.mainloop()
    66.  
    67.     def suicide(self):
    68.         print "DONE"
    69.         self.running = 0
    70.         self.screen.destroy()
    71.  
    72. def my_graph():
    73.     PT = pixelTron()
    74.     PTG = PT.graph
    75.     PTG()
    and for the program that calls it:
    Code (Python):
    1.  
    2. __author__ = 'chuck'
    3. import graph
    4.  
    5. #NO NEED FOR "WHILE TRUE" HERE
    6. graph.my_graph()
    7.  
     
    Vindhyachal Takniki likes this.
  6. Vindhyachal Takniki

    Thread Starter Member

    Nov 3, 2014
    349
    6
    strantor likes this.
Loading...