#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    26
    Rep Power
    0

    How to print variable serial data on Tkinter window.


    This code is to receive serial data and to print on the TKinter window. The received data prints on the window from top to bottom.

    I want 1 line of received data to print at the middle of the window, instead of printing from top. If i receive 3 lines of data, this data should display on the window by leaving equal space on top and bottom of the window Irrespective of the length of data, it should print on the window by leaving equal size of top and bottom space on the window.

    Code:
    import serial
        import threading
        import Queue
        import Tkinter as tk
    
        class SerialThread(threading.Thread):
            def __init__(self, queue):
                threading.Thread.__init__(self)
                self.queue = queue
            def run(self):
                s = serial.Serial('COM10',9600, timeout=10)
                s.bytesize = serial.EIGHTBITS #number of bits per  bytes
                s.parity = serial.PARITY_NONE #set parity check: no parity
                s.stopbits = serial.STOPBITS_ONE #number of stop bits
    
                while True:
                    if s.inWaiting():
                        text = s.readline(s.inWaiting())
                        self.queue.put(text)
    
        class App(tk.Tk):
            def __init__(self):
                tk.Tk.__init__(self)
                self.geometry("1360x750")
                frameLabel = tk.Frame(self, padx=40, pady =40)
                self.text = tk.Text(frameLabel, wrap='word',     font='TimesNewRoman 37',
                            bg=self.cget('bg'), relief='flat')
                frameLabel.pack()
                self.text.pack()
                self.queue = Queue.Queue()
                thread = SerialThread(self.queue)
                thread.start()
                self.process_serial()
    
            def process_serial(self):
                self.text.delete(1.0, 'end')
                while self.queue.qsize():
                    try:
                        self.text.insert('end', self.queue.get())
                    except Queue.Empty:
                        pass
                self.after('1500', self.process_serial)
    
        app = App()
        app.mainloop()
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,850
    Rep Power
    481

    Struggle


    After significant struggle I finally read Text.delete documentation. Here I've moved the away from the start. The characters overwrite at that position. And I removed serial to broaden the availability.
    Code:
    import pprint
    import random
    import time
    import threading
    import Queue
    import Tkinter as tk
    
    class SerialThread(threading.Thread):
    
        def __init__(self, queue):
            threading.Thread.__init__(self)
            self.queue = queue
    
        def run(self):
            for i in 'abcdefg':
                time.sleep(2)
                self.queue.put(i or random.choice('Thequickbrownfoxjumpsoverlazydog.'))
    
    class App(tk.Tk):
    
        def __init__(self):
            tk.Tk.__init__(self)
            self.geometry("1000x500")
            frameLabel = tk.Frame(self, padx=40, pady =40)
            self.text = text = tk.Text(
                frameLabel, wrap='word', font='TimesNewRoman 37',
                bg=self.cget('bg'), relief='flat')
            frameLabel.pack()
            text.pack()
    
            # move the end to the center
            c = text.config()
            w = c['width'][-1] # lucky guess?
            h = c['height'][-1]
            r = 10.0/37.0 # rough ratio of font size.  Width and height ratios differ
            self.center = '{}.{}'.format(int(round((h*r/2))), int(round(w*r/2)))
            text.insert(tk.END, '\n'*int(round((h*r/2))) + ' '*int(round(w*r/2)))
    
            self.queue = Queue.Queue()
            thread = SerialThread(self.queue)
            thread.start()
            self.process_serial()
    
        def process_serial(self):
            text = self.text
            center = self.center
            try:
                text.delete(center)
                text.insert(center, self.queue.get_nowait())
            except Queue.Empty:
                pass
            self.after(1500, self.process_serial)
    
    app = App()
    app.mainloop()
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    26
    Rep Power
    0
    @b49P23TIvg: Thanks for you replay, Here what i need exactly is
    if i receive just a single line of ASCII data, that should print in the middle of the window. Transmitter will send variable data, and this data should display on the window. When we receive 3 or 4 lines of ASCII data, this data should print at the middle of the window by leaving some space at the borders on the window. Irrespective of the size of the received data, it automatically adjust the data to print on the window.

    My question is @
    In breif:The font i choose is 37 in my code.with this font size i can print 9 lines on the window. if i receive 1 line of data,this data should print on 5th line, by leaving equal amount of space at top and bottom of the window.Again i may receive 3 line of serial data, this data should print from 4th to 6th line of the window by leaving equal space on top and bottom.Again if i receive 6 lines of serial data, this should print from 2nd line to 7th line on the window. Irrespective of data size, data should print on window,by leaving equal amount of spaces at top and bottom of the window. This display will make a good impression to see on the window.
    So what i have to do in my code to achieve this kind of display. please help me out. thanks.
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,850
    Rep Power
    481
    The rest is algebra.
    Code:
    import random
    import time
    import threading
    import Queue
    import Tkinter as tk
    
    message = ''' rose's red, vida's blue, ford's white, winkum, blinkum, nod'''.split(',')#'
    
    def amazing():
        random.shuffle(message)
        n = random.randrange(len(message))
        text = '\n'.join(message[:n+1])
        return '\n'*max(0,2-n//2)+text
    
    class SerialThread(threading.Thread):
    
        def __init__(self, queue):
            threading.Thread.__init__(self)
            self.queue = queue
    
        def run(self):
            for i in 'abcdefg'*2:
                time.sleep(2)
                self.queue.put(amazing())
    
    class App(tk.Tk):
    
        def __init__(self):
            tk.Tk.__init__(self)
            self.geometry("1000x500")
            frameLabel = tk.Frame(self, padx=40, pady =40)
            self.text = text = tk.Text(
                frameLabel, wrap='word', font='TimesNewRoman 37',
                bg=self.cget('bg'), relief='flat')
            frameLabel.pack()
            text.pack()
            self.queue = Queue.Queue()
            thread = SerialThread(self.queue)
            thread.start()
            self.process_serial()
    
        def process_serial(self):
            try:
                text = self.text
                text.delete(1.0,tk.END)
                text.insert(tk.END, self.queue.get_nowait())
            except Queue.Empty:
                pass
            self.after(1500, self.process_serial)
    
    app = App()
    app.mainloop()
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    26
    Rep Power
    0
    @b49p23TIvg:
    In the code
    [self.root.after(1500, self.process_serial)]
    Here the first text will display and wait for 1500ms, then second text will display and wait for 1500ms, it will keep on doing this.
    but in my code i don't know when i receive the serial data,if i receive serial data, this data should display until i receive other serial data to print on the window.The time is variable(changing) in between the data which is received.

    In brief:Here transmitter will send data, my code is just to receive data and print on the window. The transmitter might send data in 10 seconds or in 4 minutes or in 10 minutes. The receiver don't know when the transmitter sends the data.
    so i want to receive data and display it until it receives other serial data again. In my code if i use 1500ms, the serial received data is just displaying for 1500ms. I dont want to just display for 1500ms, the data should be on the screen until it receives other serial data.
    please help me.

    thank you


    Thank you very much for the code, to print the text on the window by leaving equal space at top and bottom of the window.

    I tried to implement that in my code but i could't succeed. I have seen the output of your code, its perfect. I want that same way in my code. In my code I want the received serial data to print on the window by leaving space at top and bottom of the window. The main issue is, i don't know the size of the data which i am receiving serially. Please do this for me, by editing my code.
    I am new to python and working out from few days.
    please do this for me by editing my code to print data on the window.
    thank you.
  10. #6
  11. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,850
    Rep Power
    481
    Dear srinivas.rambha,

    I love you but I don't know what further to do. Simulating the possible input from the serial seemed like a good idea so anyone reading the forum might have working code without the same hardware you have. If i have a serial device to attach to my computer I don't know about it. One might change the input delay to a randomly chosen time to enhance the simulation quality. This won't answer your question.

    Dave
    [code]Code tags[/code] are essential for python code and Makefiles!
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    26
    Rep Power
    0
    Dave,
    My hardware is, 2 pc's connected with RS232 cable. one pc will send data from hyper terminal to 2nd pc (python, pyserial installed). So when ever 1st pc send data, 2nd pc will receive data and display on the Tkinter window.
    If you had 2 pc's and RS 232 cable, please run the code. If you don't have these hardware just ignore my question.

    My major issue is, self.after(1500, self.process_serial).
    Here data is printing just for 1500 milliseconds. I want the received data to print on the window until it receives data again to print on window. PLease try.

    Any how thanks a lot, you replies made me happy.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    26
    Rep Power
    0
    Originally Posted by srinivas.rambha
    Dave,
    My hardware is, 2 pc's connected with RS232 cable. one pc will send data from hyper terminal to 2nd pc (python, pyserial installed). So when ever 1st pc send data, 2nd pc will receive data and display on the Tkinter window.
    If you had 2 pc's and RS 232 cable, please run the code. If you don't have these hardware just ignore my question.

    My major issue is, self.after(1500, self.process_serial).
    Here data is printing just for 1500 milliseconds. I want the received data to print on the window until it receives data again to print on window. PLease try.

    Any how thanks a lot, you replies made me happy.


    If possible please help me, you are the only hope. because no one except you replied to my question. thanks

IMN logo majestic logo threadwatch logo seochat tools logo