STTTextArea 是基于 LVGL textarea 的文本输入控件,支持普通文本、数字约束、变量换算、内置/自定义输入法及文本选择。
STTTextArea* edit = new STTTextArea(getRuntime(), this, "pressureInput");
edit->setMainArg(20, 40, 180, 44,
false, true, 3, 6, 2, 0.0f, 9999.99f, true);
edit->setMainStyle(4, 0xffffff, 0xffffff, 0,
1, 0x999999, 6, 6, 8, 8, 255);
edit->setFont(0x202020, 18, "", 0);
edit->setPlaceholderText("请输入压力");
setMainArg 依次设置位置尺寸、密码模式、单行模式、对齐、整数/小数位、上下限和按键音。align:0 自动、1 左、2 中、3 右。返回 this 的接口可链式调用。
edit->setText("12.30"); // 按控件输入规则设置
edit->addText("5"); // 在光标处插入
edit->delChar(); // 删除光标左侧字符
edit->delCharForward(); // 删除右侧字符
string value = edit->getText();
edit->setTextValue("原始值"); // 绕过 maxLen/accepted chars 检查
setText、addText 会走 LVGL textarea 的正常处理。setTextValue 直接写值,即使违反 setMaxLength 或 setAcceptedChars 也可成功,适合程序回显而非用户输入校验。setPlaceholderText / getPlaceholderText 管理空值提示。getText 返回拷贝,可安全保存;底层 C 字符指针不应由业务代码缓存。edit->setCursorPos(0)
->cursorRight()
->cursorDown();
edit->setCursorClickPos(true);
edit->setTextSelection(true);
edit->setTextSelStart(0);
edit->setTextSelEnd(3);
edit->setTextSelBgColor(0x3399ff);
bool selected = edit->textIsSelected();
uint32_t begin = edit->getTextSelStart();
uint32_t end = edit->getTextSelEnd();
uint32_t color = edit->getTextSelBgColor();
edit->clearSelection();
相关接口:getCursorPos、getCursorClickPos、getTextSelection、cursorLeft、cursorRight、cursorUp、cursorDown。索引以字符位置为语义,但 UTF-8 多字节字符的实际移动由 LVGL 版本决定,不要用字节偏移自行计算中文光标。
HideCursor(true) 仅把光标变为透明,并不取消焦点或禁止输入。setLabelAlign 设置 textarea 内置 label 的对齐位置。
edit->setOneLine(true)
->setPasswordMode(false)
->setAcceptedChars("0123456789.-")
->setMaxLength(9)
->setIntLen(6)
->setFracLen(2)
->setLimit(-100.0, 9999.99);
setPasswordMode / getPasswordMode:密码显示。setOneLine / getOneLine:单行模式。setAcceptedChars / getAcceptedChars:允许字符集合;空串表示不限。setMaxLength / getMaxLength:0 表示不限。setIntLen / getIntLen:整数部分最大长度。setFracLen / getFracLen:小数部分最大长度。setAlign:文本对齐。这些限制主要服务于键盘确认流程。外部直接绑定变量、setTextValue 或其他底层写入可能绕过部分规则,业务关键数据仍需在提交时二次校验。
edit->setLimit(0.0, 10.0);
double low = edit->getLowLimit();
double high = edit->getUpLimit();
edit->setVariableLimit("Recipe.MinPressure", "Recipe.MaxPressure");
setVariableLimit 会监听指定变量并更新上下限;传空名称可跳过相应一端。变量必须存在且生命周期覆盖文本框。析构会处理内部连接,但不要在变量管理器已销毁后再析构控件。
edit->setExchRate(R"({"no":"0","mo":"100","nv":"0","mv":"4095"})");
string config = edit->getExchRate();
显示公式为:
显示值 = (mo - no) * (实际值 - nv) / (mv - nv) + no
nv/mv 是变量量程,no/mo 是显示量程。必须保证 mv != nv,JSON 字段可解析为数值。配置非法时不要假定控件一定保留旧配置;设置后应使用边界值验证显示和反向写入。
Ivariable pressure = vm->get("PLC.Pressure");
edit->bindData(pressure);
edit->onEventHandler(LV_EVENT_READY, this,
(EHandler)&Frm01::onPressureReady);
onDataChanged 把变量值格式化后显示,应用整数/小数位和换算率。onConfirm 是内部确认处理:校验限制并写回绑定变量。不要直接调用这两个内部函数。
注意继承自 STTWidget 的共享指针绑定不会保留 shared ownership;绑定对象必须持续有效。程序调用 setText 不等同于确认并写回变量,是否写回应以 READY/键盘确认流程为准。
edit->setImeMode(2); // 纯数字
uint8_t mode = edit->getImeMode();
模式:0 小写、1 大写、2 纯数字、3 符号数字、4 T9 拼音、5 全键盘拼音、6 无、7 自定义。
全局开关:
STTTextArea::isSelectAllOnFocus = true;
STTTextArea::isShowMinMaxInNumberKB = true;
二者是静态全局状态,会影响所有文本框,不是单个实例配置。
static const char* keys[] = {
"F1", "F2", "SPACE", "\n",
"OK", "", nullptr
};
static uint16_t controls[] = {2, 2, 3, 2, 2};
STTTextArea::setCustomKey(keys);
STTTextArea::setCustomKeyCtrl(controls);
STTTextArea::setCustomSpecialKey("SPACE", " ", 0);
STTTextArea::setCustomKeyHandler(&Frm01::onCustomKey);
STTTextArea::setCustomKeyFont(customFont);
edit->setImeMode(7);
edit->setprivCustInputPageId("MyKeyboardPage");
edit->setCustomImePosition(1, false);
setCustomKeyHandler 回调返回 true 时阻止默认处理,返回 false 时继续默认输入。setCustomSpecialKey 的 idx 必须在 0..7。
keymap、ctrlmap 和字体指针由框架保存原始地址,不复制内容,必须使用静态/全局存储并覆盖整个使用期。数组终止格式应按当前输入法实现要求提供;不要把局部数组传入。
getImeStyle(part) 返回输入法共享样式指针,当前实现主要支持 part=0/1;返回空时不得解引用。修改会影响共享输入法外观。
edit->setMainStyle(6, 0xffffff, 0xf5f5f5, 1,
1, 0x808080, 4, 4, 6, 6, 255)
->setFont(0x101010, 16, "", 0)
->setLabelAlign(1);
setMainStyle 设置主背景、边框、内边距和透明度;setFont 设置文字颜色、字号、字体和字形。密码、单行等是行为配置,不应通过样式代替。
void Frm01::initPressureEditor() {
pressureEdit = new STTTextArea(getRuntime(), this, "pressure");
pressureEdit->setMainArg(20, 30, 200, 48,
false, true, 3, 4, 1, 0, 500, true)
->setAcceptedChars("0123456789.")
->setMaxLength(6)
->setImeMode(2)
->setPlaceholderText("0.0")
->setFont(0x202020, 18);
Ivariable v = vm->get("PLC.PressureSet");
if (v) pressureEdit->bindData(v);
}
setTextValue 会绕过字符和长度约束,不用于验证不可信输入。setCursorPos、选择范围等接口未替调用者做完整业务边界检查,索引应控制在当前文本范围内。