Skip to main content

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.

Basic Button Example

The following sketch creates a single red button labeled “Click” and uses the XPT2046 touch controller to detect presses:
examples/button.ino
#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

1

Create button instance

Declare a TFT_eSPI_Button object at global scope. It holds position, size, color, and press state.
2

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);
3

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
4

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

MethodReturnsDescription
press(bool p)voidCall each loop with the current press state
isPressed()boolTrue if currently pressed
justPressed()boolTrue only on the transition from released → pressed
justReleased()boolTrue 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.

Multi-Button Example

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.

Build docs developers (and LLMs) love