tr字符串的梗
工作问题总结
声明:应用程序代码为前人所写,仅仅只是维护代码,暂且不论代码风格瑕疵。
结论:
使用tr“包”起来的字符串,可能会被翻译为不同的语言,此时,应用程序在不同语言环境下可能会表现BUG。
1.问题及源码追溯过程
1 // 应用程序调用函数1 2 void WinHelpManual::openFunction(QString func) 3 { 4 QWebPage *webPage = m_view_list.page(); 5 QWebFrame *webFrame = webPage->frameAt(QPoint(0, 0)); 6 QWebElement webElement = webFrame->documentElement(); 7 webElement.evaluateJavaScript(func); 8 } 9 // 应用程序调用函数2 10 void WinHelpManual::openUrl() 11 { 12 QString Html = m_view_list.selectedHtml(); 13 QString strUrlExp = "outline_[0-9]*.htm"; 14 QRegExp urlRegExp(strUrlExp, Qt::CaseSensitive); 15 if (urlRegExp.indexIn(Html) != -1) 16 { 17 QString strWebUrl = urlRegExp.cap(0); // 匹配到的url 18 m_view_contents.setUrl(QUrl(m_path + strWebUrl)); 19 } 20 } 21 // 应用程序调用函数3 22 bool WinHelpManual::event(QEvent *event) 23 { 24 if (event->type() == QEvent::KeyRelease) 25 { 26 QKeyEvent *ke = static_cast<QKeyEvent*> (event); 27 if (ke->modifiers() == PANEL_MODIFIER) 28 { 29 static int Ekey; 30 if (ke->key() == PANEL_BAR || ke->key() == PANEL_WAVE || ke->key() == PANEL_NUMERIC || ke->key() == PANEL_VECTOR || \ 31 ke->key() == PANEL_MARK || ke->key() == PANEL_ITEM || ke->key() == PANEL_FORM || ke->key() == PANEL_USER || \ 32 ke->key() == PANEL_VOLTRANGE_CLOCKWISE || ke->key() == PANEL_VOLTRANGE_ANTICLOCKWISE || ke->key() == PANEL_VOLTRANGE_AUTO\ 33 || ke->key() == PANEL_CURRRANGE_CLOCKWISE || ke->key() == PANEL_CURRRANGE_ANTICLOCKWISE || ke->key() == PANEL_CURRANGE_AUTO\ 34 || ke->key() == PANEL_EXT || ke->key() == PANEL_ACCURATE || ke->key() == PANEL_UTILITY || ke->key() == PANEL_MEASURRE\ 35 || ke->key() == PANEL_OTHERS || ke->key() == PANEL_SOURCE || ke->key() == PANEL_FILE || ke->key() == PANEL_INFO \ 36 || ke->key() == PANEL_IMAGESAVE || ke->key() == PANEL_HOLD || ke->key() == PANEL_SINGLE || ke->key() == PANEL_STROE \ 37 || ke->key() == PANEL_INTEG || ke->key() == PANEL_LOCALLOCK) 38 { 39 openFunction(); 40 } 41 m_view_list.page()->findText("");//清除 42 switch (ke->key()) 43 { 44 case PANEL_ESC: 45 case PANEL_HELP: 46 hide(); 47 return true; 48 case PANEL_BAR: 49 { 50 Ekey = PANEL_BAR; 51 m_view_list.page()->findText(tr("Bar Graph Display(Bar)")); 52 } 53 break; 54 case PANEL_WAVE: 55 { 56 Ekey = PANEL_WAVE; 57 m_view_list.findText(tr("Waveform Display(WAVE)")); 58 } 59 break; 60 case PANEL_NUMERIC: 61 { 62 Ekey = PANEL_NUMERIC; 63 m_view_list.findText(tr("Numetic Data Display(NUMERIC)")); 64 } 65 break; 66 case PANEL_VECTOR: 67 Ekey = PANEL_VECTOR; 68 m_view_list.findText(tr("Vector Display(Vector)")); 69 break; 70 case PANEL_MARK: 71 { 72 switch (Ekey) 73 { 74 case PANEL_BAR: 75 m_view_list.findText(tr("Bar Display Mark (MARK)")); 76 break; 77 case PANEL_WAVE: 78 m_view_list.findText(tr("Waveform Display Mark(MARK)")); 79 break; 80 default: 81 break; 82 } 83 } 84 break; 85 case PANEL_ITEM: 86 { 87 switch (Ekey) 88 { 89 case PANEL_BAR: 90 m_view_list.findText(tr("Bar Display Item (ITEM)")); 91 break; 92 case PANEL_WAVE: 93 m_view_list.findText(tr("Waveform Display Item(ITEM)")); 94 break; 95 case PANEL_NUMERIC: 96 m_view_list.findText(tr("Numetic Display Item(ITEM)")); 97 break; 98 case PANEL_VECTOR: 99 m_view_list.findText(tr("Vector Display Item(ITEM)")); 100 break; 101 default: 102 break; 103 } 104 } 105 break; 106 case PANEL_FORM: 107 { 108 switch (Ekey) 109 { 110 case PANEL_BAR: 111 m_view_list.findText(tr("Bar Display Format(FORM)")); 112 break; 113 case PANEL_WAVE: 114 m_view_list.findText(tr("Waveform Display Format(FORM)")); 115 break; 116 case PANEL_NUMERIC: 117 m_view_list.findText(tr("Numetic Display Format(FORM)")); 118 break; 119 case PANEL_VECTOR: 120 m_view_list.findText(tr("Vector Display Format(FORM)")); 121 break; 122 default: 123 break; 124 } 125 } 126 break; 127 case PANEL_USER: 128 m_view_list.findText(tr("Numetic Data Display(NUMERIC)")); 129 break; 130 case PANEL_TAB: 131 if (m_view_contents.hasFocus()) 132 { 133 m_view_contents.setFocusPolicy(Qt::NoFocus); 134 m_view_list.setFocus(); 135 p_curWebView = &m_view_list; 136 repaint(); 137 } 138 else if (m_view_list.hasFocus()) 139 { 140 m_view_list.setFocusPolicy(Qt::NoFocus); 141 m_view_contents.setFocus(); 142 p_curWebView = &m_view_contents; 143 repaint(); 144 } 145 break; 146 case PANEL_VOLTRANGE_CLOCKWISE: 147 case PANEL_VOLTRANGE_ANTICLOCKWISE: 148 m_view_list.findText(tr("Voltage Range(RANGE UP/DOWN (V))")); 149 break; 150 case PANEL_VOLTRANGE_AUTO: 151 m_view_list.findText(tr("Auto Voltage Range(AUTO (V))")); 152 break; 153 case PANEL_CURRRANGE_CLOCKWISE: 154 case PANEL_CURRRANGE_ANTICLOCKWISE: 155 m_view_list.findText(tr("Current Range (RANGE UP/DOWN (A))")); 156 break; 157 case PANEL_CURRANGE_AUTO: 158 m_view_list.findText(tr("Auto Current Range(AUTO (A))")); 159 break; 160 case PANEL_EXT: 161 m_view_list.findText(tr("External Current Sensor Range (EXT SENSOR; option)")); 162 break; 163 case PANEL_ACCURATE: 164 m_view_list.findText(tr("Line Filter(LINE FILTER)")); 165 break; 166 case PANEL_UTILITY: 167 m_view_list.findText(tr("Utility (UTILITY)")); 168 break; 169 case PANEL_MEASURRE: 170 m_view_list.findText(tr("Computation(MEASURE)")); 171 break; 172 case PANEL_OTHERS: 173 m_view_list.findText(tr("Combination Display (COMBINE)")); 174 break; 175 case PANEL_SOURCE: 176 m_view_list.findText(tr("Measurement period(SYNC SOURCE)")); 177 break; 178 case PANEL_FILE: 179 m_view_list.findText(tr("File(File)")); 180 break; 181 case PANEL_INFO: 182 m_view_list.findText(tr("")); 183 break; 184 case PANEL_IMAGESAVE: 185 m_view_list.findText(tr("Screen capture function (Image )")); 186 break; 187 case PANEL_HOLD: 188 m_view_list.findText(tr("Holding Measured Values(HOLD)")); 189 break; 190 case PANEL_SINGLE: 191 m_view_list.findText(tr("Single Measurement(SINGLE)")); 192 break; 193 case PANEL_STROE: 194 m_view_list.findText(tr("Data Storage")); 195 break; 196 case PANEL_INTEG: 197 m_view_list.findText(tr("Integrated Power(Watt hours)")); 198 break; 199 case PANEL_LOCALLOCK: 200 m_view_list.findText(tr("Touch Unlock")); 201 break; 202 default: 203 return true; 204 } 205 openUrl(); 206 } 207 } 208 return QWidget::event(event); 209 } 210 // QWebView page() 接口源码 211 QWebPage *QWebView::page() const 212 { 213 if (!d->page) 214 { 215 QWebView *that = const_cast<QWebView *>(this); 216 that->setPage(new QWebPage(that)); 217 } 218 return d->page; 219 } 220 // QWebView findText() 接口源码 221 bool QWebView::findText(const QString &subString, QWebPage::FindFlags options) 222 { 223 if (d->page) 224 { 225 return d->page->findText(subString, options); 226 } 227 return false; 228 } 229 // QWebPage findText() 接口源码 230 bool QWebPage::findText(const QString &subString, FindFlags options) 231 { 232 return d->findText(subString, static_cast<QWebPageAdapter::FindFlag>(options.operator int())); 233 } 234 // QWebPagePrivate findText() 接口源码 235 bool QWebPageAdapter::findText(const QString& subString, FindFlag options) 236 { 237 ::WebCore::FindOptions webCoreFindOptions = 0; 238 239 if (!(options & FindCaseSensitively)) 240 { 241 webCoreFindOptions |= WebCore::CaseInsensitive; 242 } 243 244 if (options & FindBackward) 245 { 246 webCoreFindOptions |= WebCore::Backwards; 247 } 248 249 if (options & FindWrapsAroundDocument) 250 { 251 webCoreFindOptions |= WebCore::WrapAround; 252 } 253 254 if (options & FindAtWordBeginningsOnly) 255 { 256 webCoreFindOptions |= WebCore::AtWordStarts; 257 } 258 259 if (options & TreatMedialCapitalAsWordBeginning) 260 { 261 webCoreFindOptions |= WebCore::TreatMedialCapitalAsWordStart; 262 } 263 264 if (options & FindBeginsInSelection) 265 { 266 webCoreFindOptions |= WebCore::StartInSelection; 267 } 268 269 if (options & HighlightAllOccurrences) 270 { 271 if (subString.isEmpty()) 272 { 273 page->unmarkAllTextMatches(); 274 return true; 275 } 276 277 return page->markAllMatchesForText(subString, webCoreFindOptions, /*shouldHighlight*/ true, /*limit*/ 0); 278 } 279 280 if (subString.isEmpty()) 281 { 282 page->mainFrame()->selection()->clear(); 283 Frame* frame = page->mainFrame()->tree()->firstChild(); 284 while (frame) 285 { 286 frame->selection()->clear(); 287 frame = frame->tree()->traverseNextWithWrap(false); 288 } 289 } 290 291 return page->findString(subString, webCoreFindOptions); 292 } 293 // Page findString() 接口源码 294 bool Page::findString(const String& target, FindOptions options) 295 { 296 if (target.isEmpty() || !mainFrame()) 297 { 298 return false; 299 } 300 301 bool shouldWrap = options & WrapAround; 302 303 Frame* frame = focusController()->focusedOrMainFrame(); 304 Frame* startFrame = frame; 305 do 306 { 307 if (frame->editor().findString(target, (options & ~WrapAround) | StartInSelection)) 308 { 309 if (frame != startFrame) 310 { 311 startFrame->selection()->clear(); 312 } 313 314 focusController()->setFocusedFrame(frame); 315 return true; 316 } 317 frame = incrementFrame(frame, !(options & Backwards), shouldWrap); 318 } while (frame && frame != startFrame); 319 320 // Search contents of startFrame, on the other side of the selection that we did earlier. 321 // We cheat a bit and just research with wrap on 322 if (shouldWrap && !startFrame->selection()->isNone()) 323 { 324 bool found = startFrame->editor().findString(target, options | WrapAround | StartInSelection); 325 focusController()->setFocusedFrame(frame); 326 return found; 327 } 328 329 return false; 330 } 331 // Page mainFrame() 成员方法源码 332 Frame* mainFrame() const { return m_mainFrame.get(); } 333 // Editor findString() 成员方法源码 334 bool Editor::findString(const String& target, FindOptions options) 335 { 336 VisibleSelection selection = m_frame->selection()->selection(); 337 RefPtr<Range> resultRange = rangeOfString(target, selection.firstRange().get(), options); 338 if (!resultRange) 339 { 340 return false; 341 } 342 343 m_frame->selection()->setSelection(VisibleSelection(resultRange.get(), DOWNSTREAM)); 344 m_frame->selection()->revealSelection(); 345 return true; 346 }
2.问题原因
tr翻译后导致字符串查找失败。
如上实例,因为tr“包”起来的字符串被翻译为不同语言,但是每次与之比较匹配的字符串始终为英语版本。
所以,总出现匹配失败的异常,导致调试排除浪费很长时间,在此特别备录。
Good Good Study, Day Day Up.
顺序 选择 循环 总结