Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » Передача параметров между потоками и вывод в gui tkinter [RSS Feed]

#1 Фев. 25, 2010 15:58:36

pal201
От:
Зарегистрирован: 2010-01-05
Сообщения: 83
Репутация: +  0  -
Профиль   Отправить e-mail  

Передача параметров между потоками и вывод в gui tkinter

Выполняется несколько потоков, нужно что бы каждый поток мог писать в окно 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. нужно что бы обновлялось окно и дописывался лог в это окно. Подскажите как решить?



Офлайн

#2 Фев. 25, 2010 16:27:30

truporez
От:
Зарегистрирован: 2009-05-08
Сообщения: 266
Репутация: +  6  -
Профиль   Адрес электронной почты  

Передача параметров между потоками и вывод в gui tkinter

Если одна очередь на всех, то Queue. Если приватно, то Pipe.



Офлайн

#3 Фев. 25, 2010 16:45:01

pal201
От:
Зарегистрирован: 2010-01-05
Сообщения: 83
Репутация: +  0  -
Профиль   Отправить e-mail  

Передача параметров между потоками и вывод в gui tkinter

Очередей и пулов нет. Потоки не будут создаваться динамически. Простто есть 3 потока, 1 из них -.> Gui, из дух других нужно писать в scrolledtext, вроде как и задаче не сложная, как решить?



Офлайн

#4 Фев. 25, 2010 17:06:50

truporez
От:
Зарегистрирован: 2009-05-08
Сообщения: 266
Репутация: +  6  -
Профиль   Адрес электронной почты  

Передача параметров между потоками и вывод в gui tkinter

Создать глобальную очередь(Queue) и всем негуевым потокам туда писать, а гуевый тред пусть выгребает.
Можно и через глобальный список, только надо использовать mutex'ы, и учитывая, что списки суть объекты изменяемые - возможны различные глюки.



Отредактировано (Фев. 25, 2010 17:24:35)

Офлайн

#5 Фев. 25, 2010 19:06:16

pal201
От:
Зарегистрирован: 2010-01-05
Сообщения: 83
Репутация: +  0  -
Профиль   Отправить e-mail  

Передача параметров между потоками и вывод в gui tkinter

Дело в том, что я не понимаю как “выгребать”. Например, обновилась переменная список, как заставить перечитать ее GUI? У меня получается, что она читается только один раз в момент создания. Я так понимаю, что нужно сделать некоторый обработчик событий?



Офлайн

#6 Фев. 25, 2010 20:15:19

truporez
От:
Зарегистрирован: 2009-05-08
Сообщения: 266
Репутация: +  6  -
Профиль   Адрес электронной почты  

Передача параметров между потоками и вывод в gui tkinter

Не ленитесь читать документацию. http://docs.python.org/library/queue.html
есть методы put и get



Офлайн

#7 Фев. 25, 2010 20:46:31

pal201
От:
Зарегистрирован: 2010-01-05
Сообщения: 83
Репутация: +  0  -
Профиль   Отправить e-mail  

Передача параметров между потоками и вывод в gui tkinter

все это хорошо, но не понятно! Вот реализация обновления на простом примере, используется переменная:
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()

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



Отредактировано (Фев. 25, 2010 20:48:02)

Офлайн

#8 Фев. 25, 2010 21:50:24

truporez
От:
Зарегистрирован: 2009-05-08
Сообщения: 266
Репутация: +  6  -
Профиль   Адрес электронной почты  

Передача параметров между потоками и вывод в gui tkinter

ваш пример работает.

а вот пример с использование дополнительной нити

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()



Офлайн

#9 Фев. 27, 2010 16:04:57

pal201
От:
Зарегистрирован: 2010-01-05
Сообщения: 83
Репутация: +  0  -
Профиль   Отправить e-mail  

Передача параметров между потоками и вывод в gui tkinter

Решил проблему обновления таким способом:
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,())



Отредактировано (Фев. 27, 2010 16:05:28)

Офлайн

#10 Фев. 27, 2010 21:36:56

pal201
От:
Зарегистрирован: 2010-01-05
Сообщения: 83
Репутация: +  0  -
Профиль   Отправить e-mail  

Передача параметров между потоками и вывод в gui tkinter

Решил переписать код используя класс, теперь зависает. Что делаю неправильно?:

# -*- 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()



Офлайн

  • Начало
  • » GUI
  • » Передача параметров между потоками и вывод в gui tkinter[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version