Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #98041 > unrolled thread

Multithreading python,two tkinter windows

Started byVindhyachal Takniki <vindhyachal.takniki@gmail.com>
First post2015-11-01 06:05 -0800
Last post2015-11-01 18:12 -0500
Articles 4 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  Multithreading python,two tkinter windows Vindhyachal Takniki <vindhyachal.takniki@gmail.com> - 2015-11-01 06:05 -0800
    Re: Multithreading python,two tkinter windows Laura Creighton <lac@openend.se> - 2015-11-01 15:26 +0100
    Re: Multithreading python,two tkinter windows Chris Angelico <rosuav@gmail.com> - 2015-11-02 01:31 +1100
    Re: Multithreading python,two tkinter windows Terry Reedy <tjreedy@udel.edu> - 2015-11-01 18:12 -0500

#98041 — Multithreading python,two tkinter windows

FromVindhyachal Takniki <vindhyachal.takniki@gmail.com>
Date2015-11-01 06:05 -0800
SubjectMultithreading python,two tkinter windows
Message-ID<271f8b42-da03-40fd-8a8b-c562292577e6@googlegroups.com>
I have made a python code & using multithreading in it. this is very basic code, not using queues & other stuff.

1. Task is to create two independent Tkinter windows

2. Code has four files: 
main.py:creates individual thread
analog.py: generate random values every 1 sec & 10 sec
screen.py: Tkinter file, screen keeps on updating every 1 sec
scree2.py: Tkinter file, screen keeps on updating every 10 sec

3. My code never run on gives anything. However if in main.py, I disable, one of either screen thread, another screen works fine. i.e they don't work together 


main.py
[code]import thread
import time
import analog
import screen
import screen2

thread.start_new_thread(analog.get_analog_1 , ("Thread-1",))
thread.start_new_thread(analog.get_analog_2 , ("Thread-2",))
thread.start_new_thread(screen.display , ("Thread-3",))
thread.start_new_thread(screen2.display , ("Thread-4",))

while 1:
    pass

[/code]

analog.py
[code]import time
from random import randint


current_time_1 = time.time();
current_time_2 = time.time();
read_ok_1 = 0
read_ok_2 = 0
analog_1 = 0
analog_2 = 0


#get reading at every 1 second
def get_analog_1(thread_name):
    global read_ok_1, current_time_1,analog_1
    while True:
        if((time.time() - current_time_1) > 1):
            if(0 == read_ok_1):
                current_time_1 = time.time();
                read_ok_1 = 1;
                analog_1 = randint(0,100)
                
                
#get reading on update                
def read_update_analog_1():
    global read_ok_1,analog_1
    data1 = 0
    val1 = 0
    if(1 == read_ok_1):
        read_ok_1 = 0;
        data1 = 1;
        val1 = analog_1
        
    return data1,val1                

    
    
#get reading at every 10 second
def get_analog_2(thread_name):
    global read_ok_2, current_time_2,analog_2
    while True:
        if((time.time() - current_time_2) > 10):
            if(0 == read_ok_2):
                current_time_2 = time.time();
                read_ok_2 = 1;
                analog_2 = randint(0,100)
                
                
#get reading on update                
def read_update_analog_2():
    global read_ok_2,analog_2
    data2 = 0
    val2 = 0
    if(1 == read_ok_2):
        read_ok_2 = 0;
        data2 = 1;
        val2 = analog_2
        
    return data2,val2        


[/code]

screen.py
[code]
from Tkinter import *
import analog
import thread
import time

class App():
    
    def __init__(self, master):
        self.master = master

        frame = Frame(master)
        frame.pack()

        label = Label(frame , text = "Analog" , font = ("Helvetica",32))
        label.grid(row = 0)

        self.reading_label = Label(frame, text = '0.0' , font = ("Helvetica",70))
        self.reading_label.grid(row = 1)
        
        self.update_reading()

        

    def update_reading(self):        
        data1,val1 = analog.read_update_analog_1()
        if(1 == data1):
            reading_str = "{:.1f}".format(val1)
            self.reading_label.configure(text = reading_str)
        
        self.master.after(100 , self.update_reading)
        

def display(threadName):
    root = Tk()
    root.wm_title("Ammeter")
    app = App(root)
    root.geometry("480x320")
    root.mainloop()
[/code]

screen2.py
[code]from Tkinter import *
import analog
import thread
import time

class App():
    
    def __init__(self, master):
        self.master = master

        frame = Frame(master)
        frame.pack()

        label = Label(frame , text = "Analog" , font = ("Helvetica",32))
        label.grid(row = 0)

        self.reading_label = Label(frame, text = '0.0' , font = ("Helvetica",70))
        self.reading_label.grid(row = 1)

        self.update_reading()

        

    def update_reading(self):
    
        data1,val1 = analog.read_update_analog_2()
        if(1 == data1):
            reading_str = "{:.1f}".format(val1)
            self.reading_label.configure(text = reading_str)
        
        self.master.after(1000 , self.update_reading)
        

def display(threadName):
    root = Tk()
    root.wm_title("Voltmeter")
    app = App(root)
    root.geometry("480x320")
    root.mainloop()
[/code]

[toc] | [next] | [standalone]


#98042

FromLaura Creighton <lac@openend.se>
Date2015-11-01 15:26 +0100
Message-ID<mailman.21.1446388018.4463.python-list@python.org>
In reply to#98041
In a message of Sun, 01 Nov 2015 06:05:58 -0800, Vindhyachal Takniki writes:
>I have made a python code & using multithreading in it. this is very basic code, not using queues & other stuff.

This is your problem.
The code that uses queues is more basic.
For tkinter you cannot use threads like you do.
You must have one controlling thread, and several worker threads.
The best way to do this is using a queue.

http://code.activestate.com/recipes/82965-threads-tkinter-and-asynchronous-io/

(written by a freind of mine, wandering around in the next room)

outlines how to set this up  for all your tkinter tasks.

Laura

[toc] | [prev] | [next] | [standalone]


#98045

FromChris Angelico <rosuav@gmail.com>
Date2015-11-02 01:31 +1100
Message-ID<mailman.23.1446388298.4463.python-list@python.org>
In reply to#98041
On Mon, Nov 2, 2015 at 1:05 AM, Vindhyachal Takniki
<vindhyachal.takniki@gmail.com> wrote:
> #get reading at every 1 second
> def get_analog_1(thread_name):
>     global read_ok_1, current_time_1,analog_1
>     while True:
>         if((time.time() - current_time_1) > 1):
>             if(0 == read_ok_1):
>                 current_time_1 = time.time();
>                 read_ok_1 = 1;
>                 analog_1 = randint(0,100)

Never do this. It's called a "busy-wait", and not only does it
saturate your Python thread, it also saturates your entire system -
this is going to keep one CPU core permanently busy going "are we
there yet? are we there yet?" about the one-second delay. Instead, use
time.sleep(), which will delay your thread by one second, allowing
other threads to run.

Better still, think about your code in terms of events. Most GUI
libraries these days are built around an event-driven model, and the
notion of "make this event happen 1 second from now" or "10 seconds
from now" is a very common one.

ChrisA

[toc] | [prev] | [next] | [standalone]


#98072

FromTerry Reedy <tjreedy@udel.edu>
Date2015-11-01 18:12 -0500
Message-ID<mailman.42.1446419563.4463.python-list@python.org>
In reply to#98041
On 11/1/2015 9:05 AM, Vindhyachal Takniki wrote:
> I have made a python code & using multithreading in it. this is very basic code, not using queues & other stuff.

You can run multiple windows, or one window with multiple panes, in one 
thread with one event loop.  Best to do gui stuff in the main thread and 
only use other threads for things that would block.  I see that you 
already know how to use .after to loop.  You can have multiple .after 
loops, with different delays, in one thread.

-- 
Terry Jan Reedy

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web