oscommerce 3.0 人民币添加

九 17 2009

oscommerce 3.0 安装后是没有人民币的,在oscommerce 3.0 添加货币是很简单的,在后台’网店主要设置管理’->’货币管理’中点击’插入’按钮,填入如下选项值:

名称:人民币

代码:CNY

左侧符号:¥

右侧符号:元

小数位数:2

币值:6.83056021

填好后点击”保存”按钮,如果要设置为默认货币,点击默认.

oscommerce 支持网络货币汇率更新,点击眉头上的”更新货币汇率”按钮,选择XE (http://www.xe.com)更新,以为第一个会报错,第二个比较正常,这样你的汇率就是最新的了.现在人民币就添加成功了.呵呵.欢迎查看本人的oscommerce 3.0中文和添加模板.

No responses yet

oscommerce 3.0 中文及模板定制

九 17 2009

oscommerce 3.0 alpha 5已经释放好几个月了,最近一直搞zen-cart开发国外电子商务网站,已经习惯了zen-cart模式,oscommerce 2.2一直没有去学习,因为在我进入电子商务的时候我的前辈推荐我使用zen-cart,zen-cart是oscommerce的重构版本,比oscommerce好用.后来一直没有看,包括我在网上看到zen-cart和oscommerce的比较评价都是zen-cart好于oscommerce,最近在无意中发现oscommerce 3.0 alpha 5,于是随便看看,发现现在的oscommerce 3.0的文件结构都重构过了.个人觉得文件结构的安排比zen-cart好.并且oscommerce 3.0支持面向对象编程.也许面向对象编程成为php发展的趋势.

oscommerce 3.0的文档几乎就没有什么,在网上聊聊无几,很多记录和这个oscommerce 3.0根本毫无关系.

下面介绍怎么添加oscommerce 3.0的模板吧.

首先我们到www.oscommerce.com的官网下载最新的3.0 alpha 5,下载地址

然后下载中文语言包,下载地址

在apache+php环境中部署好,然后安装.我想这些大家都明白.不明白就去网上查找一下相关资料

然后把下载好的中文语言包解压覆盖源文件的相关目录,这是进入后台就会有中文的选择了.

接下来就是模板的添加了,这个和zen-cart不是一样,但是很相似.就是在templates目录里添加要增加的模板目录和模板首页例如我们要添加一个test模板,现在在templates目录里建立一个test目录还有一个test.php文件,这个test.php文件可以复制default.php然后修改成自己想要的样子.接下来也是最关键的一步就是在adminincludestemplates中增加一个test.php文件.文件复制这个目录下的default.php文件然后修改几个地方:类名中default替换成test有两处,一处15行处的class osC_Template_test ,还有一处是18行$_code = ‘test’.17行的$_title = ‘osCommerce test Template’修不修改问题不是太大,但是最好修改,这样有助于阅读分别.接下来进入后台查看templates中多出一个模板选项(“osCommerce test Template”),这样一个模板就建立成功了.

模板建立好了,接下来就是货币本地化,欢迎查看oscommerce 3.0添加人民币.

One response so far

SyntaxHighlighter brush的文本对应表

九 15 2009

Brush name Brush aliases File name
ActionScript3 as3, actionscript3 shBrushAS3.js
Bash/shell bash, shell shBrushBash.js
C# c-sharp, csharp shBrushCSharp.js
C++ cpp, c shBrushCpp.js
CSS css shBrushCss.js
Delphi delphi, pas, pascal shBrushDelphi.js
Diff diff, patch shBrushDiff.js
Groovy groovy shBrushGroovy.js
JavaScript js, jscript, javascript shBrushJScript.js
Java java shBrushJava.js
JavaFX jfx, javafx shBrushJavaFX.js
Perl perl, pl shBrushPerl.js
PHP php shBrushPhp.js
Plain Text plain, text shBrushPlain.js
PowerShell ps, powershell shBrushPowerShell.js
Python py, python shBrushPython.js
Ruby rails, ror, ruby shBrushRuby.js
Scala scala shBrushScala.js
SQL sql shBrushSql.js
Visual Basic vb, vbnet shBrushVb.js
XML xml, xhtml, xslt, html, xhtml shBrushXml.js

One response so far

CSS中背景图片定位方法

九 15 2009

图片定位可以使用光影魔术手,和Photoshop来查看.
在CSS中,背景图片的定位方位有3种:

1)关键字:background-position: top right;

2)像素:background-position: 0px 0px;

3)百分比:background-position: 0% 0%;

上面这三句语句,都将图片定位在背景的左上角,表面上看效果是一样的,实际上第三种定位机制与前两种完全不同。

前两种定位,都是将背景图片左上角的原点,放置在规定的位置。请看下面这张图,规定的位置是“20px 10px”和”60px 50px”,都是图片的原点在那个位置上,图中用X表示。

bg2008050701

但是第三种定位,也就是百分比定位,不是这样。它的放置规则是,图片本身(x%,y%)的那个点,与背景区域的(x%,y%)的那个点重合。比如,如果放置位置是“20% 10%”,实际结果如下图,可以看到这个点是在图片本身的“20% 10%”的位置上。

bg2008050702

下面是一个有趣的例子。

背景图片是四个边长为100px的方块叠在一起:

bg2008050703

请问怎样才能将其横过来:

bg2008050704

答案是,在网页中先设置四个div区域:

    <div class="box1">
    </div>

    <div class="box2"">
    </div>

    <div class="box3">
    </div>

    <div class="box4">
    </div>

然后,这样编写CSS:

.box1, .box2, .box3, .box4 {
float:left;
width:100px;
height:100px;
position:relative;
background: #F3F2E2 url(1234.png) no-repeat;
}

.box1 {
background-position:0% 0%;
}

.box2 {
background-position:0% 33.33333%;
}

.box3 {
background-position:0% 66.66666%;
}

.box4 {
background-position:0% 100%;
}

最后的效果。可以看到第二和第三个方块的设置,并不是一般想象中的“0% 25%”和“0% 75%”。

不过说实话,这个例子用像素设置法更容易一些。使用百分比设置的主要优势在于,当页面缩放的时候,背景图片也会跟着一起缩放

No responses yet

google 服务的语言切换成中文

九 13 2009

由于做web这块,一直用google的相关服务,但是有个问题一直很郁闷,就是服务页面的语言为因为,怎么切换都切换不回中文,其他服务都是正常的,就是网站管理工具不能正常,试过很多中方法都不能解决,列入,在网址的hl=en换成hl=zh_CN,这只能暂时性的解决问题,等下次打开时还是英文的,让人实在头疼,今天终于解决问题了.那就是清楚你的cookies,然后再登入,就是中文的了.前提是你的浏览器把中文设置为首选项.虽然是个小问题,但是影响人的工作心情,有中文的为什么还用英文的?所以特此记录一下

One response so far

关于php生成文件的编码

九 13 2009

近来做个项目,用到flash,因为flash只能接受GBk,gb2312编码的文件,如果为其他编码,例如utf-8则不能显示,因此想直接生成文件为gbk编码的文件,但是文件怎么生成都是utf-8的,后来我只能用记事本另存为ansi的编码,在google上突然看到有人说了这样一句话,就是生成的文件编码和php文件的编码一致,我就试试,结果果真如此,问题得以解决,故记录下来为后者提供解决的思路.

总结,如要生成gbk的编码的文件,那么你的php生成文件的文件编码也应为gbk编码,utf-8亦然.

No responses yet

域名泛解析

九 10 2009

现在我们要在一个空间放置多个二级域名,废话少说,直接进入主题.
例子:

1、http://blog.vouov.com/
2、http://music.google.cn/

以上这种形式的域名具体是怎么实现的呢?就PHP程序中涉及到得简单说一下
一、要做一个域名泛解析,就是说将 *.domain.com 解析到你的空间[服务器]上
二、要做一个服务器的泛解析,就apache来讲,要在apache的配置文件http.conf(具体的环境具体的文件名,自己注意下)中(直接添加到该配置文件的最后即可)

<VirtualHost *:80>
ServerAdmin  yuminglong@yeah.net
DocumentRoot /www/vouov
ServerName vouov.com
ServerAlias *.vouov.com
</VirtualHost>

三、rewrite 重写路径

RewriteEngine on
RewriteCond %{HTTP_HOST} ^[a-z0-9-]+.vouov.com$
RewriteRule ^/?$ /%{HTTP_HOST}
RewriteRule ^/([a-z0-9-]+).vouov.com/?$ /rewrite.php?u=$1 [L]

#含义是 例如test.vouov.com,将隐式打开的是www.vouov.com/rewrite.php?u=test这个页面
#注意:将这些放到一个.htaccess文件,然后放到网站根目录即可
#必须保证apache配置文件中的重写应用要打开,一般的空间供应商已默认打开这个模块了.如果没有打开按以下方法打开
1、去掉LoadModule rewrite_module modules/mod_rewrite.so前面出现的#号,即去掉注释
2、AllowOverride none改为AllowOverride All,在http.conf文件中搜索即可找到,修改即可
#rewrite更多规则可以参考apache文档

除了应用重写规则,我们也可以在PHP程序中来处理这些事情,

//二级域名
if(!isset($_GET['do']) &amp;&amp; $_SCONFIG['allowdomain']) {
$hostarr = explode(’.’, $_SERVER['HTTP_HOST']);
$domainrootarr = explode(’.’, $_SCONFIG['domainroot']);
if(count($hostarr) &gt; 2 &amp;&amp; count($hostarr) &gt; count($domainrootarr) &amp;&amp; $hostarr[0] != ‘www’ &amp;&amp; !isholddomain($hostarr[0])) {
showmessage(’enter_the_space’, $_SCONFIG['siteallurl'].’space.php?domain=’.$hostarr[0], 0);
}
}

注意:
第一步和第二步提到的泛解析问题,要注意的是如果我们做了真的做了 *.vouov.com的泛解析,那么任何二级域名,例如blog.vouov.com,就是之前我们做过的二级域名都将受到重写规则的影响,譬如我们之前的二级域名blog是解析到/www/vouov/blog目录的,那么做过以上三步之后,打开blog.vouov.com,实际打开的也是vouov.com/rewrite.php?u=blog,所以我们最好在重写规则中来修改blog的重写或者是在第二步中修改服务器的泛解析,将第二步中的ServerAlias *.vouov.com改为我们想要的二级域名
以上几种方法就是比较常用的二级域名实现.不要一直看,还不快动手试试.

No responses yet

session id 基础UUID

九 09 2009

首先UUID是通用唯一识别码 (Universally Unique Identifier, UUID),是一个软件建构的标准,亦为自由软件基金会 (Open Software Foundation, OSF) 的组织在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部份。一组 UUID,系由一串 16 字节(亦称 16 字节,或 128 位元)的16进位数字所构成,是故UUID理论上的总数为216 x 8=2128,约等于3.4 x 1038。也就是说若每奈秒产生1兆个UUID,要花100亿年才会将所有UUID用完。具体的可以参照(http://zh.wikipedia.org/wiki/UUID),在java中有一个这样的基础模块java.util.UUID .
UUID的版本

UUID具有多个版本,每个版本的算法不同,应用范围也不同。

首先是一个特例--Nil UUID--通常我们不会用到它,它是由全为0的数字组成,如下:

00000000-0000-0000-0000-000000000000

UUID Version 1:基于时间的UUID

基于时间的UUID通过计算当前时间戳、随机数和机器MAC地址得到。由于在算法中使用了MAC地址,这个版本的UUID可以保证在全球范围的唯一性。但与此同时,使用MAC地址会带来安全性问题,这就是这个版本UUID受到批评的地方。如果应用只是在局域网中使用,也可以使用退化的算法,以IP地址来代替MAC地址--Java的UUID往往是这样实现的(当然也考虑了获取MAC的难度)。

UUID Version 2:DCE安全的UUID

DCE(Distributed Computing Environment)安全的UUID和基于时间的UUID算法相同,但会把时间戳的前4位置换为POSIX的UID或GID。这个版本的UUID在实际中较少用到。

UUID Version 3:基于名字的UUID(MD5)

基于名字的UUID通过计算名字和名字空间的MD5散列值得到。这个版本的UUID保证了:相同名字空间中不同名字生成的UUID的唯一性;不同名字空间中的UUID的唯一性;相同名字空间中相同名字的UUID重复生成是相同的。

UUID Version 4:随机UUID

根据随机数,或者伪随机数生成UUID。这种UUID产生重复的概率是可以计算出来的,但随机的东西就像是买彩票:你指望它发财是不可能的,但狗屎运通常会在不经意中到来。

UUID Version 5:基于名字的UUID(SHA1)

和版本3的UUID算法类似,只是散列值计算使用SHA1(Secure Hash Algorithm 1)算法。

UUID的应用

从UUID的不同版本可以看出,Version 1/2适合应用于分布式计算环境下,具有高度的唯一性;Version 3/5适合于一定范围内名字唯一,且需要或可能会重复生成UUID的环境下;至于Version 4,我个人的建议是最好不用(虽然它是最简单最方便的)。

通常我们建议使用UUID来标识对象或持久化数据,但以下情况最好不使用UUID:

* 映射类型的对象。比如只有代码及名称的代码表。
* 人工维护的非系统生成对象。比如系统中的部分基础数据。

对于具有名称不可重复的自然特性的对象,最好使用Version 3/5的UUID。比如系统中的用户。如果用户的UUID是Version 1的,如果你不小心删除了再重建用户,你会发现人还是那个人,用户已经不是那个用户了。(虽然标记为删除状态也是一种解决方案,但会带来实现上的复杂性。)

One response so far

pyqt 4与google map结合应用

九 09 2009

最近学习pyqt,在网上搜索到了做Google map的,发现那个使用图片作为显示的,感觉那样很不方便,所以想以HTML显示.运用pyqt4的QWebView显示
第一步申请Google map api key,然后进行开发.
第二步,写个运用Google map api进行解析的工具 GoogleMapsUtil.py.代码如下:

import urllib

GMap_KEY_ID = 'YOUR GOOGLE MAP API KEY'

def getGMapsGEO(qaddr):
     geo_url = 'http://maps.google.com/maps/geo?'+urllib.urlencode({'q':qaddr})+'&amp;output=csv&amp;key='+GMap_KEY_ID
     gdata = urllib.urlopen(geo_url)
     gdataArray = gdata.read().split(',')
     return gdataArray

def getGMapsStaticUrl(Latitudes, Longitudes, zoom=14, width=512, height=512):
     #print "--"+str(Latitudes)+"--"+str(Longitudes)+"--"+str(zoom)
     map_url = 'http://maps.google.com/staticmap?center='+str(Latitudes)+','+str(Longitudes)+'&amp;zoom='+str(zoom)+
         '&amp;size='+str(width)+'x'+str(height)+'&amp;maptype=mobile&amp;key='+GMap_KEY_ID+'&amp;sensor=false'
     return map_url

第三步,用qt designer拉出界面,然后转化为python代码,Ui_GoogleMaps.py 代码如下:

from PyQt4 import QtCore, QtGui

class Ui_DialogGoogleMaps(object):
    def setupUi(self, DialogGoogleMaps):
        DialogGoogleMaps.setObjectName("DialogGoogleMaps")
        DialogGoogleMaps.resize(773, 588)
        self.inputAddress = QtGui.QLineEdit(DialogGoogleMaps)
        self.inputAddress.setGeometry(QtCore.QRect(40, 30, 371, 20))
        self.inputAddress.setObjectName("inputAddress")
        self.labelAddress = QtGui.QLabel(DialogGoogleMaps)
        self.labelAddress.setGeometry(QtCore.QRect(10, 30, 31, 16))
        self.labelAddress.setObjectName("labelAddress")
        self.groupBoxMapCtrl = QtGui.QGroupBox(DialogGoogleMaps)
        self.groupBoxMapCtrl.setGeometry(QtCore.QRect(530, 40, 211, 121))
        self.groupBoxMapCtrl.setObjectName("groupBoxMapCtrl")
        self.ButtonUp = QtGui.QPushButton(self.groupBoxMapCtrl)
        self.ButtonUp.setGeometry(QtCore.QRect(90, 10, 31, 31))
        self.ButtonUp.setObjectName("ButtonUp")
        self.ButtonDown = QtGui.QPushButton(self.groupBoxMapCtrl)
        self.ButtonDown.setGeometry(QtCore.QRect(90, 90, 31, 31))
        self.ButtonDown.setObjectName("ButtonDown")
        self.ButtonLeft = QtGui.QPushButton(self.groupBoxMapCtrl)
        self.ButtonLeft.setGeometry(QtCore.QRect(30, 50, 31, 31))
        self.ButtonLeft.setObjectName("ButtonLeft")
        self.ButtonRight = QtGui.QPushButton(self.groupBoxMapCtrl)
        self.ButtonRight.setGeometry(QtCore.QRect(150, 50, 31, 31))
        self.ButtonRight.setObjectName("ButtonRight")
        self.ButtonZoom = QtGui.QPushButton(self.groupBoxMapCtrl)
        self.ButtonZoom.setGeometry(QtCore.QRect(70, 50, 31, 31))
        self.ButtonZoom.setObjectName("ButtonZoom")
        self.ButtonNarrow = QtGui.QPushButton(self.groupBoxMapCtrl)
        self.ButtonNarrow.setGeometry(QtCore.QRect(110, 50, 31, 31))
        self.ButtonNarrow.setObjectName("ButtonNarrow")
        self.MapView = QtWebKit.QWebView(DialogGoogleMaps)
        self.MapView.setGeometry(QtCore.QRect(10, 60, 512, 512))
        self.MapView.setUrl(QtCore.QUrl("http://maps.google.com/staticmap?center=32.0583650,118.7964680&zoom=14&size=512x512&maptype=mobile&markers=32.0583650,118.7964680&key=ABQIAAAApIB1Ubv-TkAKBJ37W0Hh2RS1AC4DxUbsxJ-9A5H8anlW8PhTrBQW71UJo3SK1Lm1LK_DZxfeCJessA&sensor=false"))
        self.MapView.setObjectName("MapView")
        self.BtnSearch = QtGui.QPushButton(DialogGoogleMaps)
        self.BtnSearch.setGeometry(QtCore.QRect(440, 30, 75, 23))
        self.BtnSearch.setObjectName("BtnSearch")
        self.ListAddress = QtGui.QListWidget(DialogGoogleMaps)
        self.ListAddress.setGeometry(QtCore.QRect(530, 200, 211, 371))
        self.ListAddress.setFrameShape(QtGui.QFrame.StyledPanel)
        self.ListAddress.setObjectName("ListAddress")
        QtGui.QListWidgetItem(self.ListAddress)
        QtGui.QListWidgetItem(self.ListAddress)
        self.label = QtGui.QLabel(DialogGoogleMaps)
        self.label.setGeometry(QtCore.QRect(530, 180, 54, 14))
        self.label.setObjectName("label")

        self.retranslateUi(DialogGoogleMaps)
        QtCore.QMetaObject.connectSlotsByName(DialogGoogleMaps)

    def retranslateUi(self, DialogGoogleMaps):
        DialogGoogleMaps.setWindowTitle(QtGui.QApplication.translate("DialogGoogleMaps", "Google maps应用程序", None, QtGui.QApplication.UnicodeUTF8))
        self.labelAddress.setText(QtGui.QApplication.translate("DialogGoogleMaps", "地址:", None, QtGui.QApplication.UnicodeUTF8))
        self.groupBoxMapCtrl.setTitle(QtGui.QApplication.translate("DialogGoogleMaps", "地图控制", None, QtGui.QApplication.UnicodeUTF8))
        self.ButtonUp.setText(QtGui.QApplication.translate("DialogGoogleMaps", "上", None, QtGui.QApplication.UnicodeUTF8))
        self.ButtonDown.setText(QtGui.QApplication.translate("DialogGoogleMaps", "下", None, QtGui.QApplication.UnicodeUTF8))
        self.ButtonLeft.setText(QtGui.QApplication.translate("DialogGoogleMaps", "左", None, QtGui.QApplication.UnicodeUTF8))
        self.ButtonRight.setText(QtGui.QApplication.translate("DialogGoogleMaps", "右", None, QtGui.QApplication.UnicodeUTF8))
        self.ButtonZoom.setText(QtGui.QApplication.translate("DialogGoogleMaps", "大", None, QtGui.QApplication.UnicodeUTF8))
        self.ButtonNarrow.setText(QtGui.QApplication.translate("DialogGoogleMaps", "小", None, QtGui.QApplication.UnicodeUTF8))
        self.BtnSearch.setText(QtGui.QApplication.translate("DialogGoogleMaps", "搜索", None, QtGui.QApplication.UnicodeUTF8))
        self.ListAddress.setSortingEnabled(False)
        __sortingEnabled = self.ListAddress.isSortingEnabled()
        self.ListAddress.setSortingEnabled(False)
        self.ListAddress.item(0).setText(QtGui.QApplication.translate("DialogGoogleMaps", "结果1", None, QtGui.QApplication.UnicodeUTF8))
        self.ListAddress.item(1).setText(QtGui.QApplication.translate("DialogGoogleMaps", "新建项目", None, QtGui.QApplication.UnicodeUTF8))
        self.ListAddress.setSortingEnabled(__sortingEnabled)
        self.label.setText(QtGui.QApplication.translate("DialogGoogleMaps", "搜索结果:", None, QtGui.QApplication.UnicodeUTF8))

from PyQt4 import QtWebKit

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    DialogGoogleMaps = QtGui.QDialog()
    ui = Ui_DialogGoogleMaps()
    ui.setupUi(DialogGoogleMaps)
    DialogGoogleMaps.show()
    sys.exit(app.exec_())

第四步:写界面的动作插槽,GoogleMapsExec.py,代码如下:

# -*- coding: utf-8 -*-

"""
Module implementing GoogleMapsExec.
"""
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import QDialog
from PyQt4.QtCore import pyqtSignature

from Ui_GoogleMaps import Ui_DialogGoogleMaps

import GoogleMapsUtil

class GoogleMapsExec(QDialog, Ui_DialogGoogleMaps):
    """
    Class documentation goes here.
    """
    jindu = 32.058365
    weidu = 118.796468
    zoom = 14
    def __init__(self, parent = None):
        """
        Constructor
        """
        QDialog.__init__(self, parent)
        self.setupUi(self)

    @pyqtSignature("")
    def on_ButtonUp_clicked(self):
        """
        Slot documentation goes here.
        """
        self.jindu =self.jindu-0.01
        GmapUrl = GoogleMapsUtil.getGMapsStaticUrl(self.jindu, self.weidu, self.zoom)
        self.MapView.setUrl(QtCore.QUrl(GmapUrl))

    @pyqtSignature("")
    def on_ButtonDown_clicked(self):
        """
        Slot documentation goes here.
        """
        self.jindu = self.jindu+0.01
        GmapUrl = GoogleMapsUtil.getGMapsStaticUrl(self.jindu, self.weidu, self.zoom)
        self.MapView.setUrl(QtCore.QUrl(GmapUrl))

    @pyqtSignature("")
    def on_ButtonLeft_clicked(self):
        """
        Slot documentation goes here.
        """
        self.weidu = self.weidu-0.01
        GmapUrl = GoogleMapsUtil.getGMapsStaticUrl(self.jindu, self.weidu, self.zoom)
        self.MapView.setUrl(QtCore.QUrl(GmapUrl))

    @pyqtSignature("")
    def on_ButtonRight_clicked(self):
        """
        Slot documentation goes here.
        """
        self.weidu = self.weidu+0.01
        GmapUrl = GoogleMapsUtil.getGMapsStaticUrl(self.jindu, self.weidu, self.zoom)
        self.MapView.setUrl(QtCore.QUrl(GmapUrl))

    @pyqtSignature("")
    def on_ButtonZoom_clicked(self):
        """
        Slot documentation goes here.
        """
        if self.zoom < 18:
             self.zoom = self.zoom+1
        else:
            return
        GmapUrl = GoogleMapsUtil.getGMapsStaticUrl(self.jindu, self.weidu, self.zoom)
        self.MapView.setUrl(QtCore.QUrl(GmapUrl))

    @pyqtSignature("")
    def on_ButtonNarrow_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        if self.zoom > 0:
             self.zoom = self.zoom-1
        else:
            return
        GmapUrl = GoogleMapsUtil.getGMapsStaticUrl(self.jindu, self.weidu, self.zoom)
        self.MapView.setUrl(QtCore.QUrl(GmapUrl))

    @pyqtSignature("")
    def on_BtnSearch_clicked(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        qaddr = self.inputAddress.text().toUtf8()
        center = GoogleMapsUtil.getGMapsGEO(qaddr)
        self.jindu = float(center[2])
        self.weidu = float(center[3])
        self.zoom = 14
        GmapUrl = GoogleMapsUtil.getGMapsStaticUrl(self.jindu, self.weidu, self.zoom)
        self.MapView.setUrl(QtCore.QUrl(GmapUrl))
        #QtGui.QListWidgetItem(self.ListAddress)
        #self.ListAddress.item(2).setText(QtGui.QApplication.translate("DialogGoogleMaps", "结果3", None, QtGui.QApplication.UnicodeUTF8))

    @pyqtSignature("QListWidgetItem*")
    def on_ListAddress_itemClicked(self, item):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        pass

    @pyqtSignature("")
    def on_ListAddress_itemSelectionChanged(self):
        """
        Slot documentation goes here.
        """
        # TODO: not implemented yet
        pass

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    DialogGoogleMaps = GoogleMapsExec()
    DialogGoogleMaps.show()
    sys.exit(app.exec_())

第五步:这样你运行一下就可以看到最终的成果了.如图.呵呵:

可以在地址框里输入查询的地址,这个程序还没有完善好.怕自己忘记先记录下来吧.等有时间在加以完善.源代码在我的附件里.呵呵

googlemapsapp_pyqt4.zip

No responses yet

pyqt通过qtwebkit嵌入显示html与js

九 09 2009

透过Python体验QtWebKit快速开发

转载:http://blog.linux.org.tw/~jserv/archives/002026.html
稍早写过一篇文章[QtWebKit:将Web 2.0技术带入行动通讯的系统设计],谈及Trolltech对于Qt Framework与WebKit的整合,提供独到的设计,不仅可很容易在应用程式中嵌入WebKit所带来的Web 2.0网路服务外,还可作无接缝(seamless)的整合。不过前文并未解说整合细节,这里就带出具体而微的范例,体验QtWebKit的技术突破与先 进的特征,恰好下个月要出席[PycTW2008],那么程式语言选用Python作为练习。

日前Trolltech正式释出Qt 4.4,业已整合QtWebKit,与Qt framework衔接的[PyQt]日前也推出v4.4.2,即可透过Python来释放QtWebKit的威力。 Qt framework一向最为人知的卖点就是”signals-slots”机制,自然在PyQt也少不了,而且还透过[SIP] Python模组,免去了许多语言层面的繁文缛节。首先,要存取PyQt的模组很容易,只要如此宣告:

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *

在这个范例,笔者设想的操作情境为,展示如何透过WebKit显示HTML element与JavaScript,以及透过iframe tag嵌入Google首页,在使用者互动的部份,透过Javascript建立对话框,并试着与Python的程式通讯。于是,我们建立一个class 来专门描绘网页,程式码如下:

class BrowserScreen(QWebView):
def __init__(self):
QWebView.__init__(self)

self.resize(800, 600)
self.show()
self.setHtml("""
&lt;script&gt;function message() { return "Clicked!"; }&lt;/script&gt;
&lt;h1&gt;QtWebKit + Python sample program&lt;/h1&gt;
&lt;input type="button" value="Click JavaScript!"
onClick="alert('1 ' + message())"/&gt;
&lt;input type="button" value="Click Python!"
onClick="python.alert('1 ' +
python.message())"/&gt;
&lt;br /&gt;
&lt;iframe src="http://www.google.com/"
width="750" height="500"
scrolling="no"
frameborder="0"
align="center"&gt;&lt;/iframe&gt;
""")

我们定义的class继承自QtWebKit中的class QWebView,在初始化时,即呼叫resize(), show(), setHTML()等method。此外,与其说上述程式列表为Python程式语言,不如说就是HTML网页原始码。熟悉网页程式设计者,一眼就可发现 我们在两个input button上建立Javascript事件关联,其中一个呼叫alert() method来显示对话框,而另一个则比较特别:

onClick="python.alert('1 ' +
python.message())

这边的”python.alert”与”python.message”就使用了PyQt + QtWebKit的专有功能,意思是按下button时,会呼叫python物件的message method,而这个”python”物件可动态在欲嵌入WebKit的Python程式中传入物件,当然,可有颇多变化。笔者这里仅作字串回传显示的动 作,不过即使如此,还是有两项技术细节要思考:

* QtWebKit的class QWebView,其最主要的目标是走访HTML个别element并描绘网页,也就是内部维护着DOM (Document Object Model),包含我们刚刚看见的那两个input button也在其中
* Javascript (或ECMAscript)内部有自己的字串与物件表示,Python也有字串,而Qt framework更有class QString,那么,该如何建立起彼此的关联呢?至少,在笔者设计的情境中,就得考虑字串与物件游走于这三方所需面对的议题

实际上,得面对的问题不只如此,不过QtWebKit + PyQt都帮我们处理掉,所以,笔者只要另行提供Python物件并交予QtWebKit即可。以下是传入到WebKit的物件相关的Python程式码:

class PythonJS(QObject):
__pyqtSignals__ = ("contentChanged(const QString &amp;)")
@pyqtSignature("QString")
def alert(self, msg):
self.emit(SIGNAL('contentChanged(const QString &amp;)'), msg)

@pyqtSignature("", result="QString")
def message(self):
return "Click!"

这个名为PythonJS的class,继承自class QObject。透过PyQt,我们宣告一个自订的signal: “contentChanged(const QString &)”,这不需要额外的moc compiler即可有对应的metadata关联。刚刚在class BrowserScreen的HTML程式列表中,所提及的”python.alert” method就定义于此,笔者依据Qt的Signals-Slot机制,去emit出”contentChanged(const QString &)”这个signal,并将alert() method后方的字串(const QString &型态)一并传出,也可见到PyQt中宣告msg参数型态为”QString”。同样,PythonJS::message method也是如此,依据上方的执行顺序来看,会先呼叫PythonJS::message()在将传回的QString字串透过QtWebKit内部 的转换,变成JavaScript的字串并作物件的合成动作(即”‘python’ + python.message()”陈述),并将得到的JavaScript字串传递给QtWebKit外部的Python物件,呼叫 PythonJS::alert() method,当然,这时候要将JavaScript字串转变成Pthon可处理的QString字串。

撰写了以上两个class,程式几乎完成了,只要将两者整合起来即可,为了增加视觉上的比较效果,笔者透过Qt 4.4提供的System Tray (在X11/FreeDesktop的术语为”Notification Area”)来作讯息显示的动作。所以修改了class BrowserScreen,追加两个method,程式码如下:

class BrowserScreen(QWebView):
def __init__(self):
QWebView.__init__(self)

self.createTrayIcon()
...
self.trayIcon.show()

def createTrayIcon(self):
self.trayIcon = QSystemTrayIcon(self)
self.trayIcon.setIcon(QIcon("images/trash.svg"))

def showMessage(self, msg):
self.trayIcon.showMessage("This is Python", msg,
QSystemTrayIcon.MessageIcon(0), 15 * 1000)

BrowserScreen::createTrayIcon() method透过class QSystemTrayIcon要求系统配置system tray,笔者设定了SVG图档(向量绘图,所以不需要考虑显示端的空间尺寸),而BrowserScreen::showMessage() method看似不相关,仅是显示讯息的动作,稍后,我们可透过Qt的Signals-Slots,将QtWebKit中的DOM/JavaScript 事件与此method给予”connect”起来。

最后一个部份,就是画龙点睛了,以下是main程式列表:

if __name__=='__main__':
import sys

app = QApplication(sys.argv)

browser = BrowserScreen()
pjs = PythonJS()
browser.page().mainFrame().addToJavaScriptWindowObject("python", pjs)

QObject.connect(pjs, SIGNAL("contentChanged(const QString &amp;)"),
browser.showMessage)

sys.exit(app.exec_())

重点当然是从前面两个class建立Python物件,也就是”browser”与”pjs”,整个程式最巧妙之处,就在于以下这行:

browser.page().mainFrame().addToJavaScriptWindowObject(
"python", pjs)

这也是QtWebKit技术的「火力展示」,原来前面的HTML列表的JavaScript程式的”python”物件,就是甫建立的”pjs”物件,而下一行也充满着惊喜:

QObject.connect(pjs, SIGNAL("contentChanged(const QString &amp;)"),
browser.showMessage)

class PythonJS所生的物件”pjs”里头的signal “contentChanged”被连结(connect)到class BrowserScreen所生的物件”browser”里头的slot “showMessage”,原本只是平淡无奇的PyQt叙述,但因为”pjs “物件被传入QtWebKit,WebKit所描绘的网页(范例即Google首页)有完整的DOM/JavaScript,依据之前的HTML程式列 表,已建立这两者的关联,如今,再将PyQt的事件一举打通。是此,Python/PyQt – QtWebKit – DOM/JavaScript的关联就建立了,咱们来体验看看,以下是操作时的图例:
在system tray多了一个绿色、类似资源回收桶的图样,而主画面就如预期,就是QtWebKit。是的,写UI就是这么简单,只要HTML tag加上iframe,顿时有声有色,为了要证明这不是纸老虎,咱们按一下左方的”Click Javascript!” input button,会得到下方萤幕输出:

这就是Javascript里头呼叫alert() method,展示了QtWebKit的基本能力,最后我们看看刚刚张罗许久的展示,当按下”Click Python!” input button后…
注意到system tray下方弹跳出黄色对话讯息,别小看这个,这可是历经Python/PyQt – QtWebKit – DOM/JavaScript等部份,显示于我们眼前的。我们也可发现,QtWebKit要与桌面整合并产生有效的互动,只需要上述这一些程式码即可,透 过Python体验QtWebKit快速开发,看来很棒呢。

取得上述程式码加上SVG图档: [pyqtwebkit-sample.tar.bz2],因为Qt framework与PyQt都以GNU GPL授权发行,本范例也是如此。
由jserv发表于May 21, 2008 10:01 PM

No responses yet

« Newer - Older »