場輸入難題)
做LabVIEW上位機(jī)的朋友十有八九都有過這種經(jīng)歷設(shè)備已經(jīng)拉到客戶現(xiàn)場操作面板是觸摸屏一體機(jī)界面上偏偏還有配方號、批次號、工號、IP地址這些必須手動輸入的字段。讓客戶接USB鍵盤不現(xiàn)實很多產(chǎn)線工位根本沒地方放用系統(tǒng)自帶軟鍵盤界面風(fēng)格和自家程序完全不搭中文輸入還要去戳屏幕體驗一言難盡。所以我花時間整理過一套LabVIEW中英文虛擬鍵盤源程序?qū)iT解決這類場景的輸入問題。這篇把方案選型、核心實現(xiàn)、實操步驟和踩坑記錄全部攤開講一遍做上位機(jī)、做HMI的朋友可以直接拿去改。1. 為什么LabVIEW項目里非要有這塊鍵盤不可1.1 觸摸屏工控現(xiàn)場的輸入難題寫辦公軟件的團(tuán)隊可能很難理解產(chǎn)線工程師為什么會對屏幕上多一個鍵盤這種事較真。但真正到現(xiàn)場調(diào)試過就知道很多自動化設(shè)備合同里明確寫著人機(jī)界面采用觸摸屏默認(rèn)就是不配實體鍵盤鼠標(biāo)的。設(shè)備操作員每天站在屏前手上戴著手套環(huán)境里有粉塵、油污實體鍵盤既占空間又難清潔。可MES相關(guān)需求又把手動輸入的字段堆到了界面上操作員編號、產(chǎn)品型號、生產(chǎn)批號、當(dāng)前工單、設(shè)備維護(hù)密碼……這些字段用下拉框很難覆蓋必須開放自由輸入。這種情況下放任不管操作員有幾個應(yīng)對辦法。第一跟現(xiàn)場工程師抱怨然后被塞一個積灰的舊鍵盤用膠布貼在屏邊上第二靠系統(tǒng)自帶軟鍵盤湊合但自帶軟鍵盤按鈕很小戴手套戳不準(zhǔn)在英文系統(tǒng)上還輸不了中文第三干脆把設(shè)備晾在那等IT來處理。不管哪一種本質(zhì)上都是在消耗現(xiàn)場信任。虛擬鍵盤這個看似不起眼的小功能恰恰是讓上位機(jī)交付后能不能直接開機(jī)干活的關(guān)鍵一環(huán)。1.2 現(xiàn)成軟鍵盤方案的三個坑有的朋友會說Windows不是自帶屏幕鍵盤嗎直接調(diào)不就行了這個方案聽起來節(jié)省成本實際用起來有三個繞不開的坑。第一個是界面風(fēng)格問題系統(tǒng)軟鍵盤的外殼、配色、字體跟LabVIEW做的界面完全是兩個世界的產(chǎn)物客戶看第一眼就會覺得這不是一套系統(tǒng)專業(yè)度大打折扣。第二個坑是可控性差。系統(tǒng)軟鍵盤的布局、按鍵大小、數(shù)字鍵盤是否常駐、中文輸入法如何切換通通不受程序控制。你真想限制操作員只能輸入數(shù)字或者強(qiáng)制使用特定數(shù)值范圍系統(tǒng)軟鍵盤完全配合不了。第三個坑更隱蔽——許多工廠的工控機(jī)是特定定制鏡像或精簡版Windows系統(tǒng)軟鍵盤可能被策略限制部署到現(xiàn)場才發(fā)現(xiàn)在別的機(jī)器上能彈出來的鍵盤這臺機(jī)器上怎么都打不開或者中文輸入法缺失求助IT又是一輪漫長的扯皮。與其賭現(xiàn)場環(huán)境不如把鍵盤邏輯完全放進(jìn)LabVIEW程序里。1.3 一套自繪虛擬鍵盤源程序的價值點(diǎn)我自己最初決定寫這套中英文虛擬鍵盤源程序目標(biāo)其實很樸素。第一在任何現(xiàn)場都能穩(wěn)定彈出來不受系統(tǒng)版本、精簡鏡像影響。第二界面風(fēng)格跟主程序完全統(tǒng)一尺寸、配色、字體都能調(diào)。第三中英文輸入都能搞定中文不能只靠調(diào)用外部輸入法。第四能和主程序業(yè)務(wù)邏輯打通比如輸完數(shù)字按回車就觸發(fā)查詢這類事件在虛擬鍵盤內(nèi)部閉環(huán)處理掉。后來在實際項目里又驗證出兩個額外收益。一是復(fù)用性鍵盤做成一個獨(dú)立子VI后多個項目之間互相拷貝只改字典和布局就能用。二是可維護(hù)性很多需求方會在驗收前幾天突然提能不能加個中文輸入如果鍵盤邏輯分散在主程序各處這種改動會非常痛苦而集中在一個源程序模塊里修改路徑很短。這也是我堅持自繪而不是臨時拼湊的核心理由。2. 方案選型自繪虛擬鍵盤的開發(fā)路線拆解2.1 三條主流實現(xiàn)路線對比動手前我其實比較過三條路線這里直接列出對比結(jié)論。實現(xiàn)路線實現(xiàn)成本中英文支持定制化能力部署與兼容性維護(hù)成本調(diào)用系統(tǒng)屏幕鍵盤極低依賴系統(tǒng)輸入法幾乎不可定制精簡鏡像可能缺組件無源程序可控第三方ActiveX軟鍵盤控件中等視控件而定有限需要注冊組件升級易出問題依賴廠商維護(hù)純LabVIEW原生控件自繪較高完全自主實現(xiàn)完全可控打包簡單運(yùn)行時隨程序下發(fā)源碼在手上隨時改表格里第三條路線前期投入最大但它換來的是整個鍵盤模塊完全透明?,F(xiàn)場出任何問題打開LabVIEW就能改、能查、能重現(xiàn)而不是面對一個黑盒控件干瞪眼。工控項目里最怕的就是軟件在客戶那里出問題而你無法定位原生自繪恰恰把這種風(fēng)險壓到最低。2.2 為什么原生控件自繪更符合工控場景工控上位機(jī)有一個區(qū)別于普通Windows應(yīng)用的特點(diǎn)運(yùn)行環(huán)境不可控程度高。同樣是Win10有的現(xiàn)場是普通辦公版有的是各類定制精簡鏡像第三方ActiveX控件在打包后往現(xiàn)場一裝經(jīng)常出現(xiàn)注冊表項缺失、運(yùn)行庫沒裝、控件未授權(quán)等一串連鎖反應(yīng)。系統(tǒng)軟鍵盤更不用說連在不在都取決于鏡像策略。原生控件則沒這個問題——它只是普通LabVIEW前面板控件隨VI一起打進(jìn)安裝包不需要額外注冊任何組件。另外LabVIEW原生控件的風(fēng)格可以和主程序用同一套主題色、字體大小和按鈕形狀。好的HMI界面之所以讓操作員覺得高級一個重要原因是視覺語言統(tǒng)一。界面上一堆混合風(fēng)格的控件跟Word里混了三種字體一個道理。原生自繪能直接把這層統(tǒng)一感做出來。2.3 整體架構(gòu)與數(shù)據(jù)流設(shè)計這套虛擬鍵盤源程序的架構(gòu)我拆成三層。界面層是前面板上一堆布爾按鈕負(fù)責(zé)呈現(xiàn)和接收點(diǎn)擊這一層只管哪些鍵被按下映射層是按鍵識別與狀態(tài)管理邏輯負(fù)責(zé)把按鈕點(diǎn)擊翻譯成字符或者功能命令這一層是鍵盤的靈魂所在中英文切換、Shift狀態(tài)、拼音組合都在這里完成交互層負(fù)責(zé)把結(jié)果送到目標(biāo)輸入控件并處理回車通知。數(shù)據(jù)流上一次完整的按鍵操作是這樣的操作員在觸摸屏按下字母鍵該按鈕的值變更事件觸發(fā)事件結(jié)構(gòu)收到控件引用和當(dāng)前值映射層根據(jù)標(biāo)簽文本判斷按的是哪一個鍵結(jié)合當(dāng)前處于英文、拼音還是數(shù)字模式得出本次要輸出的內(nèi)容如果內(nèi)容是需要上屏的字符就直接寫入當(dāng)前目標(biāo)輸入控件然后把焦點(diǎn)切回目標(biāo)控件如果是回車、退格這類功能鍵則執(zhí)行相應(yīng)的通知或刪除操作。整體數(shù)據(jù)流單向、清晰出問題時順著鏈路查就行不會出現(xiàn)這個字符到底是誰寫進(jìn)去的這種懸案。3. 核心實現(xiàn)細(xì)節(jié)按鍵識別、中英文切換與焦點(diǎn)管理3.1 用控件標(biāo)簽識別按鍵避免100個事件分支很多第一次寫虛擬鍵盤的朋友第一反應(yīng)是在事件結(jié)構(gòu)里給每一個按鈕單獨(dú)建一個分支100個按鍵就是100個分支。這種做法不是說不行但維護(hù)起來極其痛苦想改一個字的顯示標(biāo)簽要動一堆地方。我的做法是只建三五個分支用控件標(biāo)簽文本識別這一招把按鍵區(qū)分開。具體來說在前面板上每個按鍵控件的標(biāo)簽直接設(shè)為它代表的字符比如字母A鍵標(biāo)簽就叫AShift鍵標(biāo)簽就叫Shift。在事件結(jié)構(gòu)中把這100個按鍵的值變更事件全部綁定到同一個事件分支事件數(shù)據(jù)里的控件引用就是被點(diǎn)擊的那個鍵。通過一個屬性節(jié)點(diǎn)讀取這個引用的標(biāo)簽文本再用條件結(jié)構(gòu)Case根據(jù)標(biāo)簽文本決定分支邏輯。這里把處理邏輯用文字概括一下事件分支(多個按鍵值變更): 控件引用 - 屬性節(jié)點(diǎn)讀出標(biāo)簽文本 switch(標(biāo)簽文本): case A..Z: 輸出字母 case 0..9: 輸出數(shù)字 case Shift: 切換Shift狀態(tài) case Backspace: 刪除最后一個字符 case Enter: 觸發(fā)完成通知 default: 其他字符鍵同樣輸出用這種結(jié)構(gòu)新增一個字符鍵只需要在前面板放一個按鈕、把標(biāo)簽改成對應(yīng)字符程序框圖一行不用動擴(kuò)展性比逐鍵建分支好太多。關(guān)鍵是LabVIEW的控件引用機(jī)制讓這件事變得非常簡單事件結(jié)構(gòu)中拿到的不是字符串而是控件對象的引用讀寫它的標(biāo)簽、值、焦點(diǎn)等屬性都暢通無阻。3.2 中文拼音輸入與候選字機(jī)制的實現(xiàn)這套源程序里中文輸入采用拼音加候選字方案不依賴操作系統(tǒng)任何輸入法程序?;舅悸肥钱?dāng)鍵盤切換到中文模式后字母鍵不再直接上屏而是先進(jìn)入一個拼音緩沖區(qū)緩沖區(qū)里拼出一個完整拼音后程序到內(nèi)置字典里檢索出對應(yīng)的候選漢字顯示在候選字列表控件里操作員點(diǎn)擊候選字這個字才寫入目標(biāo)輸入控件。實現(xiàn)上字典通常用一個二維字符串?dāng)?shù)組常量來表達(dá)第一列是拼音第二列是逗號分隔的漢字候選比如zhong,中,鐘,種,眾,重這樣的結(jié)構(gòu)。檢索時把拼音緩沖區(qū)內(nèi)容和字典第一列做字符串匹配命中的一行就拆成候選列表顯示。這個字典可以按項目需要增補(bǔ)比如某工廠經(jīng)常要輸入產(chǎn)品批次用字、人員姓名的生僻字直接往數(shù)組里加行就行不用改任何程序結(jié)構(gòu)。這里有個細(xì)節(jié)值得多說一句在設(shè)計拼音檢索邏輯時最好支持完整拼音匹配而不是前綴匹配否則操作員輸入帶聲調(diào)的數(shù)字或者拼音還沒輸完就急著看候選很容易造成誤判。我在實際項目里用的策略是完整拼音才匹配加候選列表動態(tài)刷新屏幕下方還有一個拼音緩沖區(qū)顯示框讓操作員隨時知道當(dāng)前拼到了哪一步。中文輸入過程的體驗順不順很大程度上看這個反饋做得到不到位。3.3 焦點(diǎn)控制虛擬鍵盤不搶焦點(diǎn)的完整做法虛擬鍵盤最容易翻車的地方是真機(jī)一碰就暴露的焦點(diǎn)問題。觸摸屏操作沒有鼠標(biāo)光標(biāo)只有一個當(dāng)前活動控件的概念。正常情況下操作員先點(diǎn)擊文本輸入框文本框獲得鍵盤焦點(diǎn)此時實體鍵盤或掃碼槍輸入的字符會落在文本框里。問題來了一旦操作員接著點(diǎn)擊屏幕上的虛擬鍵盤按鍵這個鍵盤按鈕本身變成了活動控件鍵盤焦點(diǎn)從文本框跑到了虛擬鍵盤按鈕上之后再點(diǎn)其他虛擬鍵輸出的字符就不知道跑哪去了。解決辦法的核心是焦點(diǎn)強(qiáng)制回收。虛擬鍵盤每次處理完一個按鍵都要立刻把鍵盤焦點(diǎn)寫回當(dāng)前目標(biāo)輸入控件。在程序框圖上就是保存一份目標(biāo)控件的引用處理完字符后通過屬性節(jié)點(diǎn)把該控件的Key Focus有的版本里叫鍵盤焦點(diǎn)設(shè)為True。這一步必須放在虛擬鍵盤按鈕事件分支的同一次執(zhí)行中完成不能留著下個循環(huán)再做否則操作員會肉眼可見地看到焦點(diǎn)閃了一下又跳走。另外還有一個經(jīng)驗鍵盤子VI最好作為普通子VI嵌入到主程序前面板中不要讓鍵盤彈成獨(dú)立頂層窗口。原因很簡單跨VI操作別的程序前面板控件的焦點(diǎn)在LabVIEW里有時會受到限制或需要額外引用處理而嵌入到同一前面板后所有控件引用都是同一VI下的正常關(guān)系焦點(diǎn)回收邏輯最穩(wěn)。3.4 回車觸發(fā)業(yè)務(wù)邏輯的實現(xiàn)方式工控界面上的輸入框經(jīng)常講究輸完按回車立即執(zhí)行下一步。比如掃碼槍掃完條碼自動回車程序馬上查詢數(shù)據(jù)庫操作員在鍵盤上輸完工單號按回車界面直接跳轉(zhuǎn)。很多人直接掛目標(biāo)控件的值變更事件結(jié)果發(fā)現(xiàn)每敲一個字符界面就反應(yīng)一次輸入還沒結(jié)束邏輯已經(jīng)跑了好幾遍操作體驗一塌糊涂。正確做法是這樣目標(biāo)輸入控件在生產(chǎn)運(yùn)行期間只做純文本接收不觸發(fā)業(yè)務(wù)邏輯虛擬鍵盤上的回車鍵被按下時不是簡單把回車字符追加進(jìn)文本框而是通過用戶事件或者消息隊列向主程序發(fā)送輸入完成信號主程序收到信號后才從目標(biāo)控件讀取當(dāng)前值執(zhí)行查詢、校驗或跳轉(zhuǎn)。這樣設(shè)計還有一個額外好處虛擬鍵盤、實體鍵盤、掃碼槍三種輸入路徑可用同一把回車邏輯。掃碼槍以USB鍵盤模式輸出時掃完碼自動補(bǔ)一個回車這個回車天然觸發(fā)輸入完成信號數(shù)據(jù)和鍵盤輸入統(tǒng)一走同一條處理鏈。這套一致性在MES掃碼綁定場景下特別值錢鍵盤和掃碼槍兩條輸入鏈路不用寫兩套業(yè)務(wù)代碼。4. 實操過程完整搭出一套中英文虛擬鍵盤4.1 前面板布局與按鈕機(jī)械動作選擇動手搭之前先規(guī)劃好按鍵布局。標(biāo)準(zhǔn)QWERTY三行字母區(qū)、一個數(shù)字符號區(qū)、一排功能鍵區(qū)這是大多數(shù)操作員最熟悉的排布不要為了省空間搞另類排列。觸摸屏對按鍵尺寸有硬性要求我習(xí)慣把字母鍵做成40像素以上對應(yīng)約10到12毫米物理尺寸間距至少2像素戴手套操作也不容易誤觸功能鍵可以用稍小尺寸但至少也要35像素。整體放在屏幕底部三分之一的區(qū)間避免遮擋主界面的數(shù)據(jù)展示區(qū)。每個按鍵控件的機(jī)械動作建議統(tǒng)一設(shè)為Latch類型按下觸發(fā)、讀取后自動復(fù)位。這類鎖定式機(jī)械動作的程序邏輯很簡單每次按下產(chǎn)生一次True事件結(jié)構(gòu)讀取并處理完后按鈕自動復(fù)位天然避免了長按重復(fù)觸發(fā)。如果用瞬時動作操作員手指一直按著屏幕值會持續(xù)保持True不小心就觸發(fā)N次邏輯調(diào)起來很惱火。視覺上功能鍵用不同底色區(qū)分會有幫助目前我的習(xí)慣是Shift用深灰、Backspace用紅、Enter用綠、中英文切換用藍(lán)其余字母數(shù)字鍵用淺灰布局邏輯一眼掃過去就很清楚。4.2 程序框圖的關(guān)鍵邏輯與狀態(tài)管理程序框圖主體是一個While循環(huán)包著事件結(jié)構(gòu)事件結(jié)構(gòu)里維護(hù)幾個核心狀態(tài)當(dāng)前模式英文、拼音、數(shù)字、Shift狀態(tài)、Caps狀態(tài)、拼音緩沖區(qū)字符串。這些狀態(tài)用移位寄存器保存每處理一次按鍵后更新狀態(tài)再傳給下一輪事件。字符鍵的處理邏輯分四種情況。模式是英文時把標(biāo)簽文本按Shift和Caps狀態(tài)做大小寫轉(zhuǎn)換后寫入目標(biāo)控件模式是數(shù)字時只允許數(shù)字鍵輸出模式是拼音時字符進(jìn)入拼音緩沖區(qū)并刷新候選字列表不直接上屏拼音候選字被選定時把選中的漢字拼接進(jìn)目標(biāo)文本框同時清空拼音緩沖區(qū)。功能鍵處理相對獨(dú)立Backspace從目標(biāo)控件文本末尾刪一個字符Enter發(fā)送用戶事件觸發(fā)輸入完成Shift和Caps只改狀態(tài)不產(chǎn)生字符輸出。這里提醒一個新手容易漏的點(diǎn)事件結(jié)構(gòu)里的多個按鍵共享一個分支時注意事件數(shù)據(jù)里還要判斷觸發(fā)事件的是哪一個引用。尤其是在綁定動態(tài)事件時如果不加區(qū)分就拿引用去讀標(biāo)簽文本后面Case結(jié)構(gòu)會亂。建議在事件分支開始處就讀取引用并轉(zhuǎn)成局部變量后面各處統(tǒng)一使用同一個引用保證一致性。4.3 子VI封裝、數(shù)據(jù)交互與主程序?qū)渔I盤做完后以子VI形式供主程序調(diào)用。子VI對外暴露的接口我固定為三組目標(biāo)控件引用輸入、當(dāng)前模式輸入輸出、用戶事件輸出輸出。主程序里每個需要輸入的可編輯控件都綁定一個鼠標(biāo)按下或者鍵盤焦點(diǎn)事件在事件處理里把該控件的引用傳給鍵盤子VI的輸入引腳。這樣操作員點(diǎn)哪個輸入框虛擬鍵盤就自動知道往哪個框里送字符不需要額外做選中目標(biāo)的操作。數(shù)據(jù)交互方式我推薦用戶事件加隊列的組合。用戶事件用來通知輸入完成這類異步業(yè)務(wù)信號隊列用來傳遞字符串消息主程序在其他循環(huán)里消費(fèi)。如果項目規(guī)模不大也可以簡化成鍵盤子VI輸出一個字符串控件主程序輪詢字符串控件取值后清空。不過輪詢方案多多少少有點(diǎn)浪費(fèi)CPU而且處理不及時我建議能上事件就上事件。如果你用的是JKI狀態(tài)機(jī)之類的框架虛擬鍵盤的輸出消息還可以直接轉(zhuǎn)成消息幀塞進(jìn)狀態(tài)機(jī)隊列里實現(xiàn)主界面邏輯和鍵盤輸入模塊的徹底解耦。我有一個項目就是這么干的鍵盤子VI完全不知道主程序在做什么它只負(fù)責(zé)把人按的鍵翻譯成消息主狀態(tài)機(jī)收到消息后再決定跳轉(zhuǎn)、校驗還是落庫維護(hù)起來非常清爽。4.4 與掃碼槍等外部鍵盤輸入的統(tǒng)一處理前面提到過很多掃碼槍工作在USB鍵盤模式相當(dāng)于一個只會敲字符串的實體鍵盤插入電腦后不需要裝驅(qū)動焦點(diǎn)在哪個文本框條碼就進(jìn)哪個框。這種設(shè)計恰恰給了我們一個啟發(fā)虛擬鍵盤本質(zhì)上也是輸入設(shè)備它的輸出路徑跟掃碼槍沒有本質(zhì)區(qū)別都是往當(dāng)前焦點(diǎn)控件里塞字符。所以我在主程序中并不區(qū)分字符是從虛擬鍵盤來的還是掃碼槍來的統(tǒng)一目標(biāo)控件值變更、統(tǒng)一回車觸發(fā)邏輯數(shù)據(jù)源無關(guān)性讓業(yè)務(wù)層不用寫一堆條件判斷。唯一需要留意的是掃碼槍的字符輸入速度很快一整個條碼在幾十毫秒內(nèi)全部灌進(jìn)文本框如果目標(biāo)控件的事件處理里做了重量級操作比如查數(shù)據(jù)庫就會把輸入卡在半路。做法是把數(shù)據(jù)接收和業(yè)務(wù)處理放在不同循環(huán)里接收循環(huán)只管把值收進(jìn)來放進(jìn)隊列處理循環(huán)再慢慢消費(fèi)兩者速率天然解耦。虛擬鍵盤手動輸入雖然慢但在同一套架構(gòu)下也享受到了這個好處。5. 常見問題與排查技巧實錄5.1 點(diǎn)擊按鍵后目標(biāo)框的焦點(diǎn)被搶走這是虛擬鍵盤項目里出現(xiàn)頻率最高的問題現(xiàn)象是操作員點(diǎn)一下虛擬鍵盤按鈕輸入框的光標(biāo)就不見了后面的字符要么沒反應(yīng)要么跑進(jìn)奇怪的地方。排查要點(diǎn)是把導(dǎo)致焦點(diǎn)變化的每一個事件都過一遍。首先確認(rèn)點(diǎn)擊虛擬鍵后目標(biāo)輸入控件是否被重新設(shè)置了焦點(diǎn)其次檢查目標(biāo)控件的屬性里有沒有禁用或者只讀開關(guān)誤開導(dǎo)致它根本拿不到焦點(diǎn)最后檢查鍵盤按鈕的機(jī)械動作會不會造成值在多個循環(huán)間閃爍因為焦點(diǎn)切換跟控件狀態(tài)變化有關(guān)。如果焦點(diǎn)設(shè)置了但焦點(diǎn)還是丟多半是鍵盤子VI被當(dāng)成獨(dú)立頂層窗口彈出跨VI焦點(diǎn)控制受限。把鍵盤改成嵌入主程序前面板后這個問題基本能解決。5.2 中文輸出亂碼與字體顯示異常中文亂碼分兩種情況處理。第一種是真正的編碼錯亂出現(xiàn)原因是LabVIEW字符串在不同機(jī)器上的本地代碼頁不一致比如程序在中文系統(tǒng)開發(fā)部署到英文系統(tǒng)后中文字符串變成問號。解決思路是在涉及文件的場景把字符串統(tǒng)一轉(zhuǎn)成UTF-8字節(jié)寫入讀取時反向轉(zhuǎn)換不要直接拿中文字符串當(dāng)落庫值在純界面顯示場景則要保證目標(biāo)文本框控件使用的字體支持中文常見做法是把字體設(shè)置為宋體或微軟雅黑。第二種是顯示問題字符沒亂但顯示成方框。這種不是編碼問題是字體不支持。設(shè)備部署機(jī)上如果沒有安裝對應(yīng)字體界面上的中文字符就會被替代字符占位。打包時把字體一并帶上或者干脆在設(shè)計時就指定系統(tǒng)自帶且支持中文的字體能省去不少現(xiàn)場救火的時間。5.3 觸摸屏上按鍵手感差、誤觸多觸摸屏操作和鼠標(biāo)點(diǎn)擊不一樣沒有懸停狀態(tài)也沒有精確的光標(biāo)。操作員如果戴手套手指接觸面積大40像素以下的按鍵非常容易誤觸相鄰鍵。經(jīng)驗值是鍵間距至少2到4像素整鍵尺寸至少40像素如果屏是10.1寸以下的小屏寧可壓縮布局行數(shù)也不能無限縮小按鍵。另外我遇到過一種典型的誤觸按鍵值在觸摸屏的電容感應(yīng)上產(chǎn)生抖動一次點(diǎn)擊被事件結(jié)構(gòu)抓到兩次True導(dǎo)致一個字符輸出兩遍。排查時在事件分支的True處理里加一個簡單的時間過濾比如連續(xù)兩次按鍵間隔小于100毫秒則忽略基本能壓掉這類問題。要記得這個過濾只防抖不要擋住操作員故意快速連輸?shù)那闆r所以閾值不要設(shè)得太大。5.4 打包部署后鍵盤顯示異常開發(fā)環(huán)境里一切正常打包安裝到現(xiàn)場機(jī)器后鍵盤錯位、字體變化、界面縮放異常這類問題多半和高DPI、字體缺失有關(guān)。工控現(xiàn)場常見的觸摸屏一體機(jī)分辨率不低但縮放設(shè)置五花八門LabVIEW前面板如果沒做DPI感知設(shè)置高分屏下會模糊一片或者控件錯位。打包前建議在項目屬性里確認(rèn)前面板縮放模式在目標(biāo)機(jī)器上實測不同分辨率下的顯示效果優(yōu)先保證最常使用的那個分辨率表現(xiàn)良好。還有一個容易踩的坑有些工控機(jī)安裝的是LabVIEW運(yùn)行引擎而不是完整開發(fā)環(huán)境如果鍵盤VI用到了某個只在開發(fā)環(huán)境默認(rèn)路徑下的字體或資源打包時沒設(shè)置好運(yùn)行環(huán)境里就會找不到。打包前用安裝程序向?qū)О堰\(yùn)行引擎一并帶上再把項目用到的字體手動添加進(jìn)來能避免大部分這類問題。5.5 幾個項目用過之后的整體體會這套虛擬鍵盤源程序我在實際交付里反復(fù)用了幾輪最大的體會是虛擬鍵盤不是一個錦上添花的玩具功能而是直接影響設(shè)備能否通過驗收的基礎(chǔ)設(shè)施??蛻舨粫驗樗嗉臃值坏┲形妮斎敕ㄕ{(diào)不出來、焦點(diǎn)亂跳、回車不觸發(fā)減分是實打?qū)嵉摹K越ㄗh大家在項目計劃里就把鍵盤模塊當(dāng)成一等公民排期而不是最后一天臨時塞進(jìn)去的東西。我還總結(jié)出一個實用習(xí)慣鍵盤子VI做成通用模板后每個新項目先復(fù)制一份再按項目需求改三樣?xùn)|西——拼音字典加項目專用詞匯、功能鍵布局、配色主題。主界面業(yè)務(wù)邏輯完全不需要動。這樣一套框架沉淀下來后面再遇到客戶臨時要加中文輸入這類需求改動時間基本能控制在半天以內(nèi)現(xiàn)場應(yīng)對起來會從容很多。最后再提一個細(xì)節(jié)記得在鍵盤上給輸入完成留一個顯眼的確認(rèn)鍵并且讓這個鍵在觸摸屏上足夠大很多操作員輸完數(shù)據(jù)后習(xí)慣性地找綠色確認(rèn)按鈕這個位置做不好前面所有輸入體驗都白搭。