0

「その他のファイル」(いくつかの大きなファイルに保存された小さなファイルがたくさんある)を含むファイルを管理しようとしています。「エンジン」は非常にうまく機能しますが、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()

スレッドで実行される 3 番目の関数もありますが、重要ではありません。高速 (~1 秒) で、常に正常に実行され、ウィンドウがフリーズすることはありません。他の 2 つ (上図) は、うまく実行される場合もあれば、実行されない場合もあります。たとえば、FileChooserDialog でいくつかのファイルを選択すると、追加スレッドが開始され、ファイルが現在追加されていることを示す StatusBar が連続して表示され、最後にウィンドウがフリーズします。その後、ウィンドウは次のようになります (洗練された説明で申し訳 pygtk ウィンドウ + スレッド化、ウィンドウがフリーズする ありません)。

よろしく、 モプシク

4

1 に答える 1

2

私は問題を見つけたと思います。http://faq.pygtk.org/index.py?file=faq20.006.htp&req=showによると、スレッド内のすべての gtk 関数の前に gtk.threads_enter() を追加し、その後に gtk.threads_close() を追加する必要がありました. 今ではうまくいくようです。

于 2013-03-27T22:00:39.370 に答える