2011-10-25 12 views
11

Windows XP'de all-in-one installer'dan Python 2.6 ve PyGTK 2.22.6 kullanıyorum, uygulamam için tek bir dosya yürütülebilir (py2exe aracılığıyla) oluşturmaya çalışıyorum.py2exe ile Bundling GTK kaynakları

Sorunum, uygulamamı bir komut dosyası olarak çalıştırdığımda (yani .py dosyalarının gevşek bir koleksiyonu gibi, bir .exe dosyasının içine yerleştirilmemiş), yerel görünümlü Windows temasını kullanır, ancak çalıştırdığımda yerleşik exe Ben varsayılan GTK temasını görüyorum.

Bu sorunun py2exe tarafından oluşturulan dist dizinine bir grup dosya kopyalayarak giderilebileceğini biliyorum, ancak okuduğum her şey verileri el ile kopyalamayı içerirken, bunun yapının otomatik bir parçası olmasını istiyorum. süreci. Ayrıca, konuyla ilgili her şey (the FAQ dahil) güncel değil - PyGTK artık dosyalarını C:\Python2x\Lib\site-packages\gtk-2.0\runtime\...'da saklıyor ve sadece lib ve etc dizinlerini kopyalama sorunu çözmüyor.

Sorularım şunlardır:

  1. İsterdim programlı setup.py ziyade sert kodlama yolları GTK çalışma zamanı verileri bulmak mümkün. Bunu nasıl yaparım?

  2. Eklemem gereken minimum kaynaklar nelerdir?

Güncelleme: Neredeyse deneme-yanılma yoluyla 2. cevap olabilir. (. Yani MS Windows): dist dizinde doğrudan oturan aynı dizin yapısı ile runtime öneki olmadan ...

runtime\lib\gtk-2.0\2.10.0\engines\libwimp.dll 
runtime\etc\gtk-2.0\gtkrc 
runtime\share\icons\* 
runtime\share\themes\MS-Windows 

ama aksi takdirde "pısırık" için tema ben dosya gerekir, çalışmak py2exe tarafından üretilmiştir. Ancak 2.10.0 nereden geliyor, gtk.gtk_version(2,22,0) mu? Burada kendi sorumu yanıtlayın, ama eğer birileri daha iyi biliyorsa, cevap vermekten çekinmeyin.

cevap

9

Bazıları oldukça kırılgan görünüyor (örneğin, yollardaki sürüm numaraları), daha iyi bir yol biliyorsanız yorum yapın veya düzenleyin. dosyaları

bulma

1. Öncelikle, ben aslında GTK çalışma zamanı kök bulmak için bu kodu kullanın. Bu da, çalışma zamanını yüklemek nasıl çok özel olduğunu ve muhtemelen ortak yerler için çek bir dizi geliştirilebilir:

#gtk file inclusion 
import gtk 
# The runtime dir is in the same directory as the module: 
GTK_RUNTIME_DIR = os.path.join(
    os.path.split(os.path.dirname(gtk.__file__))[0], "runtime") 

assert os.path.exists(GTK_RUNTIME_DIR), "Cannot find GTK runtime data" 

2. Hangi dosyaları Bu bağlıdır

içerecek şekilde, (a) Bir endişe büyüklüğünün ne kadar olduğu ve (b) uygulamanızın dağıtımının içeriği. Bununla demek istediğim, herkesin keyfi bir yerel ayara sahip olabileceği tüm geniş dünyaya mı yayılıyorsunuz yoksa sadece hisse senedi dizelerine ihtiyacınız olmayan iç kurumsal kullanım mı?Windows tema kullanımını istiyorsanız

, eklemek gerekir: Ayrıca yerelleştirme ben ihmal verileri (ama

GTK_ICONS = os.path.join("share", "icons") 

yok:

GTK_THEME_DEFAULT = os.path.join("share", "themes", "Default") 
GTK_THEME_WINDOWS = os.path.join("share", "themes", "MS-Windows") 
GTK_GTKRC_DIR = os.path.join("etc", "gtk-2.0") 
GTK_GTKRC = "gtkrc" 
GTK_WIMP_DIR = os.path.join("lib", "gtk-2.0", "2.10.0", "engines") 
GTK_WIMP_DLL = "libwimp.dll" 

Tango simgeleri istiyorsanız) istemeyebilirsiniz:

GTK_LOCALE_DATA = os.path.join("share", "locale") 

3. araya birleşiyor

Öncelikle, burada dosya sistemi ağacını belirli bir noktada gezen ve data_files seçeneğine uygun çıktı üreten bir işlev.

def generate_data_files(prefix, tree, file_filter=None): 
    """ 
    Walk the filesystem starting at "prefix" + "tree", producing a list of files 
    suitable for the data_files option to setup(). The prefix will be omitted 
    from the path given to setup(). For example, if you have 

     C:\Python26\Lib\site-packages\gtk-2.0\runtime\etc\... 

    ...and you want your "dist\" dir to contain "etc\..." as a subdirectory, 
    invoke the function as 

     generate_data_files(
      r"C:\Python26\Lib\site-packages\gtk-2.0\runtime", 
      r"etc") 

    If, instead, you want it to contain "runtime\etc\..." use: 

     generate_data_files(
      r"C:\Python26\Lib\site-packages\gtk-2.0", 
      r"runtime\etc") 

    Empty directories are omitted. 

    file_filter(root, fl) is an optional function called with a containing 
    directory and filename of each file. If it returns False, the file is 
    omitted from the results. 
    """ 
    data_files = [] 
    for root, dirs, files in os.walk(os.path.join(prefix, tree)):   
     to_dir = os.path.relpath(root, prefix) 

     if file_filter is not None: 
      file_iter = (fl for fl in files if file_filter(root, fl)) 
     else: 
      file_iter = files 

     data_files.append((to_dir, [os.path.join(root, fl) for fl in file_iter])) 

    non_empties = [(to, fro) for (to, fro) in data_files if fro] 

    return non_empties 

Yani şimdi şöyle setup() çağırabilirsiniz:

setup(
    # Other setup args here... 

    data_files = (
        # Use the function above... 
        generate_data_files(GTK_RUNTIME_DIR, GTK_THEME_DEFAULT) + 
        generate_data_files(GTK_RUNTIME_DIR, GTK_THEME_WINDOWS) + 
        generate_data_files(GTK_RUNTIME_DIR, GTK_ICONS) + 

        # ...or include single files manually 
        [ 
         (GTK_GTKRC_DIR, [ 
          os.path.join(GTK_RUNTIME_DIR, 
           GTK_GTKRC_DIR, 
           GTK_GTKRC) 
         ]), 

         (GTK_WIMP_DIR, [ 
          os.path.join(
           GTK_RUNTIME_DIR, 
           GTK_WIMP_DIR, 
           GTK_WIMP_DLL) 
         ]) 
        ] 
       ) 
)