Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Marcussacapuces91/doc-TFT_eSPI/llms.txt
Use this file to discover all available pages before exploring further.
The TFT_eSPI_Button class provides a ready-made widget for creating labeled, touch-enabled buttons on TFT displays. It handles button rendering, hit-testing, and debounced press state tracking — making it straightforward to build interactive UIs without writing low-level touch logic yourself.
The following sketch creates a single red button labeled “Click” and uses the XPT2046 touch controller to detect presses:
#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI(); // TFT instance
TFT_eSPI_Button btn; // Button instance
void setup() {
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
// initButton(tft*, cx, cy, w, h, outline, fill, textcolor, label, textsize)
btn.initButton(&tft, 120, 100, 100, 40,
TFT_WHITE, TFT_RED, TFT_WHITE, "Click", 2);
btn.drawButton();
}
void loop() {
uint16_t x = 0, y = 0;
if (tft.getTouch(&x, &y)) {
if (btn.contains(x, y)) {
tft.fillScreen(TFT_GREEN);
delay(500);
tft.fillScreen(TFT_BLACK);
btn.drawButton();
}
}
delay(50); // Debounce delay
}
This example requires TOUCH_CS to be defined in User_Setup.h and a resistive touchscreen connected to your board. See the touch input guide for configuration details.
How It Works
Create button instance
Declare a TFT_eSPI_Button object at global scope. It holds position, size, color, and press state.
Initialize with initButton()
Call initButton() to set the button’s center position, dimensions, colors, and label text. This does not draw anything yet.// Center-based: x/y is the center of the button
btn.initButton(&tft, cx, cy, width, height,
outline_color, fill_color, text_color,
"Label", text_size);
// Upper-left-based: x1/y1 is the top-left corner
btn.initButtonUL(&tft, x1, y1, width, height,
outline_color, fill_color, text_color,
"Label", text_size);
Draw the button
Call drawButton() to render the button. Pass true for an inverted (pressed) appearance.btn.drawButton(); // Normal appearance
btn.drawButton(true); // Inverted - visual press feedback
Poll touch and check contains()
In loop(), read touch coordinates and pass them to contains() to detect if the button was pressed.uint16_t tx, ty;
if (tft.getTouch(&tx, &ty)) {
if (btn.contains(tx, ty)) {
// Button was touched
}
}
Press State Tracking
For more responsive UI with visual feedback, use the press() / justPressed() / justReleased() pattern:
examples/button_state.ino
#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();
TFT_eSPI_Button btn;
void setup() {
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
btn.initButton(&tft, 120, 100, 120, 50,
TFT_WHITE, TFT_BLUE, TFT_WHITE, "Press Me", 2);
btn.drawButton(false);
}
void loop() {
uint16_t tx = 0, ty = 0;
bool touched = tft.getTouch(&tx, &ty);
// Update button press state
btn.press(touched && btn.contains(tx, ty));
if (btn.justPressed()) {
btn.drawButton(true); // Draw inverted (pressed look)
tft.setTextColor(TFT_YELLOW);
tft.drawString("Pressed!", 10, 150, 2);
}
if (btn.justReleased()) {
btn.drawButton(false); // Restore normal appearance
tft.fillRect(10, 145, 200, 20, TFT_BLACK); // Clear text
}
delay(20);
}
State Methods
| Method | Returns | Description |
|---|
press(bool p) | void | Call each loop with the current press state |
isPressed() | bool | True if currently pressed |
justPressed() | bool | True only on the transition from released → pressed |
justReleased() | bool | True only on the transition from pressed → released |
Always call btn.press(...) once per loop iteration before checking justPressed() or justReleased(). These edge-detection methods depend on comparing the current state to the previous state, which press() updates.
examples/multi_button.ino
#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();
TFT_eSPI_Button buttons[3];
const char* labels[] = { "Red", "Green", "Blue" };
uint16_t fills[] = { TFT_RED, TFT_GREEN, TFT_BLUE };
void setup() {
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
for (int i = 0; i < 3; i++) {
buttons[i].initButton(&tft,
60 + i * 80, 120, // cx, cy
70, 40, // w, h
TFT_WHITE, fills[i], TFT_WHITE,
(char*)labels[i], 2
);
buttons[i].drawButton();
}
}
void loop() {
uint16_t tx = 0, ty = 0;
bool touched = tft.getTouch(&tx, &ty);
for (int i = 0; i < 3; i++) {
buttons[i].press(touched && buttons[i].contains(tx, ty));
if (buttons[i].justPressed()) {
tft.fillScreen(fills[i]);
// Redraw all buttons after clearing screen
for (int j = 0; j < 3; j++) buttons[j].drawButton();
}
}
delay(20);
}
API Reference
See TFT_eSPI_Button Init & Draw and Press State for the full method reference.