基于Qt/Embedded和Qtopia的GUI设计(转)
上一篇 / 下一篇 2007-08-13 10:37:26 / 个人分类:嵌入式开发
1l X cD9M%{7j0 1 引言
"kT.[.z\1T)l0木铎校园 BBS 社区8\Ce+CZd._~)N~随着当前各种手持设备、无线设备及信息家电等嵌入式产品的迅猛发展,相应的嵌入式软硬件设计技术也在发生深刻的变化。如今,越来越多的嵌入式终端需要一个图形化的人机接口界面(GUI),良好的人机接口界面是嵌入式系统设计的一个关键技术,能够极大地提高人机交互的效率。本文详细阐述了在自行开发的嵌入式主板上实现某平台的图形显示终端过程。木铎校园 BBS 社区P/O*Ev&x+~j%F
V.w|h c0 2 系统平台介绍
z8xr2DI4qA0木铎校园 BBS 社区K Z%yC.FP+^5M根据系统设计需求,本文目的是实现一个具有图形接口界面的嵌入式显示终端,该系统使用嵌入式系统设计技术。硬件上,使用自行开发的基于Samsung S3C2440A CPU的目标板,该CPU使用arm920T内核,其主频可达400Mhz;在软件上,选择嵌入式linux为操作系统,因为它源码开放,而且稳定性与安全性较高。
p(C}zSe N0T.y3Up6j@8@0 整个系统软件由引导装载程序(uboot)、 设备驱动(包括帧缓存fb)、嵌入式Linux内核、文件系统(yaffs)、基于QT/Embedded和Qtopia的用户图形界面以及应用程序组成,系统平台结构如图(1)所示。
5R0aWo:Ja{ M9x0
图(1) 系统平台软件结构图木铎校园 BBS 社区9u"],O geH
木铎校园 BBS 社区Y E'Yf_*D)c*C2No3 Qt/Embedded和Qtopia 介绍及其开发环境的建立
/p fG+Lg R0木铎校园 BBS 社区0W\N*Z @G%pI目前嵌入式Linux的主流GUI系统主要有MiniGUI、Microwindows、OpenGUI、Qt/Embedded,这些GUI在接口定义、体系结构、功能特性存在很大差别,采取的技术路线也有所不同[1]。MiniGUI是建立在比较成熟的图形引擎之上,开发的重点在于窗口系统,其小巧精致并且尽量与Win32兼容。MicroWindows目前开发的重点在底层的图形引擎,窗口系统和图形接口方面功能比较欠缺,与Win32和X Windows窗口系统保持兼容,提供了相对完善的图形功能。OpenGUI基于一个用汇编实现的x86图形内核,提供了一个高层的C/C++图形/窗口接口,它的资源消耗小,可移植性差,不支持多进程。
1O;}0S*[YY0木铎校园 BBS 社区 rzh1H8U[9NqZ.DQt/Embedded是一个多平台的C++图形用户界面应用程序框架,其对象容易扩展,可移植性好,支持多个GUI平台的交互开发[2,3]。现在,Qt/Embedded被广泛地应用于各种嵌入式产品和设备中,从消费电器(如智能手机、机顶盒)到工业控制设备(如医学成像设备、移动信息系统等)。因此本文选择Qt/Embedded为本系统的GUI。
R;A{c9B,a6v2{0木铎校园 BBS 社区"g~;Cg!O!?+tT'Y(1) Qt/Embedded和Qtopia体系结构木铎校园 BBS 社区Ft1{:T,|:kWU
木铎校园 BBS 社区J |;e%G;e3a6r}aQt/Embedded是Trolltech公司开发的面向嵌入式系统的Qt版本,与X11版本的Qt在最大程度上接口兼容,采用帧缓存(framebuffer)作为底层图形接口。Qt/Embedded类库完全采用C++封装,并且有着丰富的控件资源以及较好的可移植性,大范围的Qt/Embedded API可用于多种开发项目。Qt/Embedded的实现结构如图(2)所示:
:BL1He5w ?E:Pw4T0
图(2) Qt/Embedded实现结构
/ee!gXEeKDm0木铎校园 BBS 社区t(U`"KD2{0@Qt/Embedded的底层图形引擎基于framebuffer。 framebuffer是一种驱动程序接口,它将显示设备抽象为帧缓冲区[4]。该驱动程序的设备文件一般是/dev/fb0、/dev/fb1等。对用户而言,它和/dev下的其他设备没有什么区别,用户可以把framebuffer看成一块内存,既可以从这块内存中读取数据,也可以向其中写入数据,而写操作立即反应在屏幕上。为运行Qt/Embedded,嵌入式Linux内核要支持framebuffer。 Qt/Embedded是Qt的面向嵌入式应用的简化版本,它包括一组完备的GUI类、操作系统封装、数据结构类、功能类和组合类。大部分Qt的应用程序可以经过简单的编译与重设窗口大小移植到Qt/Embedded。
l_0V2r7a"u{\R0木铎校园 BBS 社区h&Qp8Bv^0hQtopia是基于QT/Embedded开发的一个嵌入式的窗口系统和应用程序集,如地址本、图像浏览、Media播放器等,还包括娱乐和配置工具,广泛用于PDA等掌上设备。Qtopia平台由Qtopia 库(Qt/E,libqpe,libqtopia1,qtopiapim)和Qtopia server/laucher组成。Qtopia server/laucher是控制窗口系统、进程间通信、发起所有应用和其他核心任务的主要服务程序。
CcV!j'N.}0木铎校园 BBS 社区*Y(MnN0V-](2) Qt/Embedded和Qtopia的交叉编译与运行木铎校园 BBS 社区Qm"o S [oUkT8R
EZC@ e0 整个GUI系统的构建需要对Qt/Embedded、Qtopia依次分别编链,然后有机地整合在一起。Qt/Embedded为Qtopia提供了底层支持,GUI系统的图形库窗口组建都由Qt/Embedded实现。
g&DtX7h)^ [0木铎校园 BBS 社区?I9nS;x'E4S8[c!f,~P在构建GUI时用于Qt开发的典型工具如下:木铎校园 BBS 社区 }2e k@5Tv&f
- tmake:跨平台的Makefile生成器。
- moc:用于Qt C++扩展的metra-object编译器。
- uic:从XML文件生成代码的用户界面编译器。
- designer:用于设计窗口组建的应用程序。
qBZ[9^!s?0 Qtopia的开发工具包SDK(Software Development Kit)是Qtopia开发环境的核心部分,编译后得到创建应用程序所需的软件包如下:
@-Y\"D`,]S:K'?0- qvfb(virtual frame buffer):X窗口用来运行和测试Qtopia应用程序的系统程序。
- qpe(Qtopia executable):用来处理所有的用户程序界面[2,5]。
~+D*KY@W,T \ q0 由于我们使用的是ARM CPU,因此需要对Qt/Embedded和Qtopia开发工具包进行交叉编译。本文使用arm-linux-gcc-3.3.2来建立交叉编译环境。为了对Qt/Embedded和Qtopia进行交叉编译,需要使用如下的源码树:
+d;rw7J:~PDF*jT0- tmake-1.13.tar.gz:用来得到tmake工具。
- qt-embedded-2.3.7.tar.gz:Qt的嵌入式版本。
- qt-x11-2.3.2.tar.gz:Qt的X11版本。
- qtopia-free-1.7.0.tar.gz:官方网站提供的Qtopia免费版。
- e2fsprogs-1.38.tar.gz:为了得到qtopia所需的uuid.h和libuuid.so。
6f }hzg` s9pCT0 假设将上述源码树放在同一目录下,例如:/root/qtopia,并依次解压,然后进行编译,步骤如下:木铎校园 BBS 社区:r\ s9B6[XA8i
木铎校园 BBS 社区[9H/H xR.]①设定tmake的环境变量如下:
Gl gwo0export TMAKEPATH=/root/qtopia/tmake-1.13/lib/qws/linux-arm-g++
)| At c y_ N0 此处指定了tmake在生成Makefile时使用arm交叉编译。木铎校园 BBS 社区 q3yk&W5p
|AmAs`9c%b0 ②编译qt-x11,其目的是生成moc、uic、qvfb、designer,并将它们放在qt-embedded\bin目录下。木铎校园 BBS 社区.bGMXU)ED[]I?
[`*y$G4lE G%_#u| r0 ③配置qt-embedded编译选项,命令为:
}Mt%Wgwlg4lB4}^0./configure -platform linux-arm-g++ -qconfig qpe -qvfb -depths 4,8,16,32.
JI?#Y0ar*\0 此处-platform linux-arm-g++表示在arm平台上进行交叉编译;-qconfig local表示使用src/tools/qconfig-local.h;-depths 4,8,16,32表示需要qt支持的显示颜色深度。
@9Z4M)N:WE`/E X0木铎校园 BBS 社区E3LdL*?'Y(XQ8z1I④使用make命令编译qt-embedded,用来生成Qt库(libqte.so)。
c:sp2EyU_0BG2y/r.oV0 ⑤配置并交叉编译Qtopia,生成应用程序以及桌面环境。
-A%U+J2I#k.\Ym ]0木铎校园 BBS 社区:Zq?cgPv假设编译完成后将qt和qtopia相关的库及所需文件分别存放于目标板文件系统的/opt/qt和/opt/qtopia下,运行Qtopia的方法是:木铎校园 BBS 社区zu!{D,f2s'@f
V[&N4Gbyv0 ①设置QTDIR、QPEDIR和键盘鼠标等环境变量木铎校园 BBS 社区;O(`,^/E$ex.Qnd
export QTDIR=/opt/qt木铎校园 BBS 社区I*Cvt)p}"O
export QPEDIR=/opt/qtopia木铎校园 BBS 社区TqyS;P
export QWS_KEYBOARD=USB:/dev/input/event1
ZC(g!o7m h0export QWS_MOUSE_PROTO=USB:/dev/input/mouse0
rtR:P \vp a0 ②开启qpe,也就是在Linux图形模式下执行/opt/qtopia/bin/qpe &
B#t1z8ZF%}7z@{+z0木铎校园 BBS 社区(hy_]n5Vtf这样就可以在显示终端上看到qtopia桌面环境了。木铎校园 BBS 社区 ]+x-O"DPl1C N
U"k&ig_*x8rN`0 4 Qt/Embedded和Qtopia下应用程序的实现木铎校园 BBS 社区K h`7^w;R)I t&g _[ Q
木铎校园 BBS 社区1S2g2g#G2]u(1) Qt/Embedded应用程序的实现
bQ/Pi)fl#I2O(c0~0木铎校园 BBS 社区Z@:d)]A#ip }ZIQt是一个创建GUI程序的C++类库,编写Qt应用程序的主要工作是基于已有的Qt类编写用户类。Qt应用程序的设计使用基于工程的方法,并通过.pro文件进行工程管理。实现应用程序的第一步是编写.pro文件,然后使用tmake根据该文件生成Makefile,最后进行源代码的编写。tmake的语法如下:木铎校园 BBS 社区$CX(s\:HEo^*E+U
tmake *.pro –o Makefile木铎校园 BBS 社区KoV+e'i6k"o,za;u d
.pro的具体内容可以参考/qt/examples/下其他应用程序的.pro文件。
l5W6c+|tj jCR0xB,h*qJ*y0 在本项目的研究中,需要涉及基本的窗口构建、应用程序的调用、图像背景的显示以及中文显示,下面对此进行详细阐述。木铎校园 BBS 社区w1H4J!h"mz{rd
2I ~1or!o.N!Bf(?0 构建主窗口
,_Z$D%_Uf0.l~^8k%Cv.ht0 Qt拥有众多的窗口部件,如按钮、菜单、滚动条和应用程序窗口等,它们组合起来可以创建各种用户界面。QWidget 是所有用户界面对象的基类,窗口部件是QWidget或其子类的实例。木铎校园 BBS 社区 UoY2DGT\
木铎校园 BBS 社区3Ut'^+ZB V.RUM创建主窗口先要在main.cpp函数中创建QApplication类型的对象。QApplication类管理图形用户界面应用程序的控制流和主要设置,它包含主事件循环,在其中来自窗口系统和其它资源的所有事件被处理和调度,它也处理应用程序的初始化和结束,并提供对话管理。对于任何一个使用Qt图形用户界面应用程序,都正好存在一个QApplication对象。然后定义主窗口变量,并通过QApplication类型的函数调用主窗口变量来启动主窗口。木铎校园 BBS 社区5PTR'Fw*l&k#] p
6Hl+LQ+pZ$s/Z$]]0 创建主窗口部件最常用的方法是基于QWidget或QDialog类创建一个用户类。QDialog类是对话框窗口的基类,主要用于短期任务以及和用户进行简要通讯的顶级窗口。在本程序中使用QWidget类创建用户类,并使用户类通过公有继承派生于Qwidget类。
/x+n3|.P\!k+[D;@`q0;E/VU+A5J0 在构建窗口时需要注意用户界面的风格和布局。Qt提供了Windows、WindowsXP、Motif、MotifPlus、CDE、Platinum、SGI和Mac的内置风格。自定义风格可以通过继承QStyle、QCommonStyle或其他QCommenStyle类来完成。应用程序的风格可以如下设置:木铎校园 BBS 社区:gMC%v|2p"r.OqF
QApplication::setStyle(new MyCustomStyle)
nG{Xp [ @0 在布局上Qt提供了布局管理器来组织父部件区域中的子部件,Qt内建的布局管理器有QHBoxLayout,QVBoxLayout和QGridLayout,而且布局也可以嵌套在任意层。例如使用QHBoxLayout(按行放置部件)的部件管理器为例在窗口水平放置两个按钮B1和B2的代码如下:木铎校园 BBS 社区9~{3Zy x}
QHBoxLayout *hbox = new QHBoxLayout(this);木铎校园 BBS 社区DO/I `a0k{-j:j'H木铎校园 BBS 社区7Y;j K$N%YB0s0k#A x
Hbox->addWidget(B1);
:}-W9q'X'l/Z+F0Hbox->addWidget(B2);
创建按钮实现对应用程序的调用
f7q'o#E.iF)r04K"WQ1c%t2G0 Qt部件与用户的交互方式不同于其他的GUI工具包,其他的GUI工具包使用回调函数创建用户交互,但是Qt提供了信号/槽(signal/slots)[5]通信机制描述对象间的无缝通讯。槽(slot)是标准的成员函数,它能够连接到信号,每当槽所连接的信号被发射时,槽(函数)就被执行。信号(signal)是一种特殊类型的函数,都是返回void型,它们被定义为当某个事件发生时就被发射,之后执行所有被连接的槽。当定义信号时必须使用QT的宏SIGNAL(),定义槽时必须使用宏SLOT()。木铎校园 BBS 社区%s7qE+A,l rdd\
T$Fq"YH!wD0 通过调用QObject对象的connect函数可以将某个对象的信号与另一个对象的槽相关联,这样当发射对象发射信号时,接收对象的槽将被调用。该函数定义如下:木铎校园 BBS 社区9Z9z!xozD2Mz/Y\
bool QObject::connect(const QObject *sender,const char *signal,const QObject *receiver, const char *member)木铎校园 BBS 社区E,]"y4xw
与这个函数对应的disconnect函数,可以将信号和槽断开连接。
N,L%[)i I-Y q h$Y0木铎校园 BBS 社区'Z\-q4[*v"J]本文使用了QT库提供的按钮clicked()信号,自定义了槽函数run()来实现对应用程序的调用,并且定义了槽函数mycall()调用已经使用了特定参数的run()函数。木铎校园 BBS 社区 Ki3~w.nei
木铎校园 BBS 社区-x1X,C;@|E例如当一个按钮B1被点击时,它就发送“clicked”信号,通过connect()函数将信号与槽“mycall”连接起来,调用/opt/qt/examples/clock/下的应用程序“clock”的代码如下:木铎校园 BBS 社区S@ {b:~*i2Q
void MyMainWindow::mycall()木铎校园 BBS 社区1_ Q)E'_"_3Y8mm2Q
(n'Hmi? p0{
!F/]?\&\{Z};r-^/k0 MyMainWindow::run(“(cd /opt/qt/examples/clock; exec ./clock;)”);
G'K:z&wZ4H)Wa*g0}
&Hiv*r7hT(rm0
,`a4gj8a"Z!A&C-l"O;W0connect(B1,SIGNAL(clicked()),this,SLOT(mycall()));
图像背景的显示
R#b"J:w\Cxr0木铎校园 BBS 社区;r['Owo*G6N1m为了在Qt中装载和显示所支持的图像格式,需要创建一个QPixmap对象。QPixmap本质上是一个“屏幕外的部件(off-screen)”,图像可以先复制到一个QPixmap对象上,然后传送到QWidget。
,X4e {O4vyh0木铎校园 BBS 社区2d-e?G%t'|5NQWidget部件使用如下的成员函数来为窗口添加图像背景:
S2rNz{m O$i0public Members木铎校园 BBS 社区qNvKxC_4Fs
const QPixmap* backgroundPixmap () const
(iCo9TGMwA0virtual void setBackgroundPixmap ( const QPixmap & )
2paPmjWO0 例如有一幅名为flower.png的图片,将其设为背景的代码如下:
3pnerq1[ZuhS0QPixmap picture(“flower.png”)木铎校园 BBS 社区 @.t5^*?j g_木铎校园 BBS 社区@n9n6t4D
SetbackgroundPixmap(picture)
中文显示
&xi:tONk0木铎校园 BBS 社区_M)X8s.`2x*f)XQt的中文显示是Qt国际化的一部分,“国际化”简称为i18n,用来提供一个架构,让同样的代码可以适用于各种语种习惯和编码系统,程序设计人员只要利用这个架构的机制、准则编写应用程序,就可以在不新编译代码的情况下,支持各种语言。
7K k#}t`;OJ:?u \x0;\:pcxa{;_N0 Qt支持Unicode—国际标准字符集,程序员可以在程序里自由的混用英语、汉语和其他Unicode所支持的语言。为Qt增加一种编码只需要增加该编码和Unicode的转化编码就可以了,Qt支持中文的GBK/Big5编码。
+Q$R y9sm&tr0木铎校园 BBS 社区;x f:IT~*K3lQt支持的字体常用的是ttf和qpf。qpf是Qt/Embedded专用的一种适合嵌入式应用的字体,它属于位图字体,不可以缩放,而ttf字体可以缩放。默认情况下Qt/Embedded在lib/fonts目录下提供了一种可以显示中文的字体库UniFont,但是该字体库中没有ttf的字体。为了使用ttf字体显示中文,本文采取如下的方法:拷贝一种支持unicode编码的ttf字体到lib/fonts目录下,例如,windows系统下的宋体simsun.ttf;同时还需要在此目录的fontdir脚本中添加下面一行:
}5ne x.O:kM1b+UK0木铎校园 BBS 社区d w"vqKg|0R/B2cR0simsun simsun.ttf FT n 50 0 su木铎校园 BBS 社区:V&REH^ h
fontdir脚本用来向系统注册所支持的字体,它的每一行定义了一种字体的设置,其格式如下:木铎校园 BBS 社区5mjhc*z'D \
<字体名称><字体文件名><字体渲染类型><是否斜体><尺寸><字体标志>[尺寸列表]P2`6Gj2i n&A#w6A5q0 在程序设计中,首先指定编码方式以支持中文:
3G%Je+H:o0QTextCodec *code=QTextCodec::codecForName("GBK")木铎校园 BBS 社区"gc&V:l9js*B z5X-G[4W!K接着为部件(例如Mywidget)执行 Unicode的转化编码:
!JA~a\2{Hb0QString uniStr=code -> toUnicode("要显示的中文字符")木铎校园 BBS 社区_t-u"u@Z f木铎校园 BBS 社区\P7V(l6^
Mywidget-> setFont(QFont("simsun",20,QFont::Bold))
]s'h.a6`_}u0Mywidget-> setText(uniStr)(2) 向Qtopia移植应用程序木铎校园 BBS 社区+b7tU JfI
木铎校园 BBS 社区9g^/]nUQtopia是一个基于QT/Embedded开发的一个嵌入式的桌面环境和应用程序集,可以方便地在Qtopia桌面环境中添加用户应用程序或者对桌面进行配置。为了添加用户应用程序,需要在Qtopia/apps/Application目录下建立一个.desktop的桌面文件,该文件指明了桌面文件的图标以及应用程序的入口点。应该注意的是为了让新的应用程序在Qtopia桌面环境中运行,应用程序必须使用QT提供的图形库进行编译。
lT"D"v LDNJ7k0Dq\9}N0 下面以移植嵌入式的web浏览器konqueror为例,说明添加新的应用程序的过程。木铎校园 BBS 社区 y g$_-A3vy
#C5{S0` BE9b0 (1)下载konqueror源代码,对其进行交叉编译。为了支持中文显示和flash,还需要进行必要的源代码修改,并且加入相应的插件。木铎校园 BBS 社区R8x4K3N:Du`4}E
木铎校园 BBS 社区+tvG-u`,PD(2)将konqueror.png图标文件拷贝到在/opt/Qtopia/pic/下。木铎校园 BBS 社区H9VcF[1C"T'd(M
木铎校园 BBS 社区$Gy$Z]w M!t5SN(3)将konqueror可执行文件放于/opt/konqueror/下,然后在Qtopia/apps/Application目录下建立konqueror.desktop文件,具体内容可参考qtopia自带的.desktop文件。需要注意的是konqueror.desktop的Exec项应指明可执行文件的具体位置。例如:Exec=/opt/konqueror/bin/konqueror木铎校园 BBS 社区g!|B;mcMO
木铎校园 BBS 社区O$R!SnB*n(4)导出konqueror的运行环境变量,就可以直接在桌面上点击其图标浏览网页了。木铎校园 BBS 社区l1i$^ V.Evb'\
木铎校园 BBS 社区8B/Q[J&E;x"^w5 结束语木铎校园 BBS 社区8TvqsTDT.y
(wQUB"\b3pQl0 嵌入式产品的广泛应用带动了图形用户界面(GUI)的迅速发展,嵌入式系统需要一个高性能、高可靠的GUI的支持。基于Qt/Embedded的Qtopia桌面系统为系统用户提供了良好的使用和交互环境。本文系统介绍了基于Qt/Embedded开发应用程序的方法以及将现有的应用程序移植进Qtopia的具体过程,为类似的系统开发供了一个参考。
f6c7C,P~0木铎校园 BBS 社区W%\ j Y|:M V.g/o参考文献
*^1z7?6X)| {0木铎校园 BBS 社区+?p%wG|5S C[1] 丁丁,习勇,魏急波,三种主流嵌入式图形用户界面的移植及性能比较,《电子产品世界》,2004,9(5):73-74
'_ } h Yo0
$vh/t'y&I$D?s&{n0 [2] QT 3.3白皮书,http://www.trolltech.com
DL?~y;V{C0 [3] 袁鹏飞,24小时学通qt编程,北京:人民邮电出版社,2000/11木铎校园 BBS 社区OVtG.b6R#|-i5~
[4] 于明俭,陈向阳,方汉, LINUX程序设计权威指南,北京:机械工业出版社,2001/4
&OaF^U'`{D m0 [5] 张娟,张雪兰,基于嵌入式的GUI应用程序的实现,《计算机应用》,2003,23(4):115-117F$c&Hnd.OJ0 作者简介:王丽洁(1981-),女,硕士研究生,研究方向为嵌入式系统的开发与应用。
%]i5Sck|2z0
,E;l:|.o*y'F)L0 作者联系方式:410073,湖南长沙国防科大四院2系,0731-4575752,13873163041,lilywang_04601@163.comf3\xfC.n0 (参考链接:http://www.mct.com.cn/hot/qianrushi/9-6.doc)
~0f3rn)g0
文章来源: http://www.mct.com.cn 文章作者: 王丽洁 习勇 魏急波
'vq ox*?8gT0相关阅读:
- 【tips】 查看修改 linux 网卡工作模式 (平凡的香草, 2007-3-13)
- The Linux HTTP Benchmarking HOWTO (平凡的香草, 2007-6-04)
- Linux Autofs LDAP (平凡的香草, 2007-6-06)
- Linux Standard Base Specification 2.1 (平凡的香草, 2007-7-20)
- ReiserFS (平凡的香草, 2007-7-25)
- Qt参考文档 (行云流水, 2007-8-09)
-
引用
删除
Guest / 2008-07-17 10:40:40
-
我的皮肤去年做了光子嫩肤,字从今年5月份起每次遇冷遇热,紧张,激动,脸都会红的特别厉害,在朋友面前我觉得非常的尴尬也十分影响美观,我决心要把它去除,可是,用了好多的产品,<BR>刚开始还是有点效果,可后来越来越严重,我彻底的绝望了,偶然的机会我在网上发现了诺美康治疗过敏红血丝的医疗机构,在咨询过专家以后,才发现以前我治疗红血丝的那些方法全是错误的,难怪会变得越来越严重,在专家的耐心讲解下,我决定在试试,我定购了一套诺美康治疗先天性治疗红血丝套装,货很快,三天就到了,吃了15天,效果真的很明显,遇冷越热也不在红,我又坚持把疗程吃完,<BR>皮肤不但很有弹性而且也真的不红了,我又预定了半年的疗程,现在脸上一点点都看不到红血丝了,真的不相信我能好的这么彻底,真的感谢诺美康让我变成了另外一个人!详情可咨询诺美康专家:http://www.myns888.com 专家热线:13825207655 免费电话:400-628-9986
美亚奈斯国际集团(香港)有限公司
网址:http://www.myns888.com

