一、TouchGFX安装2 J) h. K3 I' i/ K
1.从stm32Cubemx下载TouchGFX
& M. y6 P0 j: C3 W1 N! o. n1 ]! V+ S! @; z6 w: b
" b9 `# d7 @' k9 @+ B2 Q+ f9 c
. S ~# q* ~* z* t' g2.找到下载路径
+ j6 B2 Y8 L1 ?5 ~; `( l这个路径是可以更改的,默认在C盘。 V: T. {, V3 ^! V, @7 B
在stm32Cubemx的上方工具栏里依次选择Help->Updater settings(快捷键Alt+S)找到touchGFX的下载目录。
' C' P z: T# y* o& c, T7 }1 G F4 q3 L) {8 |5 o+ x- p! ` z
) E" Y8 q# l2 H7 p+ J: z* |2 \
% ?5 R; f3 g, u% w
3.为MDK5安装touchGFX插件
5 f4 W& q* f) z: n- o7 U找到MDK5的TouchGFX安装包位置,具体位置在第2步的Packs文件夹下。...\Packs\STMicroelectronics\X-CUBE-TOUCHGFX\4.15.0\STMicroelectronics.X-CUBE-TOUCHGFX.4.15.0.exe
& _8 l9 K8 \, L6 J7 h7 ~/ P
( ]/ L8 t8 p+ I+ R. r5 c6 P; ]' W
) F5 r2 E9 L7 k9 u) C9 g" i4 }! \( ~- N; W
安装完成后可以在 keil5的Pack Installer里看到已经安装好了。0 E+ d7 z0 |; u: v. I2 ]
" v! c! K$ _* {4 j: d/ X
% b# \* g1 s1 ?* Y! Z
5 q, d+ ^: B7 Y
4.安装touchGFX M t/ a: x: Y
安装包目录:...\Packs\STMicroelectronics\X-CUBE-TOUCHGFX\4.15.0\Utilities\PC_Software\TouchGFXDesigner\TouchGFX-4.15.0.exe。
7 H5 G$ ~4 L5 V- y7 B9 b也是在第2步的下载目录下。/ t- b# P/ W8 A1 g* G- }) M7 e; Z
8 U/ m! R$ e w
4 U* R1 y; y3 W) w& X$ v5 n$ j4 t/ S4 f1 X5 t( u0 h! J
至此,安装工作已经完成。0 \- ^/ \; W8 c+ b, p
% Z, }2 X& x- X- ]1 i( O& q) U& D4 T
二、创建第一个示例工程
( O8 |8 _# c7 l, X1.创建工程
' }0 t |+ G2 ?* k( e7 m p创建工程,选择Blank UI,并设置你需要的屏幕大小。这里屏幕设置为480*272
9 s- I) B( _8 q ]; R* y& t0 S8 _$ V1 q5 O
; A9 A0 d! n. _. n0 I; h T
6 S4 @) k8 T/ X8 ?' J) W- ]2.添加背景3 G0 O( Y5 }9 `$ u; N! b5 n# |! f
1、TouchGFX 应用程序由多个屏幕组成。屏幕包含许多组成用户界面的小部件。屏幕覆盖整个显示器,因此一次只向用户显示一个屏幕。要做的第一件事是将初始屏幕的名称更改为Main,如下图所示。这样做的目的是以后有多屏幕应用的时候可以很好区分,对于程序维护和开发来说非常适合。
0 C& Z" a) `2 Y( J# O, I2、通常,用Box或Image给屏幕添加一个背景。此例子中,我们将使用Image给屏幕添加一个背景。TouchGFX支持BMP和PNG,尽量使用PNG,因为PNG更小而且支持透明度 d* R( T. S/ h, |( X( Q
7 z4 B* V" u& P6 | S
) ~& N) Y7 H9 _
" s4 {, w9 W9 j, q% F0 F; u
工具栏左侧点击Add Widget 选择添加一个Image插件,同时别忘记更改控件名称
% a k' W5 c. q; g! Z) Q% {9 `7 j& j7 {0 ?: \7 @0 w
; n2 O3 {$ g: q
8 G$ {; E3 L$ F% e! w# d) g
1、选择"Image"选项卡并单击蓝色加号图标。; B1 l' y& H5 _- V* P/ b5 y* G
2、找到下载的图片素材并选择"background.png",为了防止重复工作把其他需要的图片一起添加进去。可以多选一起添加。
6 _% S' n0 \0 b6 I l9 ]3、导入后左侧会显示添加的图片8 t* ^: U! K' k+ H
1 F2 F4 `( F# [; @% C- \
; G4 O* }# x' C9 K2 F
3 a; y! ^; v% ^! {$ y1、回到画布视图
0 y/ j- p! F% |1 n: ^, R2、右侧选择image给控件添加背景图片3 t$ _" r6 D4 U/ D
6 ]+ V- R9 B/ u, t7 f- Z
+ Q U# x5 ^2 j
3 ^7 F4 H7 q3 n3.添加按钮
7 _* R# g N4 m0 d7 U N8 F. O1、单击"小部件"选项卡中的"按钮"小部件,向屏幕添加两个按钮,并更改名字为 ButtonUp和ButtonDown
8 S1 H/ _; `) ]1 Y' h2、ButtonUp定位在 x=40,y=60。
6 o) n/ R4 U/ J, H. k1 h3、ButtonDown定位在 x=40,y=150。) g" Q0 F6 m! L7 N* h( b
1 o$ |5 s/ v$ l6 K6 m0 R" H
I) l% f+ C" w1 k: ]# w! p
6 G8 u* }2 L; ~! ^' {: |1 ^
更改按钮的外观。在右侧更改按钮松开和按下时的背景图片。
9 t% n {" ?( K7 _) G, d5 o1 ?( G* F
2 e; u) }3 F. ?. C. W _; E" j4 y, s: |
添加完成后,运行simulator,在PC模拟一下界面是否有问题。5 D% i2 s" ]: s% w/ V- {4 Q
5 m& M, r! t2 n' o4 f4 ?
' D# k3 l$ t& ~
# ?, |; X; I, R4 a& k2 g$ x4.添加文本
% a" ` t, X# v# _1、添加一个Image 控件
/ c/ J) o" d+ ^! H1 L' B2、给它添加背景图片"counter_box.png"5 \2 _) v. N3 v& _
3、坐标:x=250,y=59。# m& [. n# M" u8 s, |
4、名字改为:counter_box/ l& ~. _( d$ _) [8 t/ a+ Z
7 }8 G, ~, C; d1 F* @+ b; n
0 `; G* B; |% ^" p6 m
3 h& N- Z+ j+ u V1、添加文本控件
. e& S3 ^: o& v+ T ^9 m2、坐标:x=250,y=90
, g. p1 ]" f: B) x/ P2 C3、右侧AutoSize取消勾选,设置W=152 H=90(必须先取消Autosize否则没法改宽度和高度)' w, w B) M- h0 z0 G* b
4、名字设置countTxt
8 d. b" Z. ?1 L" f& Z5、对其方式设置:center% F: @5 ]# t [9 ~$ o/ [
" H2 u; }+ C" D
5 v8 _1 N: f a
- G8 i) N: }0 R3 E) ~6 i
按照下图设置TextArea的字体
l a/ \7 S, o' q3 A5 x
' Z/ w+ P* }& Y' y6 P9 m9 ~
r' y: Z% m2 q
& {& G0 `7 A5 Q; @% y
我们希望 TextArea 显示一个数字,我们可以用按钮更改该数字。
9 }5 h) [" H t9 O) x( N9 ?5 a; s为此,更改文本以包括"通配符"。通配符是文本中的标记<d>,在运行时用其他内容替换。我们只想显示一个数字,因此我们: X& L C2 M7 @$ y( v7 J
将文本更改为"<d>"。在其他项目中,可以将动态部件与固定文本相结合,例如"温度:<temp> °C"。另外,<...> 通配符是可选的。
9 o1 @( J/ G a0 D6 ?1、添加通配符
6 F* O% ] B0 E' K8 k2、设置通配符符号
" C. ^( w9 \) K% g9 r2 a3、设置初始化值
; E0 ]! U8 N/ R5 H q) R* M* g; ^4、设置buffer! B( q, @( Z# V& W% m1 F0 A
& r0 |3 o+ H# X* ]1 |
( C. V \0 b1 T5 p
1 f2 n& z: z7 e运行模拟器6 x- ?6 ^/ _3 ?- r! J; y
2 F3 ?0 V6 |5 l. M
9 U V3 A% t3 N9 v& J! A; i
P, U ?, t& I% W/ A+ s* Q F
5.添加代码
- P u( m5 }! C1 K我们将创建两个InterActions,每个按钮一个。4 g# i. m% A6 ] {9 E! K. o
1、添加交互( I7 \* E4 O1 ^( j) P1 L
2、设置触发方式! C! H7 F# N' g$ i+ b( z4 _ Y
3、设置触发源
. G# l q% a6 S1 ^- N2 [7 E0 {4、设置触发时调用虚函数3 W, \7 e' C( ~9 r- ]' |& y
5、增加虚函数名称,方便区分维护9 Z6 Q' Q: z6 U5 f0 N3 ]) k% H! ^
6、为"交互"提供信息性名称,以便以后可以识别它,也可以默认不修改它
- w( j( }0 I) k& j' B! Z+ b8 a- V1 R
: y: @: ^- s: M) W5 _) [6 \& e
- P9 c. V$ d* D% O
检查无误后点击右上角Generate Code生成代码5 B1 K% u. c4 s0 t! j
/ o% d5 Z1 ?% H4 s+ g6 ?7 c x
/ W( i& Y0 g( t) {
' l- Z5 _% K1 P! O' C$ V然后依次找到simulator\msvs\Application.sln并打开代码
2 ^: _1 ~! G" ` G
3 Z p3 I% Z2 G% b& Y8 P) l
6 I! m/ ~4 p' M' |# Z. R
: s1 |0 t* i* `$ N: ~2 g直接编译工程或者按快捷键F5,中间有任何提示均选择是。7 n h+ _8 R6 l" ?6 W. s
?1 J5 S9 @. W! d( G2 k
( V& E" F% }) V7 f7 x, V( i' X8 ^' a* Q
最终结果和TouchGfx仿真结果一样* e% p+ N# X J' L- J: a+ D% @4 V1 F
+ ?* `; r0 [! o5 t3 {' t
4 y, x* f7 c8 {! v I0 w
. O' ~( ]! ^, X0 Z8 ], p6.生成的代码
' J6 P# e9 u/ u& z& X虚方法位于类MainViewBase.hpp的公共部分。生成的方法具有空实现,需要重写。此文件不要更改,有touchGFX自动生成
% U4 p, j2 ]) H1 G# Z
$ `; {8 p* I: G+ x' I& m- /*********************************************************************************/
- g* z2 s6 W9 j1 F$ p - /********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
/ z: m; S0 b f5 D1 U4 G - /*********************************************************************************/
* u/ x v7 K2 d/ R - #ifndef MAINVIEWBASE_HPP6 v; L( V8 s. s, t) f
- #define MAINVIEWBASE_HPP) G. x6 i& r7 { s8 |# H
- / i5 { ?9 C \# `) ?: k4 Z H
- #include <gui/common/FrontendApplication.hpp>
2 E# k+ Z4 C' ]" [, g; T+ _ - #include <mvp/View.hpp>
0 `1 g& N/ _$ _8 P i, e* C - #include <gui/main_screen/MainPresenter.hpp>, D0 u/ p! i" d6 K8 c* r1 {5 [
- #include <touchgfx/widgets/Box.hpp>
1 J5 K# G* Y9 b - #include <touchgfx/widgets/Image.hpp>
" F) V" K/ I. D3 Z6 S* g% x. S0 r - #include <touchgfx/widgets/Button.hpp>
# x, `/ `: b" R; D: B - #include <touchgfx/widgets/TextAreaWithWildcard.hpp>5 H" N5 F9 @+ u9 K. [8 \8 t
- ( F6 }, s3 R9 @( S" h. C. W4 [6 o
- class MainViewBase : public touchgfx::View<MainPresenter>
. g8 h. F! m, F# E! b! G( x - {! t1 T9 d$ |$ a3 \" S8 ~6 Z8 ^
- public:; P5 S0 \6 h* t0 q. R) A
- MainViewBase();
# s2 e2 ~3 W& q4 k - virtual ~MainViewBase() {}
: y3 @" K9 n* _" M' C* l& D2 q% v - virtual void setupScreen();7 a1 I. t# I8 c
- & A, h- r2 n: P
- /*, v, p& o0 E2 r/ s( R9 f2 A
- * Virtual Action Handlers
. g5 j/ W- ?. } - */
' m( R/ S }, ^, {, F) Z - virtual void ButtonUpClick()
* R! D4 ^) b! C v! }, K - {5 _7 u7 t8 z* _/ i+ K/ S
- // Override and implement this function in Main% o/ p! T* q2 Z3 W; q6 G1 I
- //需要重写: x" X1 }8 _7 Y& A- L2 F3 F
- }
" P- ~4 T* k/ U* V7 I - 6 V' N' p9 x: g' a0 O& U7 r% l
- virtual void ButtonDownClick()
( n0 F+ ~& L9 T2 Y: e: S - {' Q1 l' ?. D2 K; l
- // Override and implement this function in Main1 a% A' o' v5 p1 F# i$ m% g# u
- //需要重写
! r1 i% b9 [. h7 f) u, D; t - }
V+ G: P5 L$ ]& Q- ~0 B y4 `3 [9 x
9 C7 a6 Q/ w3 r4 i- protected:
; `2 Z7 v- y6 i9 U q( J - FrontendApplication& application() {: i8 Z. _6 Z7 \6 Y( `
- return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
4 a$ {5 o O- x0 i - }
4 ]2 R( T' c) L# V# ?' U' H. g1 h - 4 f6 x' R" d0 ^/ `
- /*
, B; Y2 F7 q& c) a& O - * Member Declarations
R6 Z$ U, M' O2 ?7 @ - */( S( w9 I# f5 A! c. A" k6 S
- touchgfx::Box __background;% Y7 Z+ k: M1 _, x: i8 d" I
- touchgfx::Image Background;: h. v" E& I0 T% p
- touchgfx::Button ButtonUp;% x1 U$ E4 K) y( f/ e/ I
- touchgfx::Button ButtonDown;
) @& b* V4 S/ y% g' ? - touchgfx::Image counter_box;4 j9 [: k: j" n$ b' r3 R/ M
- touchgfx::TextAreaWithOneWildcard countTxt;5 ^* `1 i2 e1 a. W% @6 T6 O6 M& v% c
- ?) }9 \& o9 p I; p+ r+ s
- /*
" @' F. d3 q3 w - * Wildcard Buffers
. c: a/ a% i7 J( z - */
* W1 P: {1 h! B - static const uint16_t COUNTTXT_SIZE = 10;; K* C/ u. A6 c! q0 \
- touchgfx::Unicode::UnicodeChar countTxtBuffer[COUNTTXT_SIZE];( g2 F) I' D: Z% G
' @ p5 t) v& o- private:
& z/ M1 C% a# O6 H4 Y
, S; v U* o0 m! `$ z4 q3 N- /*' ~& B, h0 u9 {7 g9 `
- * Callback Declarations
3 `( K7 s& o' s/ \1 f. O7 K7 K - */* }+ n- I& Z8 Z( }. K5 q
- touchgfx::Callback<MainViewBase, const touchgfx::AbstractButton&> buttonCallback;
# x5 U u1 U; V+ g; W - ' q" ]% G) ?" U
- /*% \% r6 `% s3 _! Y8 l" K
- * Callback Handler Declarations$ f: f3 H+ j6 s" i d! q
- */
2 z, j& f" G, i6 {% a( s- L, L6 j* h - void buttonCallbackHandler(const touchgfx::AbstractButton& src);
7 U5 L4 S. {; w, u c! R$ B
+ ~2 W: E9 b! q- };4 S; |* u7 p8 R4 O8 U
- 1 f0 D5 Y! ^7 r
- #endif // MAINVIEWBASE_HPP
K F: `: M' g
复制代码
' u3 u6 T# L7 {1 @2 y7.实现虚方法, X; w; u3 b+ D+ ~* s" j; b
- 在MainView.hpp中手动增加虚方法声明
$ ]* D4 G' w( ^% C' r+ s: J - virtual void ButtonUpClick();//添加: M3 k3 u& z: ]# a
- virtual void ButtonDownClick();//添加
复制代码- #ifndef MAIN_VIEW_HPP; L, G* c: f7 w
- #define MAIN_VIEW_HPP" F" m9 b$ [" {/ L* o
- 1 C' L* _4 l" x/ F d5 c
- #include <gui_generated/main_screen/MainViewBase.hpp>( x8 ^9 t3 R+ F, d
- #include <gui/main_screen/MainPresenter.hpp> R9 G1 b) W+ g
- , z9 P5 e1 L) Q0 ?
- class MainView : public MainViewBase0 S5 u9 g; e6 m7 R
- {5 C8 M' g; ~; {- O4 H3 K/ j
- public:
0 @( \, G- E3 L& l - MainView();
n6 p+ P' ` C - virtual ~MainView() {}# r* `# ^' u9 N* l
- virtual void setupScreen();% ^0 H6 J @6 Q
- virtual void tearDownScreen();
+ O6 v5 S. \! c3 L) r5 }/ t - virtual void ButtonUpClick();//添加
: A! v% ` \1 m4 i! v$ V. r9 ]4 T' m - virtual void ButtonDownClick();//添加4 Q @0 T/ f. E- {) q7 _' W/ W
- }
复制代码 , c* s9 D6 w8 P6 d/ U% f
然后在MainView.cpp中增加ButtonUp和ButtonDown按下时打印提示" ^+ r+ M r+ N
2 ^) w' `4 E. |, t# i' M- #include <gui/main_screen/MainView.hpp>. [! |; u/ {& v1 H% Q: v
8 X. O1 g6 K; i2 F' I$ o7 }- MainView::MainView()2 X9 g* m7 T& |
- {
1 _+ ^! e& q5 @% Z( m' M
$ v& g" ?1 |8 p/ V. M7 ]' N- }% T1 t/ z( c7 L$ s) o/ n8 r
- , F" i @$ y3 u( m" G) h+ `
- void MainView::setupScreen()- h# S. c' e8 u
- {
& ]0 M5 b( |6 ] - MainViewBase::setupScreen();) P8 X! }6 V$ D, P" d/ m9 Y
- }
- P) [$ t1 H- Q7 O# q3 {
% v O" K; U' s+ J% A# q- void MainView::tearDownScreen()
! l. [# x& D2 c+ T; h: q6 | - {
3 ~9 f2 ~% c# e! x - MainViewBase::tearDownScreen();- G2 }; Y- |1 d$ n" m8 C3 G
- }
K- A, Q% t3 T5 ^
- R; m4 y; S* F3 L, e- void MainView::ButtonUpClick()
: s9 x; T4 |% d; P - {; G" \; I! o) U7 T* E4 z
- touchgfx_printf("buttonUpClicked\n");
, ?3 T/ v9 u& f' Q6 v* F" U - }
o" | B# m, `- A6 W X0 k
( x0 l$ S7 x! ^, t9 M9 @2 _( @1 T4 C- void MainView::ButtonDownClick()
# f1 j/ U. S" A) U( G+ L - {
, y+ y3 }& O5 U/ I6 k0 i J - touchgfx_printf("buttonDownClicked\n");& j' a* C7 g9 C
- }
复制代码
0 ]5 @* c9 U0 P# b( G
- a( q: T. S9 b5 p. I& G1 a# o3 W
* O1 i& m* o, U* {6 @! ^5 m
在MainView.cpp的按键按下方法中,我们增加计数器值。然后,新值将转换为字符串,并复制到我们为上一步中的文本配置的 10 个字符缓冲区。
/ d( I8 D! K9 I# ^# s1 V+ H$ W% i1 Q) F+ Z& D l, _
- #include <gui/main_screen/MainView.hpp>
. l4 P9 k, ] P - % S( O: @- S; F z3 n8 g! W: G) `
- MainView::MainView()
0 F1 D/ E7 I& w - {4 s5 `& I( n E+ ?( C+ l
- , Q6 B+ {7 |0 T( u& k( U4 o9 ]
- }
8 q) Z* ^- M( N* T5 _. L
$ T, e2 B8 i( K* z3 p8 L- void MainView::setupScreen()& {$ Q( }. l# y( u9 E
- {0 _5 l; E, _: ^* T1 J2 G
- MainViewBase::setupScreen();2 m9 ~' Y4 s2 e! \% P0 b
- }# Y! L( [7 N9 \. E, ~
% ^/ e1 o* [) T( U7 `- void MainView::tearDownScreen()8 `' l& Y8 A0 \, R' f7 h
- {
' Q+ [. M, |5 F8 w - MainViewBase::tearDownScreen();* Y6 ] ~1 b4 m" X- Y
- }7 i5 i6 E9 B- u! u6 ~0 y
- void MainView::ButtonUpClick()0 F! F% m/ u# l6 T* S
- {2 L! N* W( L/ s" m/ a
- touchgfx_printf("buttonUpClicked\n");0 I5 P( c0 a. x* p3 r$ D+ N: n$ y
- counter++;4 t7 A& n9 k& w% Y% I. \: Z" Z
- Unicode::snprintf(countTxtBuffer, COUNTTXT_SIZE, "%d", counter);" `9 ]" x, ?$ Z/ Q9 h& I9 j1 ^
- countTxt.invalidate();
?& E' M' E# ^ - }% R" G& U4 L8 p# u& i
- $ Z6 T. q. `6 p
- void MainView::ButtonDownClick()
# j0 y4 A9 F# Y( b* C" L1 s - {1 D/ G! C8 G4 J u
- touchgfx_printf("buttonDownClicked\n");$ V/ W2 I7 p V6 X1 B! ?3 N
- counter--;. V# i# u( a: a# S8 m
- Unicode::snprintf(countTxtBuffer, COUNTTXT_SIZE, "%d", counter);
2 _. o U% o& t9 e* _: u- G - countTxt.invalidate();* P9 B) R! ?" P: L/ O$ K3 ~$ g
- }
复制代码
- N4 L) E6 f& P7 e' e运行发现并没有按预期显示数字
. [: g% R! p* T' e% e8 C% x3 m9 S
/ w2 [' Z+ z3 u6 h& P% m9 Z& u$ Z
6 x4 T" G! S0 G% Y8 s! O) t
3 [+ k8 D5 e& @9 F% o" s9 q; C我们需要告诉 TouchGFX 设计器在"默认"排版中包含字符 0-9。
( u$ S1 ^0 n y3 b为此,请返回 TouchGFX 设计器,然后单击"Text"选项卡,然后单击"Typographies"选项卡。在默认排版"WildCard Ranges"列中,添加范围"0-9"。为了能表示负数还需要在WildCard characters 添加负号“-”。
$ U9 R; r u8 c# R: j0 Y; s9 o% p, j+ {3 T7 ]: G2 r; _
7 f$ s) } r' u! E5 f3 N4 k5 M& }
+ ?8 Y) a; T. A* D+ [重新运行发现实现了我们预期的功能
+ J1 }8 L! w; K2 Y# O7 J# p$ V8 y7 j' B P9 b
0 U; F+ b- J9 v3 g& B3 F6 l
* U- A$ A: L8 r2 ^至此,我们已经完成了第一个实例。8 Z# K) A( j) W# ]
) [8 C' @/ H, p
& H4 J1 }- m6 N' W
/ l6 \! F, v; d- X! R5 @" w
|