2012-12-01 41 views
5

Python'da, bash ile işbirliği yapan komut dosyası oluşturuyorum. Tüm arama seçeneklerini belirlediğimde ve bulma düğmesine bastığımda, arama tamamlandığında kaybolacak olan progress bar ile pop-up penceresini açmak istiyorum. popup.show() tarafından popup window'u açıyorum ve pencereyi kapatana kadar hiçbir işlev yürütülmüyor. Peki bu problemi nasıl çözebilirim? kontrol sınıfındaİki pencere, açılır pencere ve ana pencerede çalışan pygtk

:

def search(self, widget): 
    cmd = "find " + self.model.directory + " -name \"" + self.model.name + "\"" + " -perm -" + str(self.model.mode) 
    if self.model.type is not None and self.model.type != '': 
     cmd += " -type " + self.model.type 
    if self.model.owner is not None: 
     cmd += " -user " + self.model.owner 
    if self.model.days is not None: 
     cmd += " -mtime -" + str(self.model.days) 

    self.progress = SearcherProgressBar() 

    output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 
    out = output.stdout.read().strip() 
    array = string.split(out, '\n') 
    self.list = list() 
    self.progress.label = "sdsds" 
    for value in array: 
     self.add_to_list(value) 

    #self.progress.popup.destroy() # when I uncomment, popup never appears 

    self.view.treestore.clear() 
    self.add_to_tree(self.list, None) 
    self.view.expand_item.set_sensitive(True) 

progressbar sınıfında:

class SearcherProgressBar: 

def __init__(self): 
    self.popup = gtk.Window(gtk.WINDOW_POPUP) 
    vbox = gtk.VBox() 
    self.popup.add(vbox) 
    self.popup.set_size_request(500,100) 
    self.label = gtk.Label("Searching...") 
    vbox.pack_start(self.label, True, True, 0) 
    self.popup.connect("destroy", self.dest) 
    self.popup.show_all() 


def dest(self, widget, data=None): 
    self.popup.destroy() 
    return False 
+3

kodunuzu olun [SSCCE - İçerdiği Kısa, Self, (Derlenebilir) Doğru, Örnek] (http://sscce.org/). Sorunuzdaki kodu çalıştıramayız. Onlar sadece uygulamanızın bir parçası. –

cevap

1

[çözüldü] Bu kod, her pencere öğesinin güncelleme Herhangi bir oranda

while gtk.events_pending(): 
     gtk.main_iteration() 
1

sonra ilave edilmelidir, Ne istediğini görmek için dışarıdan zor olsa da soru oldukça ilginç görünüyordu Programınızın nasıl çalıştığı ve çalışması amaçlanıyor. Bir pop-up yapabilmeniz için en az bir kod oluşturdum.

Bash-komutu için subprocessing ve gui için threading birleşimini kullanıyorum. hızla yürütmek Konuda değildir ve iadeler için kontrol gobject.threads_init()

  • işlevlerini kullanmalıdır threading yana

    • gtk ile birlikte kullanılır:

      Önemli bitleri bu kodda dikkat edilmesi gereken gtk.main -loop

    • Alt işlemlerin işlenmemesi için çağrılırken arama düğmesi devre dışı bırakılır.

    Ve burada kod:

    #!/usr/bin/env python 
    
    import gtk 
    import threading 
    import gobject 
    from subprocess import Popen, PIPE 
    
    class SearcherProgressBar(object): 
        """This is the popup with only progress-bar that pulses""" 
        def __init__(self): 
         self._popup = gtk.Window(gtk.WINDOW_POPUP) 
         self._progress = gtk.ProgressBar() 
         self._progress.set_text = gtk.Label("Searching...") 
         self._popup.add(self._progress) 
    
        def run(self, search, target): 
         """Run spawns a thread so that it can return the process to the 
         main app and so that we can do a little more than just execute 
         a subprocess""" 
         self._popup.show_all() 
         self._thread = threading.Thread(target=self._search, args=(search, target)) 
         self._thread.start() 
    
         #Adding a callback here makes gtk check every 0.42s if thread is done 
         gobject.timeout_add(420, self._callback) 
    
        def _search(self, cmd, target): 
         """This is the thread, it makes a subprocess that it communicates with 
         when it is done it calls the target with stdout and stderr as arguments""" 
         p = Popen(cmd, stdout=PIPE, stderr=PIPE) 
         target(*p.communicate()) 
    
        def _callback(self, *args): 
         """The callback checks if thread is still alive, if so, it pulses 
         return true makes callback continue, while false makes it stop""" 
         if self._thread.is_alive(): 
          self._progress.pulse() 
          return True 
         else: 
          self._popup.destroy() 
          return False 
    
    class App(object): 
    
        def __init__(self): 
    
         self._window = gtk.Window() 
         self._window.connect("destroy", self._destroy) 
    
         vbox = gtk.VBox() 
         self._window.add(vbox) 
    
         self.button = gtk.Button() 
         self.button.set_label('Pretend to search...') 
         self.button.connect('clicked', self._search) 
         vbox.pack_start(self.button, False, False, 0) 
    
         entry = gtk.Entry() 
         entry.set_text("This is here to show this gui doesn't freeze...") 
         entry.connect("changed", self._gui_dont_freeze) 
         vbox.pack_start(entry, False, False, 0) 
    
         self._results = gtk.Label() 
         vbox.pack_start(self._results, False, False, 0) 
    
         self._gui_never_freeze = gtk.Label("Write in entry while searching...") 
         vbox.pack_start(self._gui_never_freeze, False, False, 0) 
    
         self._window.show_all() 
    
        def run(self): 
    
         gtk.main() 
    
        def _gui_dont_freeze(self, widget): 
    
         self._gui_never_freeze.set_text(
          "You've typed: '{0}'".format(widget.get_text())) 
    
        def _search(self, widget): 
         """Makes sure you can't stack searches by making button 
         insensitive, gets a new popup and runs it. Note that the run 
         function returns quickly and thus this _search function too.""" 
         self.button.set_sensitive(False) 
         self._results.set_text("") 
         popup = SearcherProgressBar() 
         popup.run(['sleep', '10'], self._catch_results) 
    
        def _catch_results(self, stdout, stderr): 
         """This is where we do something with the output from the subprocess 
         and allow button to be pressed again.""" 
         self.button.set_sensitive(True) 
         self._results.set_text("out: {0}\terr: {1}".format(stdout, stderr)) 
    
        def _destroy(self, *args): 
    
         self._window.destroy()   
         gtk.main_quit() 
    
    if __name__ == "__main__": 
    
         #This is vital for threading in gtk to work correctly 
         gobject.threads_init() 
         a = App() 
         a.run() 
    
  • +0

    Cevabınız için çok teşekkür ederim. Programımı, postanızın üstündeki kısa kodla bitirdim, ama kesinlikle kodunuzu analiz edeceğim ve python'daki thread'ları öğreneceğim. – dragon7