一、TouchGFX安装
6 L2 O4 y: D* a# U' o; i" z7 Z1.从stm32Cubemx下载TouchGFX
/ g4 w8 D7 F- [6 D& }. }! k9 R( I& v. `
; b* [; d5 y% o" x$ [) D$ O
# @4 @8 V) N( A% @- r2.找到下载路径
5 Y& d* F% H' b0 Y这个路径是可以更改的,默认在C盘。8 u. ^5 T) q5 R9 M& \
在stm32Cubemx的上方工具栏里依次选择Help->Updater settings(快捷键Alt+S)找到touchGFX的下载目录。
; B- J+ U! h" Z6 K7 V* i
U" D: u# A7 ~% a/ s0 b" o$ Q
|' c! q! s4 g- ^
2 |% v0 n9 G* |3 J8 I9 v) ?3.为MDK5安装touchGFX插件2 h3 ?3 z$ d1 ?$ j/ e
找到MDK5的TouchGFX安装包位置,具体位置在第2步的Packs文件夹下。...\Packs\STMicroelectronics\X-CUBE-TOUCHGFX\4.15.0\STMicroelectronics.X-CUBE-TOUCHGFX.4.15.0.exe
: m4 |3 q1 Z c' C
9 D1 I T% ~, }3 ~3 c% n, R2 U7 ^% X
& X% h7 a7 ?3 ?% I6 J7 m: J# a
5 E, V' B5 E+ X: |. w安装完成后可以在 keil5的Pack Installer里看到已经安装好了。
. @; h, e7 T0 d
1 j5 ?0 O d; H4 `8 {7 w9 V
( m& ^" F7 ?5 _% J, G) D9 q7 k9 ]
& B3 F) }; w, N" f" Z% y4.安装touchGFX
+ R; v: f; z' F" d: ]安装包目录:...\Packs\STMicroelectronics\X-CUBE-TOUCHGFX\4.15.0\Utilities\PC_Software\TouchGFXDesigner\TouchGFX-4.15.0.exe。( _5 a, N6 f4 u9 v2 x+ D' t
也是在第2步的下载目录下。
0 W( }' B; ]* O, ]: }
9 d. i- z; k# @ m- Y
+ x; K5 @) o6 F0 Z7 b) D. R1 Y7 b9 q
: u+ `2 [1 p. D r
至此,安装工作已经完成。1 J. ^8 w( _3 N j+ c
5 o! w/ D$ k9 ]5 p- z4 Y
二、创建第一个示例工程
* u h4 O( A/ z# ?6 v1.创建工程
0 u5 h% k1 \0 J+ U创建工程,选择Blank UI,并设置你需要的屏幕大小。这里屏幕设置为480*272% j! r' f7 _4 P% F/ w
# H, X# M4 ]* K* r- ~7 ~
1 y: q) |4 n' e; Y1 _
9 L4 r W/ q% u: j9 t
2.添加背景+ U: A% a4 i1 b3 T, j
1、TouchGFX 应用程序由多个屏幕组成。屏幕包含许多组成用户界面的小部件。屏幕覆盖整个显示器,因此一次只向用户显示一个屏幕。要做的第一件事是将初始屏幕的名称更改为Main,如下图所示。这样做的目的是以后有多屏幕应用的时候可以很好区分,对于程序维护和开发来说非常适合。9 L: Z/ |$ \- v: W6 M U9 n
2、通常,用Box或Image给屏幕添加一个背景。此例子中,我们将使用Image给屏幕添加一个背景。TouchGFX支持BMP和PNG,尽量使用PNG,因为PNG更小而且支持透明度
+ f' }5 S# j2 C. G0 o. q! m( C0 e7 Q( w% P) F7 D* U. x9 z
6 M& e$ a5 M8 d0 w; @4 y
: T; ~! b6 S# T2 ?# T工具栏左侧点击Add Widget 选择添加一个Image插件,同时别忘记更改控件名称% H+ I2 N8 h1 g7 I% D; F3 @0 n* D
b1 ?# l: F- Y) L8 R4 I6 e- H
& R8 f4 k/ ?, I7 f+ c3 N. b1 w. S- m
1、选择"Image"选项卡并单击蓝色加号图标。
2 B9 [: @8 p2 b; }0 m2、找到下载的图片素材并选择"background.png",为了防止重复工作把其他需要的图片一起添加进去。可以多选一起添加。
. G- ?% _2 `9 H4 Z5 e. }* x5 O3、导入后左侧会显示添加的图片. p: d. X8 \: a+ S. H( A/ [0 d
; b' x5 ^. v/ l
- C' y. @$ B4 Y- u) F8 d$ Q5 M6 e3 T! l1 j! J
1、回到画布视图
1 @7 E, g8 F& ?- c8 X0 n8 [2、右侧选择image给控件添加背景图片* |* ?" D3 q- U3 [2 _4 w9 Q; _: [
& e6 O, b- T: Q, y) h
; c$ ~' j: X- c: X
* }' Y- t5 O o9 C! C
3.添加按钮
4 B- u' \8 b. B' W7 l1、单击"小部件"选项卡中的"按钮"小部件,向屏幕添加两个按钮,并更改名字为 ButtonUp和ButtonDown
7 N4 f) q2 `' |, |# l6 `, T( E2、ButtonUp定位在 x=40,y=60。
4 N* x k* y4 o: ~/ R3、ButtonDown定位在 x=40,y=150。& y7 `9 Z; E9 s$ Y1 x; e
* H9 u% U8 m. b- V/ k
1 o" q8 H5 c2 U7 r% q
# X/ [ P3 H- L1 t更改按钮的外观。在右侧更改按钮松开和按下时的背景图片。/ [; P, j U' J' D
4 x3 Z( G u% z# k# d# a( f r
+ f% k6 q1 y" r
3 Q5 @6 O0 i3 _添加完成后,运行simulator,在PC模拟一下界面是否有问题。" D5 H& r+ N. a3 z
9 z9 z* S2 }' r
6 m4 h% L# G. d& q4 N/ e/ \
+ s* s+ p9 C4 H) m1 d8 Q4.添加文本
3 @5 V1 N% C$ w- s/ _( l. Q1 n, x1、添加一个Image 控件$ I9 q2 X- p Q
2、给它添加背景图片"counter_box.png"
. a# S) B% v: [; S3 ]( ?2 P4 Z3、坐标:x=250,y=59。 F( x) \- Y6 ]' ?" r- L) S$ i r' m1 _
4、名字改为:counter_box
+ j, K( t) x5 q1 z" l- ^+ u0 U9 g: ?8 x
! o7 K/ C1 U6 F: {) E5 V8 M: T# \! z
1、添加文本控件 z4 Z7 c& E! x* ^. H' l
2、坐标:x=250,y=901 g3 `( \4 o3 S" M: {
3、右侧AutoSize取消勾选,设置W=152 H=90(必须先取消Autosize否则没法改宽度和高度)" e* l. v( [1 U8 m# T
4、名字设置countTxt1 e0 B8 P. _) J8 Q, e6 _
5、对其方式设置:center
4 |& K$ C9 O: d/ Q( G2 O" b& r9 }" \6 M2 [
( U0 B6 g2 N3 p. y1 S
V5 C% m! a8 `8 ?4 y按照下图设置TextArea的字体
' |- H8 g$ c5 W* t
6 o5 F0 F! g5 V+ Q* C3 H
5 a! Z4 R/ u( y4 W
, W& O, B% S) Y8 C* L ?/ |$ i我们希望 TextArea 显示一个数字,我们可以用按钮更改该数字。/ u$ \9 J5 z2 {" u3 Y
为此,更改文本以包括"通配符"。通配符是文本中的标记<d>,在运行时用其他内容替换。我们只想显示一个数字,因此我们
5 o7 s: |- X8 J* `7 ?# {将文本更改为"<d>"。在其他项目中,可以将动态部件与固定文本相结合,例如"温度:<temp> °C"。另外,<...> 通配符是可选的。
; L9 ]6 Y- \5 E8 h) ?( c; z1、添加通配符( Y5 E, d D& T" t" Q" \( n4 O& z
2、设置通配符符号& P; f$ F/ I9 c; g
3、设置初始化值
7 Q3 |5 Z$ r/ e4、设置buffer
! e U8 q( u. A I2 O u
3 I5 [) b b# s
9 c! `5 Q; S6 h1 O' Z
% E/ E3 p" T6 ]6 [运行模拟器% X; D9 g# E& I, ^. {1 M5 k* e
5 A3 x( _6 h! c; ?$ M$ f! Q
1 u# Y. L" p+ C" R2 A( Y
# O$ D: \. ]5 U7 G9 b! q& g3 p; a5.添加代码
+ |4 t2 ~' Q, H4 R7 `7 k我们将创建两个InterActions,每个按钮一个。
2 \; X, e: H$ f1、添加交互! B+ j4 J& t2 P4 L1 ]7 X. M, q
2、设置触发方式
0 R$ a' M. F# ?5 F7 G( P8 ]1 O& v3、设置触发源
9 [' q( C' p0 [# {& O* w4、设置触发时调用虚函数9 }0 ?! F4 F$ K/ i. l/ J
5、增加虚函数名称,方便区分维护
5 g; B) j% u2 f) T8 M6、为"交互"提供信息性名称,以便以后可以识别它,也可以默认不修改它
7 e; \$ }7 J& q" O: }- m, b3 h9 d# w% E D C9 z9 `/ u
! l9 A8 s' S X% B; r$ k+ N
0 M0 |3 Z$ E! S: ]; T: J. M检查无误后点击右上角Generate Code生成代码
; v$ x1 s% [9 m3 l& v: U2 c; I( B5 P( F# c
* C( p& ?: p* s$ A4 d, ~
?1 H4 D( f! w {5 s
然后依次找到simulator\msvs\Application.sln并打开代码6 R: g L. k$ ]
1 l* D8 T8 y+ M4 x+ Q% m& X) U
C! N# b3 E% e/ c/ J
' k9 f* u% @: J
直接编译工程或者按快捷键F5,中间有任何提示均选择是。
( m; [0 L" R, I! w6 A3 U( e4 m
+ P. |% o* X7 T: J
0 C& s& [( D; f) I8 S# J
/ Y g& p; Z4 V4 H8 W, ^最终结果和TouchGfx仿真结果一样
1 W* T( u* k, r+ @6 I" l/ ~; t9 c$ f7 L% }
7 ~ n4 Q0 y7 k1 U
" a8 s# T* j" G, [8 Y- [8 g/ D. p6.生成的代码
% `' c1 O/ L0 Z* x) C% U- }; n虚方法位于类MainViewBase.hpp的公共部分。生成的方法具有空实现,需要重写。此文件不要更改,有touchGFX自动生成( [' M4 A) q( c( Z3 o/ e# S
; M- K; L' G1 L5 @6 ]0 N- /*********************************************************************************/6 S7 p4 p* c; d8 F4 m
- /********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/$ j$ ], o+ |, z5 f e
- /*********************************************************************************/5 L8 }- _$ J+ `4 V
- #ifndef MAINVIEWBASE_HPP: F1 k6 v" i y X& u. R
- #define MAINVIEWBASE_HPP4 G! I" y ~7 f6 k- N6 ]8 K
- Y% B m) |) k2 u
- #include <gui/common/FrontendApplication.hpp>: X4 b$ Q0 C5 S
- #include <mvp/View.hpp>3 G0 }8 Y5 c0 |* C
- #include <gui/main_screen/MainPresenter.hpp>! ^* c8 m# t( i8 C) _: k f. y
- #include <touchgfx/widgets/Box.hpp>6 N. l' _) b/ Y6 R
- #include <touchgfx/widgets/Image.hpp>
* }3 o! p/ K/ v# Q1 o% b - #include <touchgfx/widgets/Button.hpp>
0 V" \, p6 k1 O: B% u$ C' y) H - #include <touchgfx/widgets/TextAreaWithWildcard.hpp>
, `" F% J! z4 A$ @8 l - $ R# O1 f# l% L+ f: u
- class MainViewBase : public touchgfx::View<MainPresenter>% T* f' m! d& Z% n0 g0 L! H) @
- {
0 u2 _: A9 f( a( } - public: `2 l X; X! R4 M* \* h" E9 e+ J
- MainViewBase();
5 Y# K/ x6 k* K g5 y6 q - virtual ~MainViewBase() {}, s9 Z3 n) H6 L( K3 t0 _3 P
- virtual void setupScreen();
; n6 U+ Z# J6 u) W$ E% h' m
" M' o; F) i, m, a! ~ K- /*
" x! |0 h+ g; L6 R* K! F - * Virtual Action Handlers0 Y0 I( ^: a7 Z9 o O- E
- */5 G. ` W, c* j: V5 Z) @- t
- virtual void ButtonUpClick()
& A" \9 M. B/ X" `1 m" l: c - {
* U& c& b: B* z7 h1 Y - // Override and implement this function in Main9 l8 z. O3 T7 K( k
- //需要重写
$ A/ S/ y+ z0 m1 S* Y9 x+ _ - }$ G7 @8 @& w, C
- % e) V. \6 h6 s' @: l4 p% }
- virtual void ButtonDownClick()
( {9 B/ F& M. C - {% H" F3 a/ \7 N
- // Override and implement this function in Main0 i. q. u2 J& \8 I* D
- //需要重写) w& c/ F4 p& ?6 |% A" C
- }
/ ^6 L2 [: i$ G) X - ( J& F4 @) {- P. D1 X7 c
- protected:
7 v4 K1 p2 r" ^( ]1 n# O; H) X( N/ U - FrontendApplication& application() {9 T2 E1 O4 e* I' y) [0 D
- return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());* \1 i1 p" ], T, V' g s
- }
1 T( q# q4 r% U: W- N, j; u - e; w0 D" r* S4 s0 m
- /*
4 l2 X" T5 |: r" b" [1 n - * Member Declarations
d6 @$ ]: S4 s5 D8 {9 t+ e4 n1 u - */
7 V" Z, n& I/ m4 ~* ]* j0 c+ i$ L - touchgfx::Box __background;) H6 j7 R( O1 C- @( h( ~! O2 f
- touchgfx::Image Background;
4 {* }0 B7 y E; k' i* E @+ W - touchgfx::Button ButtonUp;; N8 T7 r5 Z+ ^8 g8 j( G" Q5 X3 E
- touchgfx::Button ButtonDown;5 J& R! E" a/ v' p4 y* P
- touchgfx::Image counter_box;6 }5 s8 ]6 O: f$ H6 u
- touchgfx::TextAreaWithOneWildcard countTxt;" L, D2 k: P* b3 j) N8 g* Q
1 N$ m0 i& J* ?! F5 n3 h+ P9 {) z- /*
" r& x6 H( p3 A. ^ - * Wildcard Buffers7 x( ~& I# J' e
- */4 k" {1 H+ ~6 s5 \/ @
- static const uint16_t COUNTTXT_SIZE = 10;
+ @ ~: q1 ]! M# I4 @& ?$ { - touchgfx::Unicode::UnicodeChar countTxtBuffer[COUNTTXT_SIZE];
5 Y+ R$ c6 @- y" T4 I0 H2 A - ' E! X& D+ o5 ^2 ~7 o5 m2 l
- private:
- N2 r4 A; J7 A! h
2 P# _) a# X* R% w: b( j) C1 G- /*
( Z# @5 `6 X- N" ~; r - * Callback Declarations+ q A/ Y. a* u; P
- */$ g5 D3 i! O' y: a2 B
- touchgfx::Callback<MainViewBase, const touchgfx::AbstractButton&> buttonCallback;$ K+ C5 `; ^$ h8 o. J' A
- 4 @ u: I4 Q$ d5 K% F
- /*
2 o; `9 G5 G- \5 ?8 p - * Callback Handler Declarations7 L4 G5 C9 m9 t
- */
+ K3 ?; \; J0 P6 K7 P1 `4 H9 H - void buttonCallbackHandler(const touchgfx::AbstractButton& src);
) `( h/ o, r9 }0 Y; c/ E - # Z8 L; y- N5 A( L+ B4 |( Z, N) q
- };
% @# A# M( c8 l( ]6 s4 e* m - $ ~* x5 f! ^: Z: R" s
- #endif // MAINVIEWBASE_HPP0 S/ Y. M) j; i8 i
复制代码 Q/ `: S& z- ^0 Z% C
7.实现虚方法: g1 s8 H/ N- a# t
- 在MainView.hpp中手动增加虚方法声明6 {6 F1 D: c+ d% F6 F2 q
- virtual void ButtonUpClick();//添加
; r# Y! ~6 \0 A - virtual void ButtonDownClick();//添加
复制代码- #ifndef MAIN_VIEW_HPP' ]) H2 H2 Z5 x8 ~$ \
- #define MAIN_VIEW_HPP
b4 ?2 l: T9 f, }/ s" K G
7 n7 x5 s8 z$ o* r% M- #include <gui_generated/main_screen/MainViewBase.hpp>7 U5 z% ?4 |8 _5 X" |. i; R
- #include <gui/main_screen/MainPresenter.hpp>
: q' S) \% J) w. F - % E) r3 u% W. W$ I' w" P
- class MainView : public MainViewBase, v; }& L3 w0 [4 J/ s' X2 A4 T0 H W
- {/ w! U3 t Y* g s L) Z
- public:
9 H9 S/ d* n: U - MainView();8 F# A5 a F+ S6 d) P/ J
- virtual ~MainView() {}
+ g: c; K$ b; q: \, d - virtual void setupScreen();9 G( V8 |0 |$ D5 {5 l* L) J9 e
- virtual void tearDownScreen();* Z; y ]7 Q5 U/ S' t9 A
- virtual void ButtonUpClick();//添加
/ m$ P/ {* N( t - virtual void ButtonDownClick();//添加
$ V! T2 Y t+ B+ A6 X/ f - }
复制代码
' }* ]" t8 V5 H$ H然后在MainView.cpp中增加ButtonUp和ButtonDown按下时打印提示
/ N2 p- ~* o G% l' }9 x0 c7 N1 d3 q2 L4 N0 i x, q0 m
- #include <gui/main_screen/MainView.hpp>; I1 i: \. ^" Z' a$ s" w
- . l! b. W" b8 I3 }. u! c6 B/ X5 P9 ^
- MainView::MainView()3 L2 B. ?: a' y
- {. o& O: `5 j7 d& N3 {
* j1 ]- J0 d1 x# D, m- }
% F/ I$ i6 O# p6 B# Y. Z2 S - 6 A8 d! s+ ]! n1 o3 k9 Y; H. C4 D
- void MainView::setupScreen()
; ~& u2 ?: X/ ^5 b$ G- Q - {
0 Y" l3 V8 N( S2 l - MainViewBase::setupScreen();- H# ?- k' |, S' O& D, ^. B$ J
- }+ }' v( j8 m( F& {3 b- m
: C3 n; ^8 {) N) m1 ?" K8 I8 v- void MainView::tearDownScreen()
3 {- y/ r2 o0 z; l+ b: J$ J - {
: V' E* U. y( T. n) U+ r) h- d - MainViewBase::tearDownScreen();. B9 ]2 Q' Z( K/ Z+ ~6 \
- }
( R* M$ i8 r& z8 _! O' k- C9 y
E& G, J' A( {! Y h* m/ B T- void MainView::ButtonUpClick() ^0 M2 a& f1 x* U8 {
- {
. S0 F9 x- S F/ N) Z - touchgfx_printf("buttonUpClicked\n");
' r: P& s' c' \" q0 r( z7 f - }8 A% P% T( ~1 U7 [
- + L( R/ P* ]7 x% n2 X
- void MainView::ButtonDownClick()7 y1 W- ^3 s$ X* U
- {
; A; P3 P! s' j6 ]3 t - touchgfx_printf("buttonDownClicked\n");! v9 j6 q5 e6 O: u+ |
- }
复制代码 9 A8 y/ b/ o9 F9 \
2 s5 b F/ c1 ^$ r6 A+ Z, D6 ^
. x. |# z) r+ G& M
在MainView.cpp的按键按下方法中,我们增加计数器值。然后,新值将转换为字符串,并复制到我们为上一步中的文本配置的 10 个字符缓冲区。) y7 E& k; g$ O
9 w; ~8 C) f$ O# L7 q5 i- #include <gui/main_screen/MainView.hpp>
$ E* l/ s! p3 y, i7 n9 h( n/ I - * Y3 h; o% [; Q+ C! e
- MainView::MainView()# V8 p/ [# r+ p; G- V2 ?9 C
- {* K( D( l& p0 f% {8 o
- : z7 _* s7 [+ `! q, r
- }
' G7 k8 v$ ]$ ]( z& y8 U* ^ - 9 ~) v. p8 n% t! v
- void MainView::setupScreen()
. a0 h$ k! i% N% F - {
8 v7 `9 J8 M1 Y6 R - MainViewBase::setupScreen();
8 m& W% ~$ \, [7 a - }2 U+ z: q" ]" M: C# ^/ k* w8 G
- + z# B L' n* Z, k7 H7 |3 N- Z' N( N
- void MainView::tearDownScreen()
0 N! y: w& n k( Y - {# H* T& y! x& Y& Z
- MainViewBase::tearDownScreen();
9 C8 J- W) ]+ K2 X' Z2 Z' Z, E - }
0 \- \* W. K+ T, @- T/ h - void MainView::ButtonUpClick()% W" P3 o) R) b: }4 H4 |2 F
- {; i9 h. ]: F1 ^% ]! G
- touchgfx_printf("buttonUpClicked\n"); M+ x; [) N! o) I
- counter++;( Q% g* F& J4 O) F' @$ j, {
- Unicode::snprintf(countTxtBuffer, COUNTTXT_SIZE, "%d", counter);
5 q- u: Z, e1 Y - countTxt.invalidate();
. u: \8 j* Y% V( Q- J - }4 S! G: Q/ D, F/ p/ Q, I- `0 @ P& T
2 M' K% L9 R' ^, g* o- j- void MainView::ButtonDownClick()
, C( k- N* ?4 | c - {# [1 ]7 |5 V0 a3 `' v3 ?% \) ]
- touchgfx_printf("buttonDownClicked\n");# l9 k, q5 n; `" n C6 q5 k
- counter--;- S5 d3 M2 v& Q$ g: G0 L1 o
- Unicode::snprintf(countTxtBuffer, COUNTTXT_SIZE, "%d", counter);! y8 Y( @/ M4 c C2 |) r! F
- countTxt.invalidate();
' a( T2 [' n/ D% w" f2 x: d - }
复制代码 7 r- e: z. Y3 c0 t. x T
运行发现并没有按预期显示数字
K4 n; M: H$ A3 c' u1 } T
7 {2 c- s9 H" w. q
3 S: j! w8 K6 C. H; X( |" T+ _* Z* ?& U
我们需要告诉 TouchGFX 设计器在"默认"排版中包含字符 0-9。
9 `% ^# R9 O. i2 P9 `8 ]0 H4 o为此,请返回 TouchGFX 设计器,然后单击"Text"选项卡,然后单击"Typographies"选项卡。在默认排版"WildCard Ranges"列中,添加范围"0-9"。为了能表示负数还需要在WildCard characters 添加负号“-”。
) P3 j0 H; R: {4 I) u/ d3 h! N& g9 j6 b; b' f8 V, z) a
4 u1 m) J) D* [0 R5 _8 _9 D2 `! l
6 U3 q6 ?5 U3 C, }$ w重新运行发现实现了我们预期的功能 V/ j, R N K5 w+ {* E
8 H/ [: q1 a) R7 g2 \0 w
5 ^) o/ v0 C6 I1 z4 h1 C1 K; V k, o" ]: o& k- `
至此,我们已经完成了第一个实例。
: F7 I! C6 C( ~
, C5 U% K) K, g* N
0 B& {% F, V/ R& i( L
; E+ h5 z+ N: U! P' z |