TypePHP\Qt
Guide
Widgets
Advanced
Reference
FAQ
  • English
  • 简体中文
GitHub
Guide
Widgets
Advanced
Reference
FAQ
  • English
  • 简体中文
GitHub
  • Widget Catalog

    • Widget Catalog
    • Containers
    • Input Controls
    • Data Controls
    • Display Controls
    • WebView

Input Controls

lineEdit — single-line input

WidgetTree::lineEdit(string $text = '', array $props = [])
PropertyMeaning
textCurrent text
placeholderPlaceholder hint
passwordPassword mode (dots)
clear_buttonShow a clear button
max_lengthMaximum characters
readonlyRead-only
WidgetTree::lineEdit($state->name, [
    'id' => 'name_input',
    'placeholder' => 'Enter a name',
    'clear_button' => true,
]);

Events: change (every keystroke), submit (Enter)

$app->on('name_input', 'change', function (array $event) use ($state) {
    $state->name = (string) $event['value'];
});

$app->on('name_input', 'submit', function (array $event) use ($state) {
    $state->search();     // search only on Enter
});

textEdit — multi-line input

WidgetTree::textEdit(string $text = '', array $props = [])
PropertyMeaning
textContent
wrapWord wrap
readonlyRead-only
WidgetTree::textEdit($state->body, ['id' => 'body', 'wrap' => true, 'grow' => 1]);

Events: change

A multi-line input has no submit

Enter inserts a newline in a textEdit, it does not submit. If you want a submit action, pair it with a button.

spin / doubleSpin — number spinners

WidgetTree::spin(int $value = 0, array $props = [])
WidgetTree::doubleSpin(float $value = 0.0, array $props = [])
PropertyMeaning
valueCurrent value
min / maxRange
stepStep
decimalsDecimal places (doubleSpin only)
prefix / suffixAffixes
WidgetTree::spin($state->count, ['id' => 'count', 'min' => 0, 'max' => 999, 'suffix' => ' items']);
WidgetTree::doubleSpin($state->price, ['id' => 'price', 'decimals' => 2, 'prefix' => '$', 'step' => 0.5]);

Events: change

slider — slider

WidgetTree::slider(int $value = 0, array $props = [])
PropertyMeaning
value min max stepAs above
orientationh / v
ticksTick marks
WidgetTree::slider($state->volume, ['id' => 'vol', 'min' => 0, 'max' => 100, 'ticks' => 11]);

Events: change

checkbox — checkbox

WidgetTree::checkbox(string $text = '', bool $checked = false, array $props = [])
WidgetTree::checkbox('Dark text', $state->dark, ['id' => 'dark_toggle']);

Events: toggle, whose value is the string '0' / '1':

$app->on('dark_toggle', 'toggle', function (array $event) use ($state) {
    $state->dark = $event['value'] === '1';    // note: a string
});

You can also read it back with $app->checked('dark_toggle').

radio — radio button

WidgetTree::radio(string $text = '', bool $checked = false, array $props = [])

Multiple radios inside the same container are mutually exclusive automatically:

WidgetTree::group('Export format', [
    WidgetTree::radio('CSV', $state->format === 'csv', ['id' => 'fmt_csv']),
    WidgetTree::radio('JSON', $state->format === 'json', ['id' => 'fmt_json']),
    WidgetTree::radio('XML', $state->format === 'xml', ['id' => 'fmt_xml']),
]);

Events: toggle

combo — combo box

WidgetTree::combo(array $items, string $value = '', array $props = [])
PropertyMeaning
itemsItem text list
currentCurrent selection (the text, not the index)
editableAllow free typing
WidgetTree::combo(['Light', 'Dark', 'System'], $state->theme, ['id' => 'theme_combo']);

Events: change, whose value is the selected text and payload.index is the index:

$app->on('theme_combo', 'change', function (array $event) use ($state) {
    $state->theme = (string) $event['value'];
    $state->themeIndex = (int) $event['payload']['index'];
});

current takes text, not an index

This differs from the other controls — list takes an index, combo takes text. Passing the wrong thing silently selects nothing.

A whole screen of inputs

WidgetTree::form([
    WidgetTree::label('Name'),
    WidgetTree::lineEdit($state->name, ['id' => 'name', 'placeholder' => 'required']),

    WidgetTree::label('Quantity'),
    WidgetTree::spin($state->qty, ['id' => 'qty', 'min' => 1, 'max' => 100]),

    WidgetTree::label('Unit price'),
    WidgetTree::doubleSpin($state->price, ['id' => 'price', 'decimals' => 2, 'prefix' => '$']),

    WidgetTree::label('Category'),
    WidgetTree::combo(['Books', 'Electronics', 'Clothing'], $state->category, ['id' => 'cat']),

    WidgetTree::label('Note'),
    WidgetTree::textEdit($state->note, ['id' => 'note', 'wrap' => true]),

    WidgetTree::label(''),
    WidgetTree::checkbox('Rush order', $state->urgent, ['id' => 'urgent']),
]);
Edit this page on GitHub
Last updated: 10/6/26, 3:13 AM
Prev
Containers
Next
Data Controls