如何在不锁定GUI的情况下顺序运行循环?

时间:2015-03-07 00:46:02

标签: python multithreading gtk pygtk

我正在我的Raspberry Pi 2上用Python编写一个photobooth程序,如果我只想拍一张照片或使用一次自动对焦,它就可以了。我正在尝试编写一个等待4秒然后运行自动对焦的功能“调度程序”,然后等待4秒钟拍摄照片1,等待另外4秒钟拍摄照片2并等待4秒钟拍摄照片3同时更新状态栏PyGTK的。但是当调用“调度程序”函数时,它会同时执行并启动所有while循环。

我尝试将while循环放在单独的函数中,并将它们作为线程运行,并在每个线程调用下使用threadx.start()threadx.join()命令。我怀疑gobject.timeout_add()函数阻止阻塞的方式,我需要保持GUI更新和实时预览运行,但我也无法弄清楚如何在需要时阻塞。我还启动了调度程序作为一个线程,并在每个while循环中使用time.sleep(1)并且它的行为表现我想要它,除了GUI在第一个图像被处理后消失,我找不到任何错误消息来解释它

我已经为此工作了好几个星期,很乐意付钱帮助我通过电子邮件完成这项工作。我住在农村地区,很难找到当地人帮忙。我可以PayPal ...请在热门的谷歌电子邮件服务derosia与我联系。如果你有一台由gphoto2支持的相机和一个usb系绳,这将是一个奖励。

class Photobooth(gtk.Window):

    def set_statusBar(self, status):
        self.statusBar.label.set_text(str(status))    

    def focus_counter2(self, counter):
        if counter > 3:
            self.set_statusBar("Get into position!")
        elif counter > 0:
            self.set_statusBar("Focusing: " + str(counter-1))
        else:
            self.set_statusBar("Focusing: " + str(counter-1))
        self.focus_function() #runs the function for auto focus     

    def countdown_function(self, counter, image_name):
        if counter > 1:
            self.set_statusBar(str(counter-1))
        elif counter > 0: 
            self.set_statusBar("Keep Smiling!")
        else:
        self.photo_cb(image_name) #runs the function to take an image           


    def scheduler(self, widget, data = None): 
        global ftp_path
        global image_names
        global countdown_timer        
        image_names = []

        counter = countdown_timer
        while counter > 0:
            gobject.timeout_add(counter * 1000, self.focus_counter2, countdown_timer-counter)
            counter -= 1        

        counter = countdown_timer
        while counter >= 0:
            image_name = datetime.datetime.now().strftime("%Y_%m-%d_%H-%M-%S")        
            gobject.timeout_add(counter * 1000, self.countdown_function, countdown_timer-counter, image_name)
            counter -= 1        
        image_names.append(image_name + ".jpg")

        counter = countdown_timer
        while counter >= 0:
            image_name = datetime.datetime.now().strftime("%Y_%m-%d_%H-%M-%S")        
            gobject.timeout_add(counter * 1000, self.countdown_function, countdown_timer-counter, image_name)
            counter -= 1        
        image_names.append(image_name + ".jpg")

        counter = countdown_timer
        while counter >= 0:
            image_name = datetime.datetime.now().strftime("%Y_%m-%d_%H-%M-%S")        
            gobject.timeout_add(counter * 1000, self.countdown_function, countdown_timer-counter, image_name)
            counter -= 1        
        image_names.append(image_name + ".jpg")    


    def __init__(self):
        super(PictureBox, self).__init__()

        startB_image = gtk.image_new_from_stock(gtk.STOCK_YES, gtk.ICON_SIZE_SMALL_TOOLBAR)
        startB = gtk.Button()
        startB.set_image(startB_image)
        startB.set_tooltip_text("Start countdown")
        startB.connect('clicked', self.scheduler, None)

1 个答案:

答案 0 :(得分:0)

感谢andlabs我按照他的建议解决了这个问题:

调用一个函数,让每个函数在完成他们正在做的事情时调用下一个函数。然后为了确保它循环了适当的次数,我只是将计数器传递给每个循环结束时迭代的每个函数image_number。它似乎工作。

class Photobooth(gtk.Window):
    def set_statusBar(self, status):
        self.statusBar.label.set_text(str(status))    

    def focus_counter1(self, widget, data=None):
        global countdown_timer
        counter = countdown_timer
        while counter > 0:
            gobject.timeout_add(counter * 1000, self.focus_counter2,
                                countdown_timer-counter)
            counter -= 1

    def focus_counter2(self, counter):
        if counter > 3:
            self.set_statusBar("Get into position!")
        elif counter > 0:
            self.set_statusBar("Focusing: " + str(counter))
        else:
            self.set_statusBar("Focusing: " + str(counter))
            self.focus_function()
            gobject.timeout_add(1000, self.countdown_clicked, 1)

    def countdown_clicked(self, image_number): 
        global countdown_timer
        counter = countdown_timer
        while counter >= 0:
            gobject.timeout_add(counter * 1000, self.countdown_function,
                                countdown_timer-counter, image_number)
            counter -= 1  

    def countdown_function(self, counter, image_number):
        global images_per_sequence
        if counter > 1:
            self.set_statusBar(str(counter-1))
        elif counter > 0: 
            self.set_statusBar("Keep Smiling!")
        else:
            image_name = datetime.datetime.now()
            self.photo_cb(image_name.strftime("%Y_%m-%d_%H-%M-%S"))    
            if image_number < images_per_sequence:
                gobject.timeout_add(1000, self.countdown_clicked,
                                    image_number + 1)

    def __init__(self):
        super(PictureBox, self).__init__()

        startB_image = gtk.image_new_from_stock(gtk.STOCK_YES,
                                 gtk.ICON_SIZE_SMALL_TOOLBAR)
        startB = gtk.Button()
        startB.set_image(startB_image)
        startB.set_tooltip_text("Start countdown")
        startB.connect('clicked', self.focus_counter1, None)