一、TouchGFX安装5 T1 _9 D* I5 D$ I! l
1.从stm32Cubemx下载TouchGFX
2 [( L0 [$ l4 v7 A9 Y
; w$ e( \5 j$ @4 J; E
# T& [/ m4 _2 f2 _3 r
& V- _2 [5 L* R: K# l$ b2.找到下载路径6 i. V0 m+ B1 z6 Q) g, F
这个路径是可以更改的,默认在C盘。1 N) h- o. C& \% L
在stm32Cubemx的上方工具栏里依次选择Help->Updater settings(快捷键Alt+S)找到touchGFX的下载目录。
. g# g, K- ]% j. K9 K3 v7 C1 D+ J6 q
9 ^/ I9 y5 H5 n( i
. c9 ?- z# l& H# j. i7 G! v
$ g$ }6 d, t: Z3 d
3.为MDK5安装touchGFX插件
2 k1 `# Z2 \. S& j% f找到MDK5的TouchGFX安装包位置,具体位置在第2步的Packs文件夹下。...\Packs\STMicroelectronics\X-CUBE-TOUCHGFX\4.15.0\STMicroelectronics.X-CUBE-TOUCHGFX.4.15.0.exe0 |' x1 @$ Z' ? K- n0 C: S
" e) i |: g( t5 z7 ~
) C/ g- l: ?& J8 `) H5 d r
W, O9 f" @2 j% { ^
安装完成后可以在 keil5的Pack Installer里看到已经安装好了。$ ~1 S) _0 H. |; g
, b% P$ T) }* x* B/ V
$ {$ I5 I" M; G6 F% @& t" W% ?% Q- M' M2 c$ K5 g: y- N9 s: |* U
4.安装touchGFX
& s _- i6 P. v7 {安装包目录:...\Packs\STMicroelectronics\X-CUBE-TOUCHGFX\4.15.0\Utilities\PC_Software\TouchGFXDesigner\TouchGFX-4.15.0.exe。) ^' E' v/ i9 ], P9 g
也是在第2步的下载目录下。
# c: p0 b6 J( U" B* ]4 ?. _4 L5 g4 k9 G0 Q6 ~
$ g' a. v% G! i
' @# `# r7 w2 ^6 `至此,安装工作已经完成。# `& q1 s# j/ \% R9 b& F
/ m' o( b! E/ a# S, F4 y; K二、创建第一个示例工程7 R0 k3 n" g5 l5 G
1.创建工程
9 m* D* `% M* R5 m7 c! w创建工程,选择Blank UI,并设置你需要的屏幕大小。这里屏幕设置为480*272+ I$ j2 O! z# t- l, F9 S9 P
$ @. v/ D: s- q0 P
+ l: @9 V& N3 S- X; E
4 v9 k* G( v6 ?6 y2.添加背景5 Y8 G' H0 C5 [% v6 \
1、TouchGFX 应用程序由多个屏幕组成。屏幕包含许多组成用户界面的小部件。屏幕覆盖整个显示器,因此一次只向用户显示一个屏幕。要做的第一件事是将初始屏幕的名称更改为Main,如下图所示。这样做的目的是以后有多屏幕应用的时候可以很好区分,对于程序维护和开发来说非常适合。7 Y1 K l; W- B! {8 f( n
2、通常,用Box或Image给屏幕添加一个背景。此例子中,我们将使用Image给屏幕添加一个背景。TouchGFX支持BMP和PNG,尽量使用PNG,因为PNG更小而且支持透明度! ?" e' I% U( v. B" W
* J: X% w; s9 e' W
4 s+ g; l$ O* d7 v
; k& N% y/ L+ @, \0 V: n" F x工具栏左侧点击Add Widget 选择添加一个Image插件,同时别忘记更改控件名称7 u7 }9 @5 S% R
/ _. k: G* \& Y
/ @- ~8 H* @8 O' y
: g! ]. `( S9 a1 Y1、选择"Image"选项卡并单击蓝色加号图标。
^9 Y8 C6 \. _% o+ U* Y; {. }2、找到下载的图片素材并选择"background.png",为了防止重复工作把其他需要的图片一起添加进去。可以多选一起添加。5 X2 R3 {" F" V( o' W+ K
3、导入后左侧会显示添加的图片' t9 S% l! D" S
# r+ ?4 L! l' j$ ?- u) p3 R! F
$ A" K: I: m% [. m* }
* E' w8 b' r* d. p9 ?: V" q8 U
1、回到画布视图
7 N, {8 }$ X6 ~2、右侧选择image给控件添加背景图片& O& L2 G; `7 p1 Y- t3 o/ B
6 W, _5 }1 W3 l6 D$ f
) o# B: i" d6 y# q' G7 e' w. b2 S, P' `! e0 C" H% n9 [
3.添加按钮) [- E& l1 G9 z2 {# e
1、单击"小部件"选项卡中的"按钮"小部件,向屏幕添加两个按钮,并更改名字为 ButtonUp和ButtonDown
- |6 T8 J$ ?# K0 y" k" M; v3 J2、ButtonUp定位在 x=40,y=60。, z% W! w, N2 R8 u+ i$ f l
3、ButtonDown定位在 x=40,y=150。
- \2 N) C) L( ~; N) c/ {3 [& l
! P2 _, N. |4 ]* m
r' d; U( V o3 N/ f3 t" c$ a/ r; X) O' O: I
更改按钮的外观。在右侧更改按钮松开和按下时的背景图片。
: R6 |( a9 k8 p2 ]! ]$ H& N' y8 z
6 e, g/ c5 c. N' P' A
) B( _* F5 H6 x' P5 w
8 K G+ y& G K7 c# @1 H添加完成后,运行simulator,在PC模拟一下界面是否有问题。4 N7 m+ z+ o+ G1 I1 J8 A! x2 j
2 R% B' d& c b3 Y' Y/ X2 j
5 K4 ?& B' _# L
# T, |( `# q3 S8 g# u0 |, o2 w; y" [4.添加文本
! S# v6 c2 p$ [1、添加一个Image 控件3 S0 Q3 N% r$ J; F. V& @0 e
2、给它添加背景图片"counter_box.png"9 T+ c+ K/ \0 ?2 @! N( V
3、坐标:x=250,y=59。' I6 D( _" @5 S5 Z7 Z. W7 K/ a, R) z' I
4、名字改为:counter_box0 Q3 B ]$ w0 ]/ `& f7 m5 b' k
* i# e" K5 B& D% T5 f- X! d+ |
& ^- l4 S' e( i V
! p7 L& v& P" R
1、添加文本控件% a5 D' H- c- d- R( M* l
2、坐标:x=250,y=903 I4 K! l6 ~* i' m1 N/ E- u
3、右侧AutoSize取消勾选,设置W=152 H=90(必须先取消Autosize否则没法改宽度和高度)5 i' q3 d. ?8 e2 l+ W
4、名字设置countTxt
d, x0 y8 Y7 n5 P8 f# _- @7 g' `5、对其方式设置:center/ w" \7 e. V# x
% C0 A6 I7 ~" U
9 a! V8 l0 J2 o' H3 r$ d) o) W# H
- T' l1 ?# I: Q! P4 U按照下图设置TextArea的字体/ h8 Q5 [2 J/ q- Y
. Q; m, t0 v+ s# q2 q3 g3 d' h
+ c: A) C7 M) c- I5 I1 N
8 P0 C0 [! F( _9 h5 D
我们希望 TextArea 显示一个数字,我们可以用按钮更改该数字。# n; g* v: [% {* O* B% T, J
为此,更改文本以包括"通配符"。通配符是文本中的标记<d>,在运行时用其他内容替换。我们只想显示一个数字,因此我们
- h! I8 n' j* j3 ?$ }& G将文本更改为"<d>"。在其他项目中,可以将动态部件与固定文本相结合,例如"温度:<temp> °C"。另外,<...> 通配符是可选的。
& I2 G0 U: [- N) v0 g# d: c1、添加通配符( M, `* l5 R) }0 i. l5 [
2、设置通配符符号( H! p, N: v/ c+ h& E/ {) @8 m: y
3、设置初始化值
# [: z+ f" `0 W2 @! E4、设置buffer
3 C* Z/ b. |$ r) G$ u8 M+ l9 p3 O+ n7 ^3 Y+ R* [3 B; V, w8 C
[- i- j6 s! f
" x! V: S- W3 P运行模拟器
- g0 a' t3 f6 b* v- c4 L y) x
) l3 y$ H4 l& G3 D
/ I$ U1 Z# e/ v4 X4 Q6 w' {8 x( {
$ x, V( f# b9 h7 I2 _; Z
5.添加代码
7 `3 [9 n1 r3 H" h* [4 j6 X: T我们将创建两个InterActions,每个按钮一个。
. |5 _+ l' ]! B% W% W2 q. N9 Y1、添加交互' t8 @1 }. \: r% [2 w8 X* Y
2、设置触发方式
+ ^/ ?+ h* `4 q' _4 e3、设置触发源9 Z) p! H5 y; q- S1 A, ]$ Z
4、设置触发时调用虚函数
9 v: @+ F3 {6 ~5 C8 K: g/ W% \( z5、增加虚函数名称,方便区分维护
# r! ?8 G6 }6 O- p) M2 q" ^ g- n4 o: V3 t: A6、为"交互"提供信息性名称,以便以后可以识别它,也可以默认不修改它
) ^, m) }. Y4 |5 k5 Z( }) E- t5 Y. Q, W) Z
+ Y/ p5 S* w& a3 k; S0 c8 i* c4 d' o: `: i- _
检查无误后点击右上角Generate Code生成代码
# w7 S9 s8 S/ j8 } w$ @, K+ Q/ k9 Y+ i1 r
& O5 L8 t6 u5 E% J. c* q' O' g& O6 m& J9 W4 h6 p: U
然后依次找到simulator\msvs\Application.sln并打开代码
1 b: n0 H) g0 {0 L$ z% f: s! U' `, G+ i6 l6 H
- n( {6 h9 x' @, m [, {4 p/ q6 I" J
直接编译工程或者按快捷键F5,中间有任何提示均选择是。* \8 w. z `+ r
! @1 e4 x' F( I+ W7 m* j& ^
% r" F+ N0 M3 F+ b
( X% [" S6 ?% X9 F- b最终结果和TouchGfx仿真结果一样
% J* C$ Y7 c" \- {. `
/ h! i# p+ N( B; F; i( h, C( q% i
+ E7 U2 M: f* F) C" G
5 e" T o- \: r L- M3 }6.生成的代码" ~# P5 d; W" m `8 k i# q" C v
虚方法位于类MainViewBase.hpp的公共部分。生成的方法具有空实现,需要重写。此文件不要更改,有touchGFX自动生成
3 T1 k2 |- P2 n( c# \# I2 _: ?6 W& K
- /*********************************************************************************/& E6 b# f( o* L0 t, B f3 v; ~
- /********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
! r2 R6 j, h n6 F# y7 O% a - /*********************************************************************************/
8 ~4 I7 n( g' B: e0 ~+ K - #ifndef MAINVIEWBASE_HPP c, E8 a! G2 K+ ]% ^5 f
- #define MAINVIEWBASE_HPP$ G1 W# n, v, Q; Z4 q
- + d U9 o) c, O
- #include <gui/common/FrontendApplication.hpp>2 o6 f/ m M O) ^: m6 D G2 p
- #include <mvp/View.hpp>
/ A0 d/ |, g7 h/ z, b. Y - #include <gui/main_screen/MainPresenter.hpp>
' R F& u5 \: m1 S0 P5 H" m - #include <touchgfx/widgets/Box.hpp>
; C: R+ J6 i( }8 }! @/ o - #include <touchgfx/widgets/Image.hpp>/ {" c) ^* d7 ]/ k( d
- #include <touchgfx/widgets/Button.hpp>- d; _! U, ], F6 U4 o) |
- #include <touchgfx/widgets/TextAreaWithWildcard.hpp>
/ U" d1 u. U( _+ d, ?- ~& V - % _9 s$ I4 A+ F
- class MainViewBase : public touchgfx::View<MainPresenter>
. k, V+ C2 i' h6 t - {1 i2 I) O1 ?6 o1 c$ w
- public: A- F$ K# |* u# t( H7 X* i* R
- MainViewBase();- S2 i5 T7 O3 H& x1 r6 u% a
- virtual ~MainViewBase() {}
( t7 u6 w- [: I& ~2 S$ H - virtual void setupScreen();
: }* ^" R8 ~* x
1 x B2 a4 O, q5 S- /* I* e3 Q$ B" c( z0 w
- * Virtual Action Handlers. [) u( u/ D7 H- }( g
- */
' [/ P) }; U( Y& [ b, w. V - virtual void ButtonUpClick()
0 {- T; |, E" }$ F! p - {
( m" X8 J, I7 f9 n5 c/ } - // Override and implement this function in Main
/ r, { e/ j3 n7 T - //需要重写
& y3 O( |/ Q( d% K1 i - }$ R9 D( _5 t# e# S' y! I" N
+ g3 X* Z4 e9 g" J! c: R+ Q. i- virtual void ButtonDownClick()
% j* ]2 G- z2 K- |* o - {0 `. b' D. a6 x
- // Override and implement this function in Main
" @: O/ H# D$ {' Q! z - //需要重写
# U& d, q4 k* f/ C$ B9 B- t) Q - }" \0 z' |- v# H! ~! Y; ^
- - o: |) V6 T) {# }# \: b
- protected:
( m Y( H& T. _$ P3 i v - FrontendApplication& application() {2 ~3 {5 G( W, ?9 \5 I% y
- return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
7 o: ?" R* a& }6 _ - }9 @( p/ P4 a# C" Z
* X1 l! ~. _2 R9 c- /*1 ]3 Y" n |& F4 l9 a
- * Member Declarations' O$ [8 _4 L2 [. ]0 v/ t! T
- */
0 b$ w8 v! G) S& j( ]( E" ]" h1 j5 R - touchgfx::Box __background;
* r( K( B8 g; V7 G1 B - touchgfx::Image Background;5 t9 c! v0 \5 D; ]) K% x
- touchgfx::Button ButtonUp;1 n0 k5 n n& m3 j) E
- touchgfx::Button ButtonDown;7 W1 E L/ H5 { U/ J4 Q
- touchgfx::Image counter_box;
" j; F* a& M6 k, g& d - touchgfx::TextAreaWithOneWildcard countTxt;
/ B0 s! s) }/ |% T. ]: [0 b - ! m& q. X6 W: k' L- K
- /*' j7 b/ `" @5 Y. _) l( ^ @
- * Wildcard Buffers: o# Y% e1 H; T* Q
- */
; M. Y' j4 S) j' ~' q5 d# @ - static const uint16_t COUNTTXT_SIZE = 10;
. m2 z9 G- |0 t% N1 _! T - touchgfx::Unicode::UnicodeChar countTxtBuffer[COUNTTXT_SIZE];; U# O; U: |. M8 V
2 `$ f( P4 v/ t( @6 i- t+ ?: u5 K, k- private:3 ^/ V6 `4 G. A8 z, _9 T; R' }
( q7 s8 C8 v2 u9 E0 N- /*
1 O/ {. J3 r3 @; {8 E" a( V - * Callback Declarations$ p1 _8 S! V5 }( t1 k% V# J; V5 z0 h
- */' z- z- T+ ]" }3 X' b8 r, A
- touchgfx::Callback<MainViewBase, const touchgfx::AbstractButton&> buttonCallback;
6 F3 ?8 r; Z0 M* N- k( M3 Y
' j. d; s( ]+ u& t8 c9 c4 m H- /*
, y3 Q/ e% {: L0 i+ P4 | - * Callback Handler Declarations. {3 A$ u0 a: Z: k" a G; l
- */( P. y$ {, M1 J$ S: b0 b
- void buttonCallbackHandler(const touchgfx::AbstractButton& src);6 O2 H2 C5 @# ~4 n8 A
- 5 p' j: _7 Q+ X1 @* Z3 }. S9 S
- };0 d+ d- g0 o( m
- , ?& ?' D- u) E
- #endif // MAINVIEWBASE_HPP4 r1 |1 B: s3 [( K- S1 W
复制代码 $ T; R4 t) w# U! c, Z% {0 g
7.实现虚方法/ I$ [; _' ]: a
- 在MainView.hpp中手动增加虚方法声明 s2 M2 s0 ^1 Y$ A& F
- virtual void ButtonUpClick();//添加
+ j4 m3 e" a, Z* h' l2 k9 H - virtual void ButtonDownClick();//添加
复制代码- #ifndef MAIN_VIEW_HPP# @& [1 ^- }3 H/ `/ [* t
- #define MAIN_VIEW_HPP- Y) _, e8 [" Q, s5 u
- $ H% u" f& l( S0 Y: d, U- t
- #include <gui_generated/main_screen/MainViewBase.hpp>
1 t! q$ \ K5 I* ?2 T. A - #include <gui/main_screen/MainPresenter.hpp>
3 L" F5 Q- r! Z* @
, Q$ N% E# y" Q0 @1 P- class MainView : public MainViewBase
' A1 e* a6 }1 x2 G - {1 b: l5 I) ^1 _; W" G1 g) r( ?
- public:- u3 A( {- i, t% K6 ?
- MainView();
2 `' o" j: p5 |1 P4 v! r- @ [ - virtual ~MainView() {}
% A' v- c( h* h& z* V7 b - virtual void setupScreen();
& `- R# v' |/ J* r' P2 K - virtual void tearDownScreen();
: @+ Y9 Z: F* C s5 f% C" o4 N - virtual void ButtonUpClick();//添加9 K- x! H# r% {9 _4 t1 u
- virtual void ButtonDownClick();//添加+ g5 P# ?* O! v7 Y
- }
复制代码
8 H: p O; Q. X+ C( T5 X然后在MainView.cpp中增加ButtonUp和ButtonDown按下时打印提示9 I* b# z0 u2 K6 u! f ?3 P& M& N6 i7 C
+ Q- G: ~% f8 W. y: D* T- #include <gui/main_screen/MainView.hpp>' X$ O6 r3 Q! l) y q- G! L8 e; _5 W
. C4 l% V! H- e) i' g$ Y5 y- MainView::MainView()8 X( y9 t" B, l" u. h: v; q
- {
- J( c4 {3 P9 r7 _9 c7 e! `
& q: B r4 C' s: X3 s. ~9 Q M- }. S' a% G0 f" w& c
3 { k: `! m1 @7 c+ Z1 w# ]" I. E2 V- void MainView::setupScreen()2 E! V# b: |9 c' A, e1 y+ g: a, L2 K) A
- {, I5 v% V0 I* d% C N6 O3 P+ ^
- MainViewBase::setupScreen();
- |: ^2 N K" O& i g, p- J, M - }' R* g& \6 c5 K( V7 j
! h, z9 W- Q! R- void MainView::tearDownScreen()
/ r7 q" @( ]* @ - {, g1 O1 T5 {6 v6 h) z; g
- MainViewBase::tearDownScreen();# e5 G9 @8 W ~# l y6 ?2 E/ |; O
- }1 e i7 S8 @& ?% g& a. R3 x4 K8 ~/ {
. E0 Y) {) o3 g7 A; z8 Q* j4 f- void MainView::ButtonUpClick()
) c5 X& S2 P) V3 ~; B7 c - {
! T- v- X0 ^: o6 q - touchgfx_printf("buttonUpClicked\n");
4 P$ |) E/ z5 {, G- Q! n - }
* O }( q2 F R
# D( Q& Z/ E. k8 X9 ?- void MainView::ButtonDownClick()0 e5 p$ @9 f# @7 P- n1 t l7 u% x( Y
- {
! H% K; r: W9 O. u1 J& Q+ A - touchgfx_printf("buttonDownClicked\n");! d; _2 y1 }; G. v2 _1 E1 b/ |) V
- }
复制代码 0 B7 d/ l# R# u- _7 }& |
4 _7 ?0 ]1 o: Y3 w. O
# l4 B9 a- @' | Y# q! l% {在MainView.cpp的按键按下方法中,我们增加计数器值。然后,新值将转换为字符串,并复制到我们为上一步中的文本配置的 10 个字符缓冲区。
t2 |# `; A. Q# v7 _5 b& S0 k4 z: H+ h* `3 f5 u& Z, Z8 X% X: [
- #include <gui/main_screen/MainView.hpp>3 `2 F0 _9 e2 i0 D
- " {, W8 x4 o, o! E- l* m( S
- MainView::MainView()& c' [- C5 j X6 i1 }
- {3 N( S$ o: o# X. G6 f, _. ?
- - |# z! N4 l( _
- }
: q s/ O: e5 K
/ }, Y" ^: M" `3 ~) H0 X2 W- void MainView::setupScreen()! b6 j$ |! e5 I6 z' d
- {& \- z$ r5 C4 G( W
- MainViewBase::setupScreen();( x" I9 L' |4 t2 ^" P
- }4 F; J8 ?2 u# `8 o5 f# n/ O
- 0 C! c/ N3 U+ f, h. \ Q
- void MainView::tearDownScreen()+ O3 |- N$ J+ y8 f2 s- H
- {
0 @0 {2 ~. V+ U( i& h - MainViewBase::tearDownScreen();
+ }4 m+ f }+ f: m$ a; o ~ - }
/ N4 `: i7 k8 k2 Z - void MainView::ButtonUpClick()0 B; ?* j+ |' J% E( }; a& O; A
- {
0 F* l7 o# r' t - touchgfx_printf("buttonUpClicked\n");
9 _1 a) u" m4 G5 h5 y - counter++;
9 }. u( B4 f9 |4 Y - Unicode::snprintf(countTxtBuffer, COUNTTXT_SIZE, "%d", counter);3 N) G! `# m: T( F4 H- U8 O
- countTxt.invalidate();! `+ o# Z2 Y* J) i# M8 j3 ^9 Q
- }
) Y. M$ K7 L3 l* F& ^ - & H0 y3 ~. Y. F+ o& p4 f
- void MainView::ButtonDownClick()
+ f1 q& y+ E( m0 w! A8 y+ M! l' T/ h - {2 ^5 S- c2 ^/ p ~
- touchgfx_printf("buttonDownClicked\n");
) {4 d G v* F8 d - counter--;
) K9 B8 r8 N) ]2 A& z, v - Unicode::snprintf(countTxtBuffer, COUNTTXT_SIZE, "%d", counter);
4 @: |( S6 {5 S) ^: | - countTxt.invalidate();$ ~9 U; V [ G7 N) q" l
- }
复制代码 4 Z( o/ F$ n4 ~) N. }
运行发现并没有按预期显示数字
* |9 W0 M- e0 D3 D! d8 P
9 \2 z% B8 \, n0 V* w
! ~& `0 q, }( X3 D$ k
5 b* E) j- S* r我们需要告诉 TouchGFX 设计器在"默认"排版中包含字符 0-9。( u; Y3 P/ C5 P' Z) R# u
为此,请返回 TouchGFX 设计器,然后单击"Text"选项卡,然后单击"Typographies"选项卡。在默认排版"WildCard Ranges"列中,添加范围"0-9"。为了能表示负数还需要在WildCard characters 添加负号“-”。
) b; J3 `' w% @% t# X `5 Y8 x8 M" j+ E' E; P
% l: g8 \' v9 {3 R. h: b3 S0 Z) |' {- h* ~# k( Q) T4 r) H
重新运行发现实现了我们预期的功能
" _6 R+ w/ ~ y/ }0 X4 S5 ]; q& O( ^5 j
. O S: [) l. {( z
( f: \- Y9 h6 @6 s9 b
至此,我们已经完成了第一个实例。
' J/ {& r3 s. d
8 q* a8 r. g3 G0 C: |( ^2 Y% J) e/ Q5 V& P ]
& h* _" a. T0 E6 e* g
|