📄 pywxrc.py
字号:
#----------------------------------------------------------------------
# Name: wx.tools.pywxrc
# Purpose: XML resource compiler
#
# Author: Robin Dunn
# Based on wxrc.cpp by Vaclav Slavik, Eduardo Marques
# Ported to Python in order to not require yet another
# binary in wxPython distributions
#
# Massive rework by Eli Golovinsky
#
# RCS-ID: $Id: pywxrc.py,v 1.8 2006/06/27 22:36:24 RD Exp $
# Copyright: (c) 2004 by Total Control Software, 2000 Vaclav Slavik
# Licence: wxWindows license
#----------------------------------------------------------------------
"""
pywxrc -- Python XML resource compiler
(see http://wiki.wxpython.org/index.cgi/pywxrc for more info)
Usage: python pywxrc.py -h
python pywxrc.py [-p] [-g] [-e] [-o filename] xrc input files...
-h, --help show help message
-p, --python generate python module
-g, --gettext output list of translatable strings (may be combined with -p)
-e, --embed embed XRC resources in the output file
-o, --output output filename, or - for stdout
"""
import sys, os, getopt, glob, re
import xml.dom.minidom as minidom
import wx
import wx.xrc
#----------------------------------------------------------------------
class PythonTemplates:
FILE_HEADER = """\
# This file was automatically generated by pywxrc, do not edit by hand.
# -*- coding: UTF-8 -*-
import wx
import wx.xrc as xrc
__res = None
def get_resources():
\"\"\" This function provides access to the XML resources in this module.\"\"\"
global __res
if __res == None:
__init_resources()
return __res
"""
CLASS_HEADER = """\
class xrc%(windowName)s(wx.%(windowClass)s):
def PreCreate(self, pre):
\"\"\" This function is called during the class's initialization.
Override it for custom setup before the window is created usually to
set additional window styles using SetWindowStyle() and SetExtraStyle().\"\"\"
pass
def __init__(self, parent):
# Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoStageCreation)
pre = wx.Pre%(windowClass)s()
self.PreCreate(pre)
get_resources().LoadOn%(windowClass)s(pre, parent, "%(windowName)s")
self.PostCreate(pre)
# Define variables for the controls
"""
CREATE_WIDGET_VAR = """\
self.%(widgetName)s = xrc.XRCCTRL(self, \"%(widgetName)s\")
"""
MENU_CLASS_HEADER = """\
class xrc%(windowName)s(wx.%(windowClass)s):
def __init__(self):
pre = get_resources().LoadMenu("%(windowName)s")
# This is a copy of Robin's PostCreate voodoo magic in wx.Window that
# relinks the self object with the menu object.
self.this = pre.this
self.thisown = pre.thisown
pre.thisown = 0
if hasattr(self, '_setOORInfo'):
self._setOORInfo(self)
if hasattr(self, '_setCallbackInfo'):
self._setCallbackInfo(self, self.__class__)
# Define variables for the menu items
"""
CREATE_MENUITEM_VAR = """\
self.%(widgetName)s = self.FindItemById(xrc.XRCID(\"%(widgetName)s\"))
"""
INIT_RESOURE_HEADER = """\
# ------------------------ Resource data ----------------------
def __init_resources():
global __res
__res = xrc.EmptyXmlResource()
"""
LOAD_RES_FILE = """\
__res.Load('%(resourceFilename)s')"""
FILE_AS_STRING = """\
%(filename)s = '''\\
%(fileData)s'''
"""
PREPARE_MEMFS = """\
wx.FileSystem.AddHandler(wx.MemoryFSHandler())
"""
ADD_FILE_TO_MEMFS = """\
wx.MemoryFSHandler.AddFile('XRC/%(memoryPath)s/%(filename)s', %(filename)s)
"""
LOAD_RES_MEMFS = """\
__res.Load('memory:XRC/%(memoryPath)s/%(resourceFilename)s')
"""
GETTEXT_DUMMY_FUNC = """
# ----------------------- Gettext strings ---------------------
def __gettext_strings():
# This is a dummy function that lists all the strings that are used in
# the XRC file in the _("a string") format to be recognized by GNU
# gettext utilities (specificaly the xgettext utility) and the
# mki18n.py script. For more information see:
# http://wiki.wxpython.org/index.cgi/Internationalization
def _(str): pass
%s
"""
#----------------------------------------------------------------------
class XmlResourceCompiler:
templates = PythonTemplates()
"""This class generates Python code from XML resource files (XRC)."""
def MakePythonModule(self, inputFiles, outputFilename,
embedResources=False, generateGetText=False):
outputFile = self._OpenOutputFile(outputFilename)
classes = []
resources = []
gettextStrings = []
# process all the inputFiles, collecting the output data
for inFile in inputFiles:
resourceDocument = minidom.parse(inFile)
classes.append(self.GenerateClasses(resourceDocument))
if embedResources:
res = self.GenerateInitResourcesEmbedded(inFile, resourceDocument)
else:
res = self.GenerateInitResourcesFile(inFile, resourceDocument)
resources.append(res)
if generateGetText:
gettextStrings += self.FindStringsInNode(resourceDocument.firstChild)
# now write it all out
print >>outputFile, self.templates.FILE_HEADER
# Note: Technically it is not legal to have anything other
# than ascii for class and variable names, but since the user
# can create the XML with non-ascii names we'll go ahead and
# allow for it here, and then let Python complain about it
# later when they try to run the program.
classes = u"\n".join(classes)
print >>outputFile, classes.encode("UTF-8")
print >>outputFile, self.templates.INIT_RESOURE_HEADER
if embedResources:
print >>outputFile, self.templates.PREPARE_MEMFS
resources = u"\n".join(resources)
print >>outputFile, resources.encode("UTF-8")
if generateGetText:
# These have already been converted to utf-8...
gettextStrings = [' _("%s")' % s for s in gettextStrings]
gettextStrings = "\n".join(gettextStrings)
print >>outputFile, self.templates.GETTEXT_DUMMY_FUNC % gettextStrings
#-------------------------------------------------------------------
def MakeGetTextOutput(self, inputFiles, outputFilename):
"""
Just output the gettext strings by themselves, with no other
code generation.
"""
outputFile = self._OpenOutputFile(outputFilename)
for inFile in inputFiles:
resourceDocument = minidom.parse(inFile)
resource = resourceDocument.firstChild
strings = self.FindStringsInNode(resource)
strings = ['_("%s");' % s for s in strings]
print >>outputFile, "\n".join(strings)
#-------------------------------------------------------------------
def GenerateClasses(self, resourceDocument):
outputList = []
resource = resourceDocument.firstChild
topWindows = [e for e in resource.childNodes
if e.nodeType == e.ELEMENT_NODE and e.tagName == "object"]
# Generate a class for each top-window object (Frame, Panel, Dialog, etc.)
for topWindow in topWindows:
windowClass = topWindow.getAttribute("class")
windowClass = re.sub("^wx", "", windowClass)
windowName = topWindow.getAttribute("name")
if windowClass == "Menu":
outputList.append(self.templates.MENU_CLASS_HEADER % locals())
else:
outputList.append(self.templates.CLASS_HEADER % locals())
# Generate a variable for each control, and standard event handlers
# for standard controls.
for widget in topWindow.getElementsByTagName("object"):
widgetClass = widget.getAttribute("class")
widgetClass = re.sub("^wx", "", widgetClass)
widgetName = widget.getAttribute("name")
if (widgetName != "" and widgetClass != ""):
if widgetClass == "MenuItem":
outputList.append(self.templates.CREATE_MENUITEM_VAR % locals())
elif widgetClass not in \
['tool', 'unknown', 'notebookpage', 'separator', 'sizeritem']:
outputList.append(self.templates.CREATE_WIDGET_VAR % locals())
outputList.append('\n\n')
return "".join(outputList)
#-------------------------------------------------------------------
def GenerateInitResourcesEmbedded(self, resourceFilename, resourceDocument):
outputList = []
files = []
resourcePath = os.path.split(resourceFilename)[0]
memoryPath = self.GetMemoryFilename(os.path.splitext(os.path.split(resourceFilename)[1])[0])
resourceFilename = self.GetMemoryFilename(os.path.split(resourceFilename)[1])
self.ReplaceFilenamesInXRC(resourceDocument.firstChild, files, resourcePath)
filename = resourceFilename
fileData = resourceDocument.toxml() # what about this? encoding=resourceDocument.encoding)
outputList.append(self.templates.FILE_AS_STRING % locals())
for f in files:
filename = self.GetMemoryFilename(f)
fileData = self.FileToString(os.path.join(resourcePath, f))
outputList.append(self.templates.FILE_AS_STRING % locals())
for f in [resourceFilename] + files:
filename = self.GetMemoryFilename(f)
outputList.append(self.templates.ADD_FILE_TO_MEMFS % locals())
outputList.append(self.templates.LOAD_RES_MEMFS % locals())
return "".join(outputList)
#-------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -