书接上回,继续研究WebKit 实现了梦幻中的三位一体式的XmlRichEdit
示范效果:
在View面板上的修改能体现在Edit上
同样修改了Edit 也能体现在View面板上
同时数据使用xml描述,xslt转换到html,使用webkit渲染html并响应其中的html事件
以后只要修改xml和xslt就能产生不同的效果
xml 表达 数据Model:
template.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="richedit.xsl"?>
<document id='doc'>
<title id='title'>Template</title>
<text id='text'>1234567891234</text>
</document>
xsl 将xml转换到html:
richedit.xsl
<xsl:stylesheet version="1.0"
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method="html" />
<xsl:template match="document">
<html>
<head>
<meta http-equiv="content-type"
content="text/html; charset=UTF-8" />
<script type="text/javascript">
function onChanged(e,id) { var element
=document.getElementById(id);
python.onChanged(id,element.textContent); }
</script>
</head>
<body>
<div>
<xsl:attribute name='id'>
<xsl:value-of select='@id' />
</xsl:attribute>
<xsl:apply-templates />
</div>
</body>
</html>
</xsl:template>
<xsl:template match="title">
<div>
<h1>
<xsl:attribute name='id'>
<xsl:value-of select='@id' />
</xsl:attribute>
<xsl:attribute name='contenteditable'>
<xsl:text>true</xsl:text>
</xsl:attribute>
<xsl:attribute name='onkeyup'>
<xsl:text>onChanged(event,'</xsl:text>
<xsl:value-of select='@id' />
<xsl:text>')</xsl:text>
</xsl:attribute>
<xsl:value-of select='.' />
</h1>
</div>
</xsl:template>
<xsl:template match="text">
<div>
<p>
<xsl:attribute name='id'>
<xsl:value-of select='@id' />
</xsl:attribute>
<xsl:attribute name='contenteditable'>
<xsl:text>true</xsl:text>
</xsl:attribute>
<xsl:attribute name='onkeyup'>
<xsl:text>onChanged(event,'</xsl:text>
<xsl:value-of select='@id' />
<xsl:text>')</xsl:text>
</xsl:attribute>
<xsl:value-of select='.' />
</p>
</div>
</xsl:template>
</xsl:stylesheet>
python脚本 将html渲染到WebKit:
xml_utils.py
from lxml import etree
def getElementById(doc,id):
return doc.xpath("//*[@id='%s']"%id)[0]
def XSLTransform(xml,xslt):
try:
return xslt(xml)
except Exception,e:
transform=etree.XSLT(etree.parse(xslt))
try:
return transform(xml)
except Exception,e:
root=etree.parse(xml)
return transform(root)
if __name__=='__main__':
print XSLTransform('template.xml', 'richedit.xsl')
sample.py
import sys,locale
from lxml import etree
from PyQt4 import Qt
from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4 import QtWebKit
import xml_utils
encoding=locale.getdefaultlocale()[1]
class PythonJS(QtCore.QObject):
__pyqtSignals__ = ("contentChanged(const QString &,const QString &)")
@QtCore.pyqtSignature("QString,QString")
def onChanged(self, id,msg):
#print msg,id
self.emit(QtCore.SIGNAL('contentChanged(const QString &,const QString &)'),id, msg)
@QtCore.pyqtSignature("", result="QString")
def message(self):
return "Message!"
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow,self).__init__()
self.update=True
self.xml=etree.parse('template.xml')
self.tabs=QtGui.QTabWidget(self)
self.browser=QtWebKit.QWebView(self.tabs)
self.edit=QtGui.QPlainTextEdit(self.tabs)
self.tabs.addTab(self.browser,'View')
self.tabs.addTab(self.edit,'Edit')
self.edit.setPlainText(etree.tostring(self.xml,pretty_print=True))
self.pjs=PythonJS()
self.connect(self.edit,QtCore.SIGNAL('textChanged()'),self.onTextChanged)
self.connect(self.pjs,QtCore.SIGNAL('contentChanged(const QString &,const QString &)'),self.onJSMessage)
self.connect(self.browser.page().mainFrame(),QtCore.SIGNAL('javaScriptWindowObjectCleared ()'),self.onObjectClear)
html=xml_utils.XSLTransform(self.xml, 'richedit.xsl')
self.browser.setHtml(unicode(html))
def onJSMessage(self,id,msg):
self.html= self.browser.page().mainFrame ().toHtml()
#print unicode(self.html).encode(encoding)
self.setEditText(id,msg)
def resizeEvent(self,s):
size=self.size()
self.tabs.resize(size)
def setEditText(self,id,str,update=False):
t=self.update
self.update=update
e=xml_utils.getElementById(self.xml, id)
e.text=unicode(str)
self.edit.setPlainText(etree.tostring(self.xml,pretty_print=True))
self.update=t
def onTextChanged(self):
if self.update:
try:
self.xml= etree.fromstring(unicode(self.edit.toPlainText()) )
try:
html=xml_utils.XSLTransform(self.xml, 'richedit.xsl')
html=unicode(html)
if html:
self.browser.setHtml(html)
self.browser.page().mainFrame().addToJavaScriptWindowObject('python',self.pjs)
self.browser.reload()
except Exception,e:
print e
except Exception,e:
print e
def onObjectClear(self):
self.browser.page().mainFrame().addToJavaScriptWindowObject('python',self.pjs)
if __name__=='__main__':
app=QtGui.QApplication(sys.argv)
frame=MainWindow()
frame.show()
sys.exit(app.exec_())
posted on 2008-08-01 12:01
zarra 阅读(2398)
评论(4) 编辑 收藏