2013-08-28 4 views
0

У меня есть проблема с текстом wxpython и потоком. Поблагодарили бы за любую помощь в решении этой проблемы.wxpython threading textctrl delay

Моя программа обрабатывает файлы, так как и каждый файл обрабатывается, он указан в текстеctrl как готовый. При работе с несколькими файлами textctrl реагирует и отображает себя сразу и не исчезает. Даже если эти файлы большие. Был ли тест на файл 700mb и textctrl отлично работает.

Проблема возникает при работе во многих файлах, скажем, 20+ для exmaple. В этих условиях textctrl исчезает в течение 6 или 7 секунд, затем появляется снова и работает нормально.

Я пробовал обычную резьбу, демонную резьбу и т. Д. Также попробовал использовать .join(), который сделал вещи еще хуже. Мне интересно, если это только потому, что моя программа очень интенсивно работает с процессором, или если я просто делаю что-то неправильно.

Ниже представлена ​​моя строка строки кода. Пока это самый быстрый способ, просто недостаточно для моих целей. Спасибо заранее, Клинтон.

def Worker(self, e, _file): 

    match = '' 

    with open(_file, 'r') as f: 
     data = f.read() 

    for char in data: 
     if char in self.key: 
      match += chr(self.key.index(char)) 

    open(_file, 'w').close() 

    with open(_file, 'w') as f: 
     f.write(match) 

    wx.CallAfter(self.ListFilesEncrypt, e, _file) 

if __name__ == '__main__': 
    for _file in self.file2process: 
     self.filenum += 1 
     Thread(target=self.Worker, args=(e, _file,)).start() 
+0

Как вы обновляете текстовое управление из потока?Если вы вызываете текстовый элемент управления напрямую, у вас есть проблема –

+0

Вы утверждаете, что создаете несколько потоков, которые могут обновлять текстовое управление, возможно, сразу? –

+0

Честно говоря, я не знаю, как новый для питона и программирования. Приведенный выше код работает, но когда много файлов выбрано для обработки, textctrl исчезает в течение 6 секунд, а затем снова появляется. Как только он снова появится, он работает так, как должен. По мере обработки каждого файла он печатается в textctrl. Таким образом, вывод textctrl похож на вывод команды linux ls. Как только печать начинается, он работает нормально, его просто эта интуитивная досадная задержка. –

ответ

3

Обновите графический интерфейс, используя поточно-безопасные методы. В WxPython, есть 3:

  • wx.CallAfter
  • wx.CallLater
  • wx.PostEvent

Вы должны также гляньте вики WxPython для получения информации о WxPython и нарезание резьб:

Я также написал учебник по теме:

UPDATE: Вот простой пример, который создает 40 нитей и "процессы" 40 составлявшие файлов. Он обновляет дисплей, когда выполняется каждый поток. Однако я не вижу вопроса, о котором вы говорите.

import random 
import time 
import wx 

from threading import Thread 
from wx.lib.pubsub import Publisher 

######################################################################## 
class TestThread(Thread): 
    """Test Worker Thread Class.""" 

    #---------------------------------------------------------------------- 
    def __init__(self, fname, sleepAmt): 
     """Init Worker Thread Class.""" 
     Thread.__init__(self) 
     self.fname = fname 
     self.sleepAmt = sleepAmt 
     self.start() # start the thread 

    #---------------------------------------------------------------------- 
    def run(self): 
     """Run Worker Thread.""" 
     # This is the code executing in the new thread. 
     time.sleep(self.sleepAmt) 
     msg = "%s finished in %s seconds!" % (self.fname, self.sleepAmt) 
     wx.CallAfter(Publisher().sendMessage, "update", msg) 


######################################################################## 
class MyForm(wx.Frame): 

    #---------------------------------------------------------------------- 
    def __init__(self): 
     wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial") 

     panel = wx.Panel(self, wx.ID_ANY) 
     self.updateText = wx.TextCtrl(panel, style=wx.TE_MULTILINE) 
     self.btn = btn = wx.Button(panel, label="Start Thread") 

     btn.Bind(wx.EVT_BUTTON, self.onButton) 

     sizer = wx.BoxSizer(wx.VERTICAL) 
     sizer.Add(self.updateText, 1, wx.ALL|wx.EXPAND, 5) 
     sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5) 
     panel.SetSizer(sizer) 

     # create a pubsub receiver 
     Publisher().subscribe(self.updateDisplay, "update") 

    #---------------------------------------------------------------------- 
    def onButton(self, event): 
     """ 
     Runs the thread 
     """ 
     for i in range(40): 
      fname = "test%s.txt" % i 
      secs = random.choice(range(3, 15)) 
      TestThread(fname, secs) 

    #---------------------------------------------------------------------- 
    def updateDisplay(self, msg): 
     """ 
     Receives data from thread and updates the display 
     """ 
     data = msg.data + "\n" 
     self.updateText.WriteText(data) 

#---------------------------------------------------------------------- 
# Run the program 
if __name__ == "__main__": 
    app = wx.PySimpleApp() 
    frame = MyForm().Show() 
    app.MainLoop() 

Я бегу на Windows 7 с помощью Python 2.6 с WxPython 2.8.12.1

+0

Спасибо за ответ. Должен упомянуть, что я уже использую ww.CallAfter. Я даже попытался удалить все это вместе, чтобы увидеть, какой эффект он имеет. Не отвечайте ни на что, даже когда вы не печатаете в textctrl. Это как-то связано с количеством файлов, выбранных для обработки. Клинтон. –

+0

Я редактировал вопрос и предоставил код для функции рабочего потока. –

+0

Спасибо, Майк за пример кода. Причина, по которой вы не получаете такой же проблемы, как я, вполне может свести к тому, что ваш код - это то, что отличается от моего. Я все еще сейчас работаю над своей первой проблемой, в настоящее время около 300 строк кода, поэтому для меня нет Hello World :-) Мне кажется, что мне снова придется перезаписать (5 или 6 раз) используя ваш код в качестве примера. Меня это поражает, насколько сложно программировать GUI по сравнению с программой командной строки. Для меня это удваивает количество кода и утроит сложность. Еще раз спасибо, Клинтон. –

0

Ваши темы должны не обновляют управления текстом непосредственно - они должны либо использовать wx.CallAfter или, лучше, установить флаг для основной, (ГИУ), нить для обновления управления - это звучит как может быть целесообразным метод сквозной потока.

+0

Спасибо за ответ. В ответ на ответ Майка Дрисколла я уже использую wx.CallAfter, так что это не проблема. Это больше связано с количеством файлов, которые были выбраны для обработки. Даже удаленный wx.callafter, поэтому не было печати в textctrl. По-прежнему такая же проблема. Однако я рассмотрю ваши другие предложения. Клинтон. –

0

Более ресурсоемкие, это может быть IO интенсивно. И IO-интенсивные приложения могут иметь очень большое влияние на производительность, особенно когда вы также используете модули ввода-вывода для других важных целей, таких как пейджинг. Я предлагаю вам от 5 до 10 за один раз, а остальные остальное.

+0

Спасибо за ответ. Однажды попробовал очередь, но попробую еще раз. Я по-прежнему очень новичок в программировании, так что, возможно, это испортило это. –

Смежные вопросы