Hello;
I have the following issue with a gtk.Assistant designed in galde and
used via gtk. builder :
The fist time I launch the assistant and use it correctly.
When I launch the assistant the secod time I have a segmentation fault,
and my application, btw, stops.

I use a destroy method to close the assistant window. It is normal ?

I read out on FAQ that is sometime better to use the hide method instead
of destroy.

But with the hide metho I have a new problem.
First time I launch the assistant all is OK , when finished the apply
button emit a signal as expected.
On the second launch the assistant window start;  but the signal 'apply'
is emitted twice . At yhis time I don't understand why ?

I attached my file who use the assistant.

Thanks in advance for help

Nico








#!/usr/bin/env python
# -*- coding: utf-8 -*-
# -*- Mode: Python -*-
# vi:si:ai:et:sw=4:sts=4:ts=4
#
# Copyright Nicolas Bertrand ([email protected]), 2009
#
# This file is part of Luciole.
#
#    Luciole is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Luciole is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Luciole.  If not, see <http://www.gnu.org/licenses/>.
#
#


import os.path
import gtk
import gtk.glade

#import luciole_global as MG
#import luciole_file_in_out as MF
from .. import luciole_constants as LCONST

from .. import lucioWebCamDetect as M_WEBCAM

import gobject
import threading
import time

from gettext import gettext as _


class Webcam_detection_thread_worker(threading.Thread):
        
    def __init__(self,on_finish) : 
        super(Webcam_detection_thread_worker, self).__init__()
        self._on_finish = on_finish

    def run (self) :
        WebCamObj = M_WEBCAM.luciole_webcam_detection()
        nb_webcam = WebCamObj.detect_webcam()
        gobject.idle_add(self._on_finish,nb_webcam, WebCamObj )


class Webcam_detection_thread(threading.Thread):
    """ Manages webcam detection """
    
    def __init__(self,progress_bar_widget,on_finish) : 
        super(Webcam_detection_thread, self).__init__()
        self._is_worker_finished = False
        self._webcam_obj = None 
        self._progress_bar_widget = progress_bar_widget
        self._on_finish = on_finish
   
    def _worker_finished(self, nb_webcam, webcam_obj) :
        self._is_worker_finished = True
        if nb_webcam > 0 : 
            self._webcam_obj = webcam_obj

    def run (self) :
        self._progress_bar_clear()
        t_worker = Webcam_detection_thread_worker(self._worker_finished)
        t_worker.start()
        while (self._is_worker_finished == False ) :
            time.sleep(0.1)
            self._progress_bar_on_progress()
        self._progress_bar_complete()
        gobject.idle_add(self._on_finish,self._webcam_obj)
            
    def _progress_bar_clear(self):
        self._progress_bar_widget.set_fraction(0.0)
        self._progress_bar_widget.set_text(_('Please wait for webcam detection'))

    def _progress_bar_complete(self):
        self._progress_bar_widget.set_fraction(1.0)
        self._progress_bar_widget.set_text(_('Webcam detection done'))
    
    def _progress_bar_on_progress(self):
        self._progress_bar_widget.pulse()


class ProjectAssistant(object) :
    """ Class for managing the cration of a new project"""  

    def __init__(self,builder,assistant, apply_callback) :
        """ class init """
        self.builder = builder
        self.apply_callback = apply_callback
        self.assistant = assistant
        self.assistant.show() 

        # connect assisnat signals
        self.assistant.connect('apply',self.assistant_apply)
        self.assistant.connect('cancel',self.assistant_cancel)
        self.assistant.connect('close',self.assistant_close)
        self.assistant.connect('prepare',self.assistant_prepare)
        self.assistant.connect('delete-event',self.on_delete_event)

        # connect project path entries
        self.builder.get_object('entry_project_name1').connect('changed',self.project_name_changed)
        #self.builder.get_object('entry_project_dir1').connect('changed',self.project_dir_changed)
        
        self._filechooser = self.builder.get_object('filechooserbutton1')
        initial_folder = os.path.expandvars('$HOME')  
        status =  self._filechooser.set_current_folder(initial_folder)
        #connect signal fot radiobutton
        self.builder.get_object('radiobutton1').connect('group-changed',self.radiobutton_changed)
        self.builder.get_object('radiobutton1').connect('toggled',self.radiobutton_toggled,LCONST.DVCAM)
        self.builder.get_object('radiobutton2').connect('toggled',self.radiobutton_toggled,LCONST.WEBCAM)
        self.builder.get_object('radiobutton3').connect('toggled',self.radiobutton_toggled,LCONST.DIGICAM)

        #connect fpi scrollbar change
        self.builder.get_object('hscale_fpi1').connect('value-changed',self.scale_fps_value_changed)
        self.builder.get_object('hscale_fpi1').connect('format-value',self.scale_fps_format_value)
        
        #debug purpose
        #print "Nombre de pages %s"%self.assistant.get_n_pages()

        self.Page0=self.builder.get_object("Page0")
         
        # forward button active by default in Page 2
        Page2=self.builder.get_object("Page2")
        self.assistant.set_page_complete(Page2,True)
         
        # aply button active by default in Page 4
        Page_summary=self.builder.get_object("Page_summary")
        self.assistant.set_page_complete(Page_summary,True)
        
        # get webcam_page
        self.page_webcam_detection = self.builder.get_object("Page_webcam")
        

        self.assistant.set_forward_page_func(self.page_func)
         
        #management of changed text
        self.name_changed = False
        self.project_dir_changed = False
            
        #dictionary with project datas
        self.project_datas={}
        self.project_datas['hardtype']=LCONST.DVCAM
        # select radiobutton1 
        self.builder.get_object('radiobutton1').set_active(True)
        
        # get the dedault FPI value    
        FPIWidget =  self.builder.get_object('hscale_fpi1')
        value= FPIWidget.get_value()
        if value > 5 : value =5
        if value < 1 : value =1 
        (fpsDisplay,NbFrame) = LCONST.VIDEO_FPS_TABLE[int(value)]  
        self.project_datas['fpi']= NbFrame
        self.fpsDisplay= fpsDisplay
        
        #self._GuiObj = MG.luciole_global.dico['appgui']
     
        #for debug only 
        ProjectNameEntry = self.builder.get_object('entry_project_name1')
        ProjectNameEntry.set_text('new_luciole_project')


     
    def is_page1_complete(self) :
        is_complete = False
        if (self.name_changed) : is_complete = True
        return is_complete
  
    def project_name_changed(self,widget):
        self.name_changed = True
        if (self.is_page1_complete()) :
            self.assistant.set_page_complete(self.Page0,True)
  
    #def project_dir_changed(self,widget):
    #    self.project_dir_changed = True
    #    if (self.is_page1_complete()) :
    #        self.assistant.set_page_complete(self.Page0,True)
      
    
    def button_dir_clicked(self,widget) :
        print "dir button clicked" 
   
        #dir_dialog = gtk.FileChooserDialog("Select a directory ",
        #                       self.assistant,
        #                       gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
        #                       (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
        #                        gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        #dir_dialog.set_default_response(gtk.RESPONSE_OK)
        
        dir_dialog  = self.builder.get_object('filechooserbutton1')

        dir_dialog.set_current_folder(os.path.expandvars('$HOME'))
    
        response = dir_dialog.run()
        if response == gtk.RESPONSE_OK:
            DirNameEntry = self.builder.get_object('entry_project_dir1')
            DirNameEntry.set_text(dir_dialog.get_filename())
      
        elif response == gtk.RESPONSE_CANCEL:
            print 'Closed, no files selected'
        dir_dialog.destroy()
   
    def assistant_apply(self,widget) :
        print "ASSISTANT APLLY"
        # n...@grape : to define correctly action with controller
        # projectObj = MG.luciole_global.dico[MF.luciole_project_file.__name__]
        # project_folder=os.path.join(self.project_datas['projectDir'],self.project_datas['projectName'])
        # projectObj.new_project(project_folder,self.project_datas)
        self.apply_callback(self.project_datas)
        self.assistant.destroy()
         
    def assistant_cancel(self,widget) :
        self.assistant.destroy()

    def assistant_close(self,widget) :
        self.assistant.destroy()
          
    def assistant_prepare(self,assistant,page) :
        """ action performed at the beginning of a new page : prepare page"""
        # prepare webcam detection
        if assistant.get_current_page() == 2 : self.assistant_prepare_webcam_detection(page)
        # prepare summary page  
        if assistant.get_current_page() == 3 : self.assistant_prepare_summary_page(page)

    def on_webcam_radio_button_clicked(self,widget,webcam_index,webcam_obj):
        """ save info on selected webcam """
        # when a webcam is selected select webcam data
        self.project_datas['webcam_data'] = webcam_obj.get_gst_best_input(webcam_index) 
    
    def _on_webcam_detect_complete(self,webcam_obj) :
        """ callback , executed when webcam detection is complete """
        self.assistant.set_page_complete(self.page_webcam_detection,True)
        label = self.builder.get_object("label11")
        if webcam_obj != None and webcam_obj.webcam_devices != None:
            vbox = self.builder.get_object("vbox_webcam_list1")
            # firt clean childs on the vbox widget
            for my_child in vbox.get_children() : vbox.remove(my_child)
            # loop on detected webcams 
            RadioButton = None

            for (webcam_index, webcam ) in enumerate(webcam_obj.webcam_devices) :
                RadioButton = gtk.RadioButton(group=RadioButton, label= webcam["name"] )
                vbox.pack_start(RadioButton)
                RadioButton.show()
                
                #connect event 
                RadioButton.connect("clicked",self.on_webcam_radio_button_clicked,webcam_index,webcam_obj )
                
                # First set 
                if webcam_index == 0 :
                    # select by default. 
                    self.project_datas['webcam_data'] = webcam_obj.get_gst_best_input(webcam_index) 
            label.set_text(_('Detected webcam'))
        else :
            label.set_text(_('No webcam detected'))
        label.show()
    
    def assistant_prepare_webcam_detection(self,page) :
        """ prepare page for the webcam detection page """
        self.assistant.set_page_complete(page,False)
        progress_bar = self.builder.get_object("progressbar_webcam1")
        # destroy label status for webcam status 
        label = self.builder.get_object("label11")
        label.destroy()
        # launch webcam detection thread
        t_webcam = Webcam_detection_thread(progress_bar,self._on_webcam_detect_complete)
        t_webcam.start()
        
    def assistant_prepare_summary_page(self,page) :
        """ prepare sumary page """
        textview_widget =self.builder.get_object("textview1_summary")
        textbuffer = textview_widget.get_buffer()
        string=""
        text_list=list()
        
        # display project name
        string = "%s : %s"%( _('Project Name'), self.project_datas['project_name'])
        text_list.append(string)

        # display project path
        string = "%s : %s \n"%( _('Project Path'), self.project_datas['project_dir'])
        text_list.append(string)

        # display project FPI 
        string = "%s : %s "%( _('Number of frames per seconds'), self.fpsDisplay)
        text_list.append(string)
        
        # display Hardware type  
        string = "%s : %s "%( _('Hardware type'), LCONST.HardTypeName[self.project_datas['hardtype']] )
        text_list.append(string)
        
        # display info specific for webcam
        if ( self.project_datas['hardtype'] == LCONST.WEBCAM ) :
            # webcam name
            string = "\n%s : %s"%(_('Webcam name'),self.project_datas['webcam_data']['name'])
            text_list.append(string)
            
            #webcam device 
            string = "%s : %s"%(_('Webcam device'),self.project_datas['webcam_data']['device'])
            text_list.append(string)

            #webcam resolution 
            string = "%s : %sx%s"%(  _('Webcam resolution used'), 
                                        self.project_datas['webcam_data']['width'],
                                        self.project_datas['webcam_data']['height'])
            text_list.append(string)

            #webcam device 
            string = "%s : %s"%(_('Webcam driver used'),self.project_datas['webcam_data']['source_input'])
            text_list.append(string)
        
            
            # Final message  
            string = "\n %s "%(_('Have fun wityh luciole !'))
            text_list.append(string)

        string = "\n".join(text_list)         

        textbuffer.set_text(string)

    def verify_project_path_data(self):
        """ Verify if datas in page 1 are OK and save valid datas """
        if ( self.assistant.get_page_complete(self.Page0)) :
            state = True
            # Verify that a project name is entered
            ProjectNameEntry = self.builder.get_object('entry_project_name1')
            if (not ProjectNameEntry.get_text()) :
                state = False
                print ProjectNameEntry.get_text() , " n est pas un nom de projet valide"
            else :
                #save project Name
                self.project_datas['project_name']= ProjectNameEntry.get_text()
                # verify if a directory is selected
            
            # get directory path
            self.project_datas['project_dir'] = self._filechooser.get_filename()

            # verify if project exists
            if  (state==True) : 
                if (os.path.exists(os.path.join(self.project_datas['project_dir'],  self.project_datas['project_name']))) :
                    # directory exists
                    state = False
                    msg = "Le répertoire %s existe déja !"%(os.path.join(self.project_datas['project_dir'],  self.project_datas['project_name']))
                    #self._GuiObj.ErrMessage(msg) 
        else :
            # page not complete
            state =False 
        return state
    
      
    def verify_page_ok(self,num_page) :
        state = False 
        if (num_page == 0) :
            # check data given as parameter
            state = self.verify_project_path_data()
        else :
            state = True
        return state
   
    def page_func(self,page_num) :
        """ call back to verify the validity of the pages """
        page_out = page_num
        if (self.verify_page_ok(page_num)) : 
            if (page_out == 1 ) and  (self.project_datas['hardtype'] != LCONST.WEBCAM) :
                # if web cam selected go to page 2
                # else go to page 3
                page_out = 3
            else :
                page_out = page_out +1

        else :
            pageWidget = self.assistant.get_nth_page(page_num)
            self.assistant.set_page_complete(pageWidget,False)
        return page_out

    def radiobutton_changed(self,widget) :
        """ call back for radio button change"""
        pass
  
    def radiobutton_toggled(self,widget, data) :
        if (widget.get_active() ) :
            self.project_datas['hardtype']=data
 
    #def spinbutton_ips_value_changed(self,widget) :
    #  self.project_datas['FPI']=widget.get_value_as_int()
  
    def scale_fps_value_changed(self,widget) :
        """ Fps Scale value changed"""
        value= widget.get_value()
        if value > 5 : value =5
        if value < 1 : value =1 
        # get the choosen number of frame per image value 
        (fpsDisplay,NbFrame) = LCONST.VIDEO_FPS_TABLE[int(value)]  
        self.project_datas['fpi']= NbFrame
        self.fpsDisplay= fpsDisplay
    
    def scale_fps_format_value(self,widget,value) :
        """ Fps Scale value changed"""
        if value > 5 : value =5
        if value < 1 : value =1  
        (fpsDisplay, NbFrame) = LCONST.VIDEO_FPS_TABLE[int(value)]  
        return fpsDisplay
   
    def on_delete_event(self, widget, event):
        self.assistant.destroy()
        return True

    def get_project_datas(self) :
        """ Return the project datas retrieved by assistant"""
        return self.project_datas

    
 
_______________________________________________
pygtk mailing list   [email protected]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to