Найти - Пользователи
Полная версия: Передача параметров между потоками и вывод в gui tkinter
Начало » GUI » Передача параметров между потоками и вывод в gui tkinter
1
pal201
Выполняется несколько потоков, нужно что бы каждый поток мог писать в окно scrolledtext. Делаю через глобальную переменную-список.

log=
n_log=

def win():
global log,n_log
tk=Tk()
st=ScrolledText(tk)
st.pack()
if len(log)>len(n_log):
st.insert(END,log)
n_log=log
tk.update()
tk.mainloop()

def print_log(tx):
global log, n_log
print log,n_log
log.extend()

в потоках вызывается функция print_log. нужно что бы обновлялось окно и дописывался лог в это окно. Подскажите как решить?
truporez
Если одна очередь на всех, то Queue. Если приватно, то Pipe.
pal201
Очередей и пулов нет. Потоки не будут создаваться динамически. Простто есть 3 потока, 1 из них -.> Gui, из дух других нужно писать в scrolledtext, вроде как и задаче не сложная, как решить?
truporez
Создать глобальную очередь(Queue) и всем негуевым потокам туда писать, а гуевый тред пусть выгребает.
Можно и через глобальный список, только надо использовать mutex'ы, и учитывая, что списки суть объекты изменяемые - возможны различные глюки.
pal201
Дело в том, что я не понимаю как “выгребать”. Например, обновилась переменная список, как заставить перечитать ее GUI? У меня получается, что она читается только один раз в момент создания. Я так понимаю, что нужно сделать некоторый обработчик событий?
truporez
Не ленитесь читать документацию. http://docs.python.org/library/queue.html
есть методы put и get
pal201
все это хорошо, но не понятно! Вот реализация обновления на простом примере, используется переменная:
import Tkinter
import time

curtime = ‘'
clock = Tkinter.Label()
clock.pack()

def tick():
global curtime
newtime = time.strftime(’%H:%M:%S')
if newtime != curtime:
curtime = newtime
clock.config(text=curtime)
clock.after(200, tick)

tick()
clock.mainloop()

Все предельно просто, я хочу так же использовать переменную, а оно что-то не работает, хотя переменная меняется.
truporez
ваш пример работает.

а вот пример с использование дополнительной нити
import Tkinter
import time
import Queue
import threading

queue = Queue.Queue()

log_lb = Tkinter.Listbox()
log_lb.pack()

def lb_updater():
global queue
try:
val = queue.get()
log_lb.insert(Tkinter.END, val)
log_lb.see(Tkinter.END)
except Queue.Empty:
pass
log_lb.after(1000,lb_updater)

def worker(queue, stop_event):
while not stop_event.is_set():
queue.put(time.strftime('%H:%M:%S'))
time.sleep(1)

stop_event = threading.Event()

th = threading.Thread(target=worker, args=(queue,stop_event))
th.start()

lb_updater()
log_lb.mainloop()

stop_event.set()
th.join()
pal201
Решил проблему обновления таким способом:
def l():
global log
st.delete('1.0',END)
for t in log:
st.insert(END,str(t)+'\n')
tk.after(300,l)
l()
#var=StringVar(tk)
tk.mainloop()

И сразу возник вопрос, у меня запускается gui в отдельном потоке, все вроде выполняется, но главное окно закрывается сразу после завершения основного тела программы. Что делать?
GUI запускаю так:
thread.start_new(win,())
pal201
Решил переписать код используя класс, теперь зависает. Что делаю неправильно?:

# -*- coding: utf-8 -*-

from Tkinter import *
import threading,time
from ScrolledText import *

log=

class AppGUI:
global log
def __init__(self):
#self.insert_st #запуск вывода на экран лога
self.tk = Tk()
frame = Frame(self.tk)
frame.pack()

button=Button(frame, text=“Write_Log”, command=self.write_log)
button.pack()
button2=Button(frame, text=“Print_Log”, command=self.print_log('123'))
button2.pack()

self.st=ScrolledText(frame)
self.st.pack()


def insert_st(self):
global log
#print log
self.st.delete('1.0',END)
for t in log:
self.st.insert(END,str(t)+'\n')
self.tk.after(300,self.insert_st)


def run(self):
self.tk.mainloop()
def write_log(self):
threading.Thread(target=gui.insert_st).start()

def print_log(self,tx):
global log
#mutex.acquire()
log.append(tx)
#mutex.release()

gui = AppGUI()
gui.run()
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB