使用Webkit和xml、xslt 实现html风格的RichEdit试验

使用Webkit和xml、xslt 实现html风格的RichEdit试验
书接上回,继续研究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_())       
        





你可能感兴趣的:(使用Webkit和xml、xslt 实现html风格的RichEdit试验)