我试图管理包含"其他文件的文件" (许多小文件存储在几个大文件中)。 "引擎"效果很好,但我有一些GUI问题。由于处理时间的原因,某些功能是线程化的,例如删除或添加文件。这是代码的一部分:
import gtk, os, data, time, threading, subprocess
import Image, re
gtk.gdk.threads_init()
#some unimportant code - creating window with some buttons and IconView item (to show elements in currently opened directory)
def _del_thread(self): #deletes items selected in gtk.IconView
dl, fl = self.items #self.items stores selected dirs and files
for d in dl:
self.changestatus('Deleting: '+data.dirs[d][0]+'...') #prints the text at StatusBar (data.dirs[d][0] is a filename)
data.RemoveDir(d) #recursively removes all content in directory d
for f in fl:
self.changestatus('Usuwanie pliku: '+data.files[f][0]+'...')
data.PopFile(f) #removes single file
self.changestatus('') #clears the StatusBar
self.refresh() #some elements are deleted - refresh IconView
def _add_thread(self, fl): #adds files listed in fl
for f in fl:
self.changestatus('Adding: '+f[-50:]+'...')
#some unimportant code (recognizing file's extension and generating a thumbnail
data.PutFile(f, thumb, self.dir) #adds the file with generated thumbnail to currently opened directory (self.dir)
self.changestatus('') #clears the StatusBar
self.refresh() #some elements are added - refresh IconView
def Delete(self, widget): #triggered by clicking a context-menu item
md = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, \
gtk.MESSAGE_QUESTION, gtk.BUTTONS_OK_CANCEL, \
"Do you want to remove selected items?")
res = md.run()
md.destroy()
if res == gtk.RESPONSE_OK:
t = threading.Thread(target=self._del_thread) #start new thread
t.start()
def Add(self, widget): #triggered by clicking a context-menu item
chooser = gtk.FileChooserDialog(title='Select files to add...',action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
chooser.set_select_multiple(True)
response = chooser.run()
if response == gtk.RESPONSE_OK:
#star new thread with selected files' list as an argument
t = threading.Thread(target=self._add_thread, args=(chooser.get_filenames(),))
t.start()
chooser.destroy()
还有一个在线程中运行的第三个函数,但它并不重要。它很快(约1秒),总是执行得很好,永远不会冻结窗口。其他两个(如上所示)有时执行得很好,有时不执行。例如,我在FileChooserDialog中选择一些文件,添加线程开始,StatusBar现在连续显示文件正在添加,最后窗口冻结。之后,窗口看起来像那样(抱歉抛光描述): 为什么线程有时会毫无问题地处理,有时候不会?
祝你好运, mopsiok
答案 0 :(得分:2)
我想我发现了这个问题。根据{{3}},我必须在线程中的每个gtk函数之前添加gtk.threads_enter(),然后在它之后添加gtk.threads_close()。现在它似乎工作正常。