【原创】一段简短的读取libglade的UI文件的Python代码

时间:2022-09-03 10:19:16

准备写一个将Glade/GtkBuilder等格式的UI文件转换成C++代码的python程序

首先完成的是将LIBGlade格式读取至内存中

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os, sys, copy
from xml.etree.ElementTree import ElementTree

'''
result format:
[
  {
      "class" : "GtkWindow"
      "id"    : "window1"
      "property" : [
                      { "name" : "can_focus"
                        "value": "False"
                      }
                      {
                      }
                    ]
      "child" : [
                  {
                   "object":{
                        "class" : "GtkWindow"
                        "id"    : "window1"
                        "property": [
                                      { "name" : "can_focus"
                                        "value": "False"
                                      }
                                      {
                                      }
                                    ]
                        "child" : [
                                   ...
                                  ]
                      }
                   "packing" :
                      {
                        "property": [
                                      { "name" : "expand"
                                        "value": "True"
                                      }
                                      {
                                      }
                                    ]
                      }
                  }
                  {
                  }
                ]
  }
  {
  }
]

child_node_name = "child"
object_node_name = "widget"
packing_node_name = "packing"

'''

def load_packing(parent_node):
    packing = {}
    propertys = []
    tmp_property = {}

    # property list
    for property in parent_node.iterfind("property"):
        # name
        tmp_property["name"] = property.get("name")
        # value
        tmp_property["value"] = property.text
        # append to list
        propertys.append(copy.copy(tmp_property))
    # assign value
    packing["property"] = propertys

    return packing

def load_object(parent_node):
    result = {}
    # find widget
    widget = parent_node.find("widget")
    if widget != None:
        result["object"] = load_full_object(widget)
    # find packing
    packing = parent_node.find("packing")
    if packing != None:
        result["packing"] = load_packing(packing)

    return result

def load_full_object(self_node):
    result = {}
    propertys = []
    childs = []
    tmp_property = {}
    tmp_child = {}
    # class
    result["class"] = self_node.get("class")
    # id
    result["id"] = self_node.get("id")

    # property list
    for property in self_node.iterfind("property"):
        # name
        tmp_property["name"] = property.get("name")
        # value
        tmp_property["value"] = property.text
        # other attribute
        if property.attrib.has_key("translatable"):
            tmp_property["translatable"] = property.get("translatable")
        if property.attrib.has_key("context"):
            tmp_property["context"] = property.get("context")
        if property.attrib.has_key("agent"):
            tmp_property["agent"] = property.get("agent")
        if property.attrib.has_key("comments"):
            tmp_property["comments"] = property.get("comments")
        # append to list
        propertys.append(copy.copy(tmp_property))
    # assign value
    result["property"] = propertys
    # childs
    for child in self_node.iterfind("child"):
        # recurse to load object
        tmp_child = load_object(child)
        # append it to list
        childs.append(copy.copy(tmp_child))
    # assign value
    result["child"] = childs
    
    return result

def load_xml(xml_file):
    result_lst = []
    # get root
    xml_root = ElementTree(file=xml_file).getroot()
    if(xml_root == None):
        return -1, result_lst
    # check is libglade type?
    if (xml_root.tag != "glade-interface"):
        return -1, result_lst
    for object in xml_root.iterfind("widget"):
        #print object
        result_lst.append(load_full_object(object))

    return 0, result_lst
   
if __name__=="__main__":
    argNum=len(sys.argv)

    # check param num
    if argNum <> 2 :
        print "parameter number(%d) is not match" % argNum
        sys.exit(0)

    xml_file = sys.argv[1]

    ret, result = load_xml(xml_file)
    print result