Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multithreading python,two tkinter windows

118 views
Skip to first unread message

Vindhyachal Takniki

unread,
Nov 1, 2015, 9:06:39 AM11/1/15
to
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]

Laura Creighton

unread,
Nov 1, 2015, 9:27:21 AM11/1/15
to
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


Chris Angelico

unread,
Nov 1, 2015, 9:31:50 AM11/1/15
to
On Mon, Nov 2, 2015 at 1:05 AM, Vindhyachal Takniki
<vindhyach...@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

Terry Reedy

unread,
Nov 1, 2015, 6:13:03 PM11/1/15
to
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

0 new messages