├── InputTool.pro ├── README.md ├── frminput.cpp ├── frminput.h ├── frminput.ui ├── frmmain.cpp ├── frmmain.h ├── frmmain.ui ├── frmnum.cpp ├── frmnum.h ├── frmnum.ui ├── main.cpp ├── py.db └── readme.txt /InputTool.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2014-08-15T14:34:50 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui sql 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = InputTool 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | frmmain.cpp \ 17 | frminput.cpp \ 18 | frmnum.cpp 19 | 20 | HEADERS += frmmain.h \ 21 | frminput.h \ 22 | frmnum.h 23 | 24 | FORMS += frmmain.ui \ 25 | frminput.ui \ 26 | frmnum.ui 27 | 28 | MOC_DIR = temp/moc 29 | RCC_DIR = temp/rcc 30 | UI_DIR = temp/ui 31 | OBJECTS_DIR = temp/obj 32 | DESTDIR = bin 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KeyboardLiuDianWu 2 | qt 实现的虚拟键盘。。。 3 | -------------------------------------------------------------------------------- /frminput.cpp: -------------------------------------------------------------------------------- 1 | #include "frminput.h" 2 | #include "ui_frminput.h" 3 | #include "qdesktopwidget.h" 4 | 5 | frmInput *frmInput::_instance = 0; 6 | frmInput::frmInput(QWidget *parent) : 7 | QWidget(parent), 8 | ui(new Ui::frmInput) 9 | { 10 | ui->setupUi(this); 11 | this->InitProperty(); 12 | this->InitForm(); 13 | this->ChangeStyle(); 14 | } 15 | 16 | frmInput::~frmInput() 17 | { 18 | delete ui; 19 | } 20 | 21 | void frmInput::Init(QString position, QString style, int btnFontSize, int labFontSize) 22 | { 23 | this->currentPosition = position; 24 | this->currentStyle = style; 25 | this->btnFontSize = btnFontSize; 26 | this->labFontSize = labFontSize; 27 | this->ChangeStyle(); 28 | this->ChangeFont(); 29 | } 30 | 31 | void frmInput::mouseMoveEvent(QMouseEvent *e) 32 | { 33 | if (mousePressed && (e->buttons() && Qt::LeftButton)) { 34 | this->move(e->globalPos() - mousePoint); 35 | e->accept(); 36 | } 37 | } 38 | 39 | void frmInput::mousePressEvent(QMouseEvent *e) 40 | { 41 | if (e->button() == Qt::LeftButton) { 42 | mousePressed = true; 43 | mousePoint = e->globalPos() - this->pos(); 44 | e->accept(); 45 | } 46 | } 47 | 48 | void frmInput::mouseReleaseEvent(QMouseEvent *) 49 | { 50 | mousePressed = false; 51 | } 52 | 53 | void frmInput::InitForm() 54 | { 55 | this->mousePressed = false; 56 | this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); 57 | 58 | QDesktopWidget w; 59 | deskWidth = w.availableGeometry().width(); 60 | deskHeight = w.availableGeometry().height(); 61 | frmWidth = this->width(); 62 | frmHeight = this->height(); 63 | 64 | QSqlDatabase DbConn; 65 | DbConn = QSqlDatabase::addDatabase("QSQLITE", "py"); 66 | DbConn.setDatabaseName(qApp->applicationDirPath() + "/py.db"); 67 | DbConn.open(); 68 | 69 | isFirst = true; 70 | isPress = false; 71 | timerPress = new QTimer(this); 72 | connect(timerPress, SIGNAL(timeout()), this, SLOT(reClicked())); 73 | 74 | currentWidget = 0; 75 | currentLineEdit = 0; 76 | currentTextEdit = 0; 77 | currentPlain = 0; 78 | currentBrowser = 0; 79 | currentEditType = ""; 80 | 81 | //如果需要更改输入法面板的显示位置,改变currentPosition这个变量即可 82 | //control--显示在对应输入框的正下方 bottom--填充显示在底部 center--窗体居中显示 83 | currentPosition = ""; 84 | 85 | //如果需要更改输入法面板的样式,改变currentStyle这个变量即可 86 | //blue--淡蓝色 dev--dev风格 black--黑色 brown--灰黑色 lightgray--浅灰色 darkgray--深灰色 gray--灰色 silvery--银色 87 | currentStyle = ""; 88 | 89 | //输入法面板字体大小,如果需要更改面板字体大小,该这里即可 90 | btnFontSize = 10; 91 | labFontSize = 10; 92 | 93 | //如果需要更改输入法初始模式,改变currentType这个变量即可 94 | //min--小写模式 max--大写模式 chinese--中文模式 95 | currentType = "min"; 96 | changeType(currentType); 97 | 98 | QList btn = this->findChildren(); 99 | foreach (QPushButton * b, btn) { 100 | connect(b, SIGNAL(clicked()), this, SLOT(btn_clicked())); 101 | } 102 | 103 | //绑定全局改变焦点信号槽 104 | connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)), 105 | this, SLOT(focusChanged(QWidget *, QWidget *))); 106 | //绑定按键事件过滤器 107 | qApp->installEventFilter(this); 108 | } 109 | 110 | void frmInput::InitProperty() 111 | { 112 | ui->btnOther1->setProperty("btnOther", true); 113 | ui->btnOther2->setProperty("btnOther", true); 114 | ui->btnOther3->setProperty("btnOther", true); 115 | ui->btnOther4->setProperty("btnOther", true); 116 | ui->btnOther5->setProperty("btnOther", true); 117 | ui->btnOther6->setProperty("btnOther", true); 118 | ui->btnOther7->setProperty("btnOther", true); 119 | ui->btnOther8->setProperty("btnOther", true); 120 | ui->btnOther9->setProperty("btnOther", true); 121 | ui->btnOther10->setProperty("btnOther", true); 122 | ui->btnOther11->setProperty("btnOther", true); 123 | ui->btnOther12->setProperty("btnOther", true); 124 | ui->btnOther13->setProperty("btnOther", true); 125 | ui->btnOther14->setProperty("btnOther", true); 126 | ui->btnOther15->setProperty("btnOther", true); 127 | ui->btnOther16->setProperty("btnOther", true); 128 | ui->btnOther17->setProperty("btnOther", true); 129 | ui->btnOther18->setProperty("btnOther", true); 130 | ui->btnOther19->setProperty("btnOther", true); 131 | ui->btnOther20->setProperty("btnOther", true); 132 | ui->btnOther21->setProperty("btnOther", true); 133 | 134 | ui->btnDot->setProperty("btnOther", true); 135 | ui->btnSpace->setProperty("btnOther", true); 136 | ui->btnEnter->setProperty("btnOther", true); 137 | ui->btnDelete->setProperty("btnOther", true); 138 | 139 | ui->btn0->setProperty("btnNum", true); 140 | ui->btn1->setProperty("btnNum", true); 141 | ui->btn2->setProperty("btnNum", true); 142 | ui->btn3->setProperty("btnNum", true); 143 | ui->btn4->setProperty("btnNum", true); 144 | ui->btn5->setProperty("btnNum", true); 145 | ui->btn6->setProperty("btnNum", true); 146 | ui->btn7->setProperty("btnNum", true); 147 | ui->btn8->setProperty("btnNum", true); 148 | ui->btn9->setProperty("btnNum", true); 149 | ui->btn00->setProperty("btnNum", true); 150 | 151 | ui->btna->setProperty("btnLetter", true); 152 | ui->btnb->setProperty("btnLetter", true); 153 | ui->btnc->setProperty("btnLetter", true); 154 | ui->btnd->setProperty("btnLetter", true); 155 | ui->btne->setProperty("btnLetter", true); 156 | ui->btnf->setProperty("btnLetter", true); 157 | ui->btng->setProperty("btnLetter", true); 158 | ui->btnh->setProperty("btnLetter", true); 159 | ui->btni->setProperty("btnLetter", true); 160 | ui->btnj->setProperty("btnLetter", true); 161 | ui->btnk->setProperty("btnLetter", true); 162 | ui->btnl->setProperty("btnLetter", true); 163 | ui->btnm->setProperty("btnLetter", true); 164 | ui->btnn->setProperty("btnLetter", true); 165 | ui->btno->setProperty("btnLetter", true); 166 | ui->btnp->setProperty("btnLetter", true); 167 | ui->btnq->setProperty("btnLetter", true); 168 | ui->btnr->setProperty("btnLetter", true); 169 | ui->btns->setProperty("btnLetter", true); 170 | ui->btnt->setProperty("btnLetter", true); 171 | ui->btnu->setProperty("btnLetter", true); 172 | ui->btnv->setProperty("btnLetter", true); 173 | ui->btnw->setProperty("btnLetter", true); 174 | ui->btnx->setProperty("btnLetter", true); 175 | ui->btny->setProperty("btnLetter", true); 176 | ui->btnz->setProperty("btnLetter", true); 177 | 178 | labCh.append(ui->labCh0); 179 | labCh.append(ui->labCh1); 180 | labCh.append(ui->labCh2); 181 | labCh.append(ui->labCh3); 182 | labCh.append(ui->labCh4); 183 | labCh.append(ui->labCh5); 184 | labCh.append(ui->labCh6); 185 | labCh.append(ui->labCh7); 186 | labCh.append(ui->labCh8); 187 | labCh.append(ui->labCh9); 188 | for (int i = 0; i < 10; i++) { 189 | labCh[i]->installEventFilter(this); 190 | } 191 | } 192 | 193 | void frmInput::ShowPanel() 194 | { 195 | this->setVisible(true); 196 | int width = ui->btn0->width(); 197 | width = width > 60 ? width : 60; 198 | ui->btnPre->setMinimumWidth(width); 199 | ui->btnPre->setMaximumWidth(width); 200 | ui->btnNext->setMinimumWidth(width); 201 | ui->btnNext->setMaximumWidth(width); 202 | ui->btnClose->setMinimumWidth(width); 203 | ui->btnClose->setMaximumWidth(width); 204 | } 205 | 206 | //事件过滤器,用于识别鼠标单击汉字标签处获取对应汉字 207 | bool frmInput::eventFilter(QObject *obj, QEvent *event) 208 | { 209 | if (event->type() == QEvent::MouseButtonPress) { 210 | QMouseEvent *mouseEvent = static_cast(event); 211 | if (mouseEvent->button() == Qt::LeftButton) { 212 | if (obj == ui->labCh0) { 213 | setChinese(0); 214 | } else if (obj == ui->labCh1) { 215 | setChinese(1); 216 | } else if (obj == ui->labCh2) { 217 | setChinese(2); 218 | } else if (obj == ui->labCh3) { 219 | setChinese(3); 220 | } else if (obj == ui->labCh4) { 221 | setChinese(4); 222 | } else if (obj == ui->labCh5) { 223 | setChinese(5); 224 | } else if (obj == ui->labCh6) { 225 | setChinese(6); 226 | } else if (obj == ui->labCh7) { 227 | setChinese(7); 228 | } else if (obj == ui->labCh8) { 229 | setChinese(8); 230 | } else if (obj == ui->labCh9) { 231 | setChinese(9); 232 | } else if (currentEditType != "" && obj != ui->btnClose) { 233 | QString objName = obj->objectName(); 234 | if (!obj->property("noinput").toBool() && objName != "frmMainWindow" 235 | && objName != "frmInputWindow" && objName != "qt_edit_menu") { 236 | ShowPanel(); 237 | } 238 | } 239 | 240 | btnPress = (QPushButton *)obj; 241 | if (checkPress()) { 242 | isPress = true; 243 | timerPress->start(500); 244 | } 245 | return false; 246 | } 247 | } else if (event->type() == QEvent::MouseButtonRelease) { 248 | btnPress = (QPushButton *)obj; 249 | if (checkPress()) { 250 | isPress = false; 251 | timerPress->stop(); 252 | } 253 | return false; 254 | } else if (event->type() == QEvent::KeyPress) { 255 | //如果输入法窗体不可见,则不需要处理 256 | if (!isVisible()) { 257 | return QWidget::eventFilter(obj, event); 258 | } 259 | 260 | QKeyEvent *keyEvent = static_cast(event); 261 | //Shift切换输入法模式,esc键关闭输入法面板,空格取第一个汉字,退格键删除 262 | //中文模式下回车键取拼音,中文模式下当没有拼音时可以输入空格 263 | if (keyEvent->key() == Qt::Key_Space) { 264 | if (ui->labPY->text() != "") { 265 | setChinese(0); 266 | return true; 267 | } else { 268 | return false; 269 | } 270 | } else if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { 271 | insertValue(ui->labPY->text()); 272 | ui->labPY->setText(""); 273 | selectChinese(); 274 | return true; 275 | } else if (keyEvent->key() == Qt::Key_Shift) { 276 | ui->btnType->click(); 277 | return true; 278 | } else if (keyEvent->key() == Qt::Key_Escape) { 279 | ui->btnClose->click(); 280 | return true; 281 | } else if (keyEvent->key() == Qt::Key_Backspace) { 282 | ui->btnDelete->click(); 283 | return true; 284 | } else if (keyEvent->text() == "+" || keyEvent->text() == "=") { 285 | if (ui->labPY->text() != "") { 286 | ui->btnNext->click(); 287 | return true; 288 | } else { 289 | return false; 290 | } 291 | } else if (keyEvent->text() == "-" || keyEvent->text() == "_") { 292 | if (ui->labPY->text() != "") { 293 | ui->btnPre->click(); 294 | return true; 295 | } else { 296 | return false; 297 | } 298 | } else if (keyEvent->key() == Qt::Key_CapsLock) { 299 | if (currentType != "max") { 300 | currentType = "max"; 301 | } else { 302 | currentType = "min"; 303 | } 304 | changeType(currentType); 305 | return true; 306 | } else { 307 | if (currentEditType == "QWidget") { 308 | return false; 309 | } 310 | QString key; 311 | if (currentType == "chinese") { 312 | key = keyEvent->text(); 313 | } else if (currentType == "min") { 314 | key = keyEvent->text().toLower(); 315 | } else if (currentType == "max") { 316 | key = keyEvent->text().toUpper(); 317 | } 318 | QList btn = this->findChildren(); 319 | foreach (QPushButton * b, btn) { 320 | if (b->text() == key) { 321 | b->click(); 322 | return true; 323 | } 324 | } 325 | } 326 | return false; 327 | } 328 | return QWidget::eventFilter(obj, event); 329 | } 330 | 331 | bool frmInput::checkPress() 332 | { 333 | //只有属于输入法键盘的合法按钮才继续处理 334 | bool num_ok = btnPress->property("btnNum").toBool(); 335 | bool other_ok = btnPress->property("btnOther").toBool(); 336 | bool letter_ok = btnPress->property("btnLetter").toBool(); 337 | if (num_ok || other_ok || letter_ok) { 338 | return true; 339 | } 340 | return false; 341 | } 342 | 343 | void frmInput::reClicked() 344 | { 345 | if (isPress) { 346 | timerPress->setInterval(30); 347 | btnPress->click(); 348 | } 349 | } 350 | 351 | void frmInput::focusChanged(QWidget *oldWidget, QWidget *nowWidget) 352 | { 353 | //qDebug() << "oldWidget:" << oldWidget << " nowWidget:" << nowWidget; 354 | if (nowWidget != 0 && !this->isAncestorOf(nowWidget)) { 355 | //在Qt5和linux系统中(嵌入式linux除外),当输入法面板关闭时,焦点会变成无,然后焦点会再次移到焦点控件处 356 | //这样导致输入法面板的关闭按钮不起作用,关闭后马上有控件获取焦点又显示. 357 | //为此,增加判断,当焦点是从有对象转为无对象再转为有对象时不要显示. 358 | //这里又要多一个判断,万一首个窗体的第一个焦点就是落在可输入的对象中,则要过滤掉 359 | #ifndef __arm__ 360 | if (oldWidget == 0x0 && !isFirst) { 361 | QTimer::singleShot(0, this, SLOT(hide())); 362 | return; 363 | } 364 | #endif 365 | 366 | //如果对应属性noinput为真则不显示 367 | if (nowWidget->property("noinput").toBool()) { 368 | QTimer::singleShot(0, this, SLOT(hide())); 369 | return; 370 | } 371 | 372 | isFirst = false; 373 | if (nowWidget->inherits("QLineEdit")) { 374 | currentLineEdit = (QLineEdit *)nowWidget; 375 | currentEditType = "QLineEdit"; 376 | ShowPanel(); 377 | } else if (nowWidget->inherits("QTextEdit")) { 378 | currentTextEdit = (QTextEdit *)nowWidget; 379 | currentEditType = "QTextEdit"; 380 | ShowPanel(); 381 | } else if (nowWidget->inherits("QPlainTextEdit")) { 382 | currentPlain = (QPlainTextEdit *)nowWidget; 383 | currentEditType = "QPlainTextEdit"; 384 | ShowPanel(); 385 | } else if (nowWidget->inherits("QTextBrowser")) { 386 | currentBrowser = (QTextBrowser *)nowWidget; 387 | currentEditType = "QTextBrowser"; 388 | ShowPanel(); 389 | } else if (nowWidget->inherits("QComboBox")) { 390 | QComboBox *cbox = (QComboBox *)nowWidget; 391 | //只有当下拉选择框处于编辑模式才可以输入 392 | if (cbox->isEditable()) { 393 | currentLineEdit = cbox->lineEdit() ; 394 | currentEditType = "QLineEdit"; 395 | ShowPanel(); 396 | } 397 | } else if (nowWidget->inherits("QSpinBox") || 398 | nowWidget->inherits("QDoubleSpinBox") || 399 | nowWidget->inherits("QDateEdit") || 400 | nowWidget->inherits("QTimeEdit") || 401 | nowWidget->inherits("QDateTimeEdit")) { 402 | currentWidget = nowWidget; 403 | currentEditType = "QWidget"; 404 | ShowPanel(); 405 | } else { 406 | //需要将输入法切换到最初的原始状态--小写,同时将之前的对象指针置为零 407 | currentWidget = 0; 408 | currentLineEdit = 0; 409 | currentTextEdit = 0; 410 | currentPlain = 0; 411 | currentBrowser = 0; 412 | currentEditType = ""; 413 | currentType = "min"; 414 | changeType(currentType); 415 | this->setVisible(false); 416 | } 417 | 418 | //根据用户选择的输入法位置设置-居中显示-底部填充-显示在输入框正下方 419 | if (currentPosition == "center") { 420 | QPoint pos = QPoint(deskWidth / 2 - frmWidth / 2, deskHeight / 2 - frmHeight / 2); 421 | this->setGeometry(pos.x(), pos.y(), frmWidth, frmHeight); 422 | } else if (currentPosition == "bottom") { 423 | this->setGeometry(0, deskHeight - frmHeight, deskWidth, frmHeight); 424 | } else if (currentPosition == "control") { 425 | QRect rect = nowWidget->rect(); 426 | QPoint pos = QPoint(rect.left(), rect.bottom() + 2); 427 | pos = nowWidget->mapToGlobal(pos); 428 | 429 | int x = pos.x(); 430 | int y = pos.y(); 431 | if (pos.x() + frmWidth > deskWidth) { 432 | x = deskWidth - frmWidth; 433 | } 434 | if (pos.y() + frmHeight > deskHeight) { 435 | y = pos.y() - frmHeight - rect.height() - 35; 436 | } 437 | 438 | this->setGeometry(x, y, frmWidth, frmHeight); 439 | } 440 | } 441 | } 442 | 443 | void frmInput::changeType(QString type) 444 | { 445 | if (type == "max") { 446 | changeLetter(true); 447 | ui->btnType->setText("大写"); 448 | ui->lab_Title->setText(" 中文输入法--大写"); 449 | ui->btnOther12->setText("/"); 450 | ui->btnOther14->setText(":"); 451 | ui->btnOther17->setText(","); 452 | ui->btnOther18->setText("\\"); 453 | ui->btnOther21->setText("\""); 454 | } else if (type == "min") { 455 | changeLetter(false); 456 | ui->btnType->setText("小写"); 457 | ui->lab_Title->setText(" 中文输入法--小写"); 458 | ui->btnOther12->setText("/"); 459 | ui->btnOther14->setText(":"); 460 | ui->btnOther17->setText(","); 461 | ui->btnOther18->setText("\\"); 462 | ui->btnOther21->setText("\""); 463 | } else { 464 | changeLetter(false); 465 | ui->btnType->setText("中文"); 466 | ui->lab_Title->setText(" 中文输入法--中文"); 467 | ui->btnOther12->setText("。"); 468 | ui->btnOther14->setText(":"); 469 | ui->btnOther17->setText(","); 470 | ui->btnOther18->setText(";"); 471 | ui->btnOther21->setText("“"); 472 | } 473 | //每次切换到模式,都要执行清空之前中文模式下的信息 474 | clearChinese(); 475 | ui->labPY->setText(""); 476 | } 477 | 478 | void frmInput::changeLetter(bool isUpper) 479 | { 480 | QList btn = this->findChildren(); 481 | foreach (QPushButton * b, btn) { 482 | if (b->property("btnLetter").toBool()) { 483 | if (isUpper) { 484 | b->setText(b->text().toUpper()); 485 | } else { 486 | b->setText(b->text().toLower()); 487 | } 488 | } 489 | } 490 | } 491 | 492 | void frmInput::selectChinese() 493 | { 494 | clearChinese(); 495 | QSqlQuery query(QSqlDatabase::database("py")); 496 | QString currentPY = ui->labPY->text(); 497 | QString sql = QString("select word from pinyin where pinyin='%1'").arg(currentPY); 498 | query.exec(sql); 499 | //逐个将查询到的字词加入汉字队列 500 | while(query.next()) { 501 | QString result = query.value(0).toString(); 502 | QStringList text = result.split(" "); 503 | foreach (QString txt, text) { 504 | if (txt.length() > 0) { 505 | allPY.append(txt); 506 | currentPY_count++; 507 | } 508 | } 509 | } 510 | showChinese(); 511 | } 512 | 513 | void frmInput::showChinese() 514 | { 515 | //每个版面最多显示10个汉字 516 | int count = 0; 517 | currentPY.clear(); 518 | for (int i = 0; i < 10; i++) { 519 | labCh[i]->setText(""); 520 | } 521 | 522 | for (int i = currentPY_index; i < currentPY_count; i++) { 523 | if (count == 10) { 524 | break; 525 | } 526 | QString txt = QString("%1.%2").arg(count).arg(allPY[currentPY_index]); 527 | currentPY.append(allPY[currentPY_index]); 528 | labCh[count]->setText(txt); 529 | count++; 530 | currentPY_index++; 531 | } 532 | //qDebug() << "currentPY_index:" << currentPY_index << "currentPY_count:" << currentPY_count; 533 | } 534 | 535 | void frmInput::btn_clicked() 536 | { 537 | //如果当前焦点控件类型为空,则返回不需要继续处理 538 | if (currentEditType == "") { 539 | return; 540 | } 541 | 542 | QPushButton *btn = (QPushButton *)sender(); 543 | QString objectName = btn->objectName(); 544 | if (objectName == "btnType") { 545 | if (currentType == "min") { 546 | currentType = "max"; 547 | } else if (currentType == "max") { 548 | currentType = "chinese"; 549 | } else if (currentType == "chinese") { 550 | currentType = "min"; 551 | } 552 | changeType(currentType); 553 | } else if (objectName == "btnDelete") { 554 | //如果当前是中文模式,则删除对应拼音,删除完拼音之后再删除对应文本输入框的内容 555 | if (currentType == "chinese") { 556 | QString txt = ui->labPY->text(); 557 | int len = txt.length(); 558 | if (len > 0) { 559 | ui->labPY->setText(txt.left(len - 1)); 560 | selectChinese(); 561 | } else { 562 | deleteValue(); 563 | } 564 | } else { 565 | deleteValue(); 566 | } 567 | } else if (objectName == "btnPre") { 568 | if (currentPY_index >= 20) { 569 | //每次最多显示10个汉字,所以每次向前的时候索引要减20 570 | if (currentPY_index % 10 == 0) { 571 | currentPY_index -= 20; 572 | } else { 573 | currentPY_index = currentPY_count - (currentPY_count % 10) - 10; 574 | } 575 | } else { 576 | currentPY_index = 0; 577 | } 578 | showChinese(); 579 | } else if (objectName == "btnNext") { 580 | if (currentPY_index < currentPY_count - 1) { 581 | showChinese(); 582 | } 583 | } else if (objectName == "btnClose") { 584 | this->setVisible(false); 585 | } else if (objectName == "btnSpace") { 586 | if (currentType == "chinese") { 587 | setChinese(0); 588 | } else { 589 | insertValue(" "); 590 | } 591 | } else if (objectName == "btnEnter") { 592 | QWidget *widget; 593 | widget = 0; 594 | if (currentEditType == "QLineEdit") { 595 | widget = currentLineEdit; 596 | } else if (currentEditType == "QTextEdit") { 597 | widget = currentTextEdit; 598 | } else if (currentEditType == "QPlainTextEdit") { 599 | widget = currentPlain; 600 | } else if (currentEditType == "QTextBrowser") { 601 | widget = currentBrowser; 602 | } else if (currentEditType == "QWidget") { 603 | widget = currentWidget; 604 | } 605 | 606 | QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); 607 | QApplication::sendEvent(widget, &keyPress); 608 | 609 | this->setVisible(false); 610 | } else { 611 | QString value = btn->text(); 612 | //如果是&按钮,因为对应&被过滤,所以真实的text为去除前面一个&字符 613 | if (objectName == "btnOther7") { 614 | value = value.right(1); 615 | } 616 | //当前不是中文模式,则单击按钮对应text为传递参数 617 | if (currentType != "chinese") { 618 | insertValue(value); 619 | } else { 620 | //中文模式下,不允许输入特殊字符,单击对应数字按键取得当前索引的汉字 621 | if (btn->property("btnOther").toBool()) { 622 | if (ui->labPY->text().length() == 0) { 623 | insertValue(value); 624 | } 625 | } else if (btn->property("btnNum").toBool()) { 626 | if (ui->labPY->text().length() == 0) { 627 | insertValue(value); 628 | } else if (objectName == "btn0") { 629 | setChinese(0); 630 | } else if (objectName == "btn1") { 631 | setChinese(1); 632 | } else if (objectName == "btn2") { 633 | setChinese(2); 634 | } else if (objectName == "btn3") { 635 | setChinese(3); 636 | } else if (objectName == "btn4") { 637 | setChinese(4); 638 | } else if (objectName == "btn5") { 639 | setChinese(5); 640 | } else if (objectName == "btn6") { 641 | setChinese(6); 642 | } else if (objectName == "btn7") { 643 | setChinese(7); 644 | } else if (objectName == "btn8") { 645 | setChinese(8); 646 | } else if (objectName == "btn9") { 647 | setChinese(9); 648 | } 649 | } else if (btn->property("btnLetter").toBool()) { 650 | ui->labPY->setText(ui->labPY->text() + value); 651 | selectChinese(); 652 | } 653 | } 654 | } 655 | } 656 | 657 | void frmInput::insertValue(QString value) 658 | { 659 | if (currentEditType == "QLineEdit") { 660 | currentLineEdit->insert(value); 661 | } else if (currentEditType == "QTextEdit") { 662 | currentTextEdit->insertPlainText(value); 663 | } else if (currentEditType == "QPlainTextEdit") { 664 | currentPlain->insertPlainText(value); 665 | } else if (currentEditType == "QTextBrowser") { 666 | currentBrowser->insertPlainText(value); 667 | } else if (currentEditType == "QWidget") { 668 | QKeyEvent keyPress(QEvent::KeyPress, 0, Qt::NoModifier, QString(value)); 669 | QApplication::sendEvent(currentWidget, &keyPress); 670 | } 671 | } 672 | 673 | void frmInput::deleteValue() 674 | { 675 | if (currentEditType == "QLineEdit") { 676 | currentLineEdit->backspace(); 677 | } else if (currentEditType == "QTextEdit") { 678 | //获取当前QTextEdit光标,如果光标有选中,则移除选中字符,否则删除光标前一个字符 679 | QTextCursor cursor = currentTextEdit->textCursor(); 680 | if(cursor.hasSelection()) { 681 | cursor.removeSelectedText(); 682 | } else { 683 | cursor.deletePreviousChar(); 684 | } 685 | } else if (currentEditType == "QPlainTextEdit") { 686 | //获取当前QTextEdit光标,如果光标有选中,则移除选中字符,否则删除光标前一个字符 687 | QTextCursor cursor = currentPlain->textCursor(); 688 | if(cursor.hasSelection()) { 689 | cursor.removeSelectedText(); 690 | } else { 691 | cursor.deletePreviousChar(); 692 | } 693 | } else if (currentEditType == "QTextBrowser") { 694 | //获取当前QTextEdit光标,如果光标有选中,则移除选中字符,否则删除光标前一个字符 695 | QTextCursor cursor = currentBrowser->textCursor(); 696 | if(cursor.hasSelection()) { 697 | cursor.removeSelectedText(); 698 | } else { 699 | cursor.deletePreviousChar(); 700 | } 701 | } else if (currentEditType == "QWidget") { 702 | QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, QString()); 703 | QApplication::sendEvent(currentWidget, &keyPress); 704 | } 705 | } 706 | 707 | void frmInput::setChinese(int index) 708 | { 709 | int count = currentPY.count(); 710 | if (count > index) { 711 | insertValue(currentPY[index]); 712 | //添加完一个汉字后,清空当前汉字信息,等待重新输入 713 | clearChinese(); 714 | ui->labPY->setText(""); 715 | } 716 | } 717 | 718 | void frmInput::clearChinese() 719 | { 720 | //清空汉字,重置索引 721 | for (int i = 0; i < 10; i++) { 722 | labCh[i]->setText(""); 723 | } 724 | allPY.clear(); 725 | currentPY.clear(); 726 | currentPY_index = 0; 727 | currentPY_count = 0; 728 | } 729 | 730 | void frmInput::ChangeStyle() 731 | { 732 | if (currentStyle == "blue") { 733 | changeStyle("#DEF0FE", "#C0DEF6", "#C0DCF2", "#386487"); 734 | } else if (currentStyle == "dev") { 735 | changeStyle("#C0D3EB", "#BCCFE7", "#B4C2D7", "#324C6C"); 736 | } else if (currentStyle == "gray") { 737 | changeStyle("#E4E4E4", "#A2A2A2", "#A9A9A9", "#000000"); 738 | } else if (currentStyle == "lightgray") { 739 | changeStyle("#EEEEEE", "#E5E5E5", "#D4D0C8", "#6F6F6F"); 740 | } else if (currentStyle == "darkgray") { 741 | changeStyle("#D8D9DE", "#C8C8D0", "#A9ACB5", "#5D5C6C"); 742 | } else if (currentStyle == "black") { 743 | changeStyle("#4D4D4D", "#292929", "#D9D9D9", "#CACAD0"); 744 | } else if (currentStyle == "brown") { 745 | changeStyle("#667481", "#566373", "#C2CCD8", "#E7ECF0"); 746 | } else if (currentStyle == "silvery") { 747 | changeStyle("#E1E4E6", "#CCD3D9", "#B2B6B9", "#000000"); 748 | } 749 | } 750 | 751 | void frmInput::ChangeFont() 752 | { 753 | QFont btnFont(this->font().family(), btnFontSize); 754 | QFont labFont(this->font().family(), labFontSize); 755 | 756 | QList btns = ui->widgetMain->findChildren(); 757 | foreach (QPushButton * btn, btns) { 758 | btn->setFont(btnFont); 759 | } 760 | 761 | QList labs = ui->widgetTop->findChildren(); 762 | foreach (QLabel * lab, labs) { 763 | lab->setFont(labFont); 764 | } 765 | ui->btnPre->setFont(labFont); 766 | ui->btnNext->setFont(labFont); 767 | ui->btnClose->setFont(labFont); 768 | } 769 | 770 | void frmInput::changeStyle(QString topColor, QString bottomColor, QString borderColor, QString textColor) 771 | { 772 | QStringList qss; 773 | qss.append(QString("QWidget#widget_title{background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 %1,stop:1 %2);}") 774 | .arg(topColor).arg(bottomColor)); 775 | qss.append("QPushButton{padding:5px;border-radius:3px;}"); 776 | qss.append(QString("QPushButton:hover{background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 %1,stop:1 %2);}") 777 | .arg(topColor).arg(bottomColor)); 778 | qss.append(QString("QLabel,QPushButton{color:%1;}").arg(textColor)); 779 | qss.append(QString("QPushButton#btnPre,QPushButton#btnNext,QPushButton#btnClose{padding:5px;}")); 780 | qss.append(QString("QPushButton{border:1px solid %1;background:rgba(0,0,0,0);}") 781 | .arg(borderColor)); 782 | qss.append(QString("QLineEdit{border:1px solid %1;border-radius:5px;padding:2px;background:none;selection-background-color:%2;selection-color:%3;}") 783 | .arg(borderColor).arg(bottomColor).arg(topColor)); 784 | this->setStyleSheet(qss.join("")); 785 | } 786 | -------------------------------------------------------------------------------- /frminput.h: -------------------------------------------------------------------------------- 1 | #ifndef FRMINPUT_H 2 | #define FRMINPUT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace Ui 19 | { 20 | class frmInput; 21 | } 22 | 23 | class frmInput : public QWidget 24 | { 25 | Q_OBJECT 26 | 27 | public: 28 | explicit frmInput(QWidget *parent = 0); 29 | ~frmInput(); 30 | 31 | //单例模式,保证一个程序只存在一个输入法实例对象 32 | static frmInput *Instance() { 33 | if (!_instance) { 34 | static QMutex mutex; 35 | QMutexLocker locker(&mutex); 36 | if (!_instance) { 37 | _instance = new frmInput; 38 | } 39 | } 40 | return _instance; 41 | } 42 | 43 | //初始化面板状态,包括字体大小 44 | void Init(QString position, QString style, int btnFontSize, int labFontSize); 45 | 46 | protected: 47 | //事件过滤器,处理鼠标在汉字标签处单击操作 48 | bool eventFilter(QObject *obj, QEvent *event); 49 | //鼠标拖动事件 50 | void mouseMoveEvent(QMouseEvent *e); 51 | //鼠标按下事件 52 | void mousePressEvent(QMouseEvent *e); 53 | //鼠标松开事件 54 | void mouseReleaseEvent(QMouseEvent *); 55 | 56 | private slots: 57 | //焦点改变事件槽函数处理 58 | void focusChanged(QWidget *oldWidget, QWidget *nowWidget); 59 | //输入法面板按键处理 60 | void btn_clicked(); 61 | //改变输入法面板样式 62 | void changeStyle(QString topColor, QString bottomColor, 63 | QString borderColor, QString textColor); 64 | //定时器处理退格键 65 | void reClicked(); 66 | 67 | private: 68 | Ui::frmInput *ui; 69 | static frmInput *_instance; //实例对象 70 | 71 | int deskWidth; //桌面宽度 72 | int deskHeight; //桌面高度 73 | int frmWidth; //窗体宽度 74 | int frmHeight; //窗体高度 75 | 76 | QPoint mousePoint; //鼠标拖动自定义标题栏时的坐标 77 | bool mousePressed; //鼠标是否按下 78 | 79 | bool isPress; //是否长按退格键 80 | QPushButton *btnPress; //长按按钮 81 | QTimer *timerPress; //退格键定时器 82 | bool checkPress(); //校验当前长按的按钮 83 | 84 | bool isFirst; //是否首次加载 85 | void InitForm(); //初始化窗体数据 86 | void InitProperty(); //初始化属性 87 | void ChangeStyle(); //改变样式 88 | void ChangeFont(); //改变字体大小 89 | void ShowPanel(); //显示输入法面板 90 | 91 | QWidget *currentWidget; //当前焦点的对象 92 | QLineEdit *currentLineEdit; //当前焦点的单行文本框 93 | QTextEdit *currentTextEdit; //当前焦点的多行文本框 94 | QPlainTextEdit *currentPlain; //当前焦点的富文本框 95 | QTextBrowser *currentBrowser; //当前焦点的文本浏览框 96 | 97 | QString currentEditType; //当前焦点控件的类型 98 | QString currentPosition; //当前输入法面板位置类型 99 | QString currentStyle; //当前输入法面板样式 100 | int btnFontSize; //当前输入法面板按钮字体大小 101 | int labFontSize; //当前输入法面板标签字体大小 102 | void insertValue(QString value);//插入值到当前焦点控件 103 | void deleteValue(); //删除当前焦点控件的一个字符 104 | 105 | QString currentType; //当前输入法类型 106 | void changeType(QString type); //改变输入法类型 107 | void changeLetter(bool isUpper);//改变字母大小写 108 | 109 | QListlabCh; //汉字标签数组 110 | QStringList allPY; //所有拼音链表 111 | QStringList currentPY; //当前拼音链表 112 | int currentPY_index; //当前拼音索引 113 | int currentPY_count; //当前拼音数量 114 | void selectChinese(); //查询汉字 115 | void showChinese(); //显示查询到的汉字 116 | void setChinese(int index); //设置当前汉字 117 | void clearChinese(); //清空当前汉字信息 118 | 119 | }; 120 | 121 | #endif // FRMINPUT_H 122 | -------------------------------------------------------------------------------- /frminput.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | frmInput 4 | 5 | 6 | 7 | 0 8 | 0 9 | 600 10 | 220 11 | 12 | 13 | 14 | 中文输入法面板 15 | 16 | 17 | 18 | 19 | 20 | 21 | 6 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 0 31 | 32 | 33 | 0 34 | 35 | 36 | 37 | 38 | 39 | 0 40 | 0 41 | 42 | 43 | 44 | 45 | 46 | 47 | border-width:0px; 48 | 49 | 50 | 51 | 6 52 | 53 | 54 | 0 55 | 56 | 57 | 0 58 | 59 | 60 | 0 61 | 62 | 63 | 0 64 | 65 | 66 | 67 | 68 | 2 69 | 70 | 71 | 72 | 73 | 74 | 0 75 | 0 76 | 77 | 78 | 79 | 80 | 0 81 | 25 82 | 83 | 84 | 85 | 中文输入法--小写 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 0 94 | 0 95 | 96 | 97 | 98 | 99 | 100 | 101 | Qt::AlignCenter 102 | 103 | 104 | 105 | 106 | 107 | 108 | Qt::NoFocus 109 | 110 | 111 | 112 | 113 | 114 | < 115 | 116 | 117 | 118 | 119 | 120 | 121 | Qt::NoFocus 122 | 123 | 124 | 125 | 126 | 127 | > 128 | 129 | 130 | 131 | 132 | 133 | 134 | Qt::NoFocus 135 | 136 | 137 | 138 | 139 | 140 | 关闭 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 0 150 | 151 | 152 | 153 | 154 | 155 | 0 156 | 0 157 | 158 | 159 | 160 | 161 | 0 162 | 25 163 | 164 | 165 | 166 | 167 | 168 | 169 | Qt::AlignCenter 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 0 178 | 0 179 | 180 | 181 | 182 | 183 | 0 184 | 25 185 | 186 | 187 | 188 | 189 | 190 | 191 | Qt::AlignCenter 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 0 200 | 0 201 | 202 | 203 | 204 | 205 | 0 206 | 25 207 | 208 | 209 | 210 | 211 | 212 | 213 | Qt::AlignCenter 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 0 222 | 0 223 | 224 | 225 | 226 | 227 | 0 228 | 25 229 | 230 | 231 | 232 | 233 | 234 | 235 | Qt::AlignCenter 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 0 244 | 0 245 | 246 | 247 | 248 | 249 | 0 250 | 25 251 | 252 | 253 | 254 | 255 | 256 | 257 | Qt::AlignCenter 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 0 266 | 0 267 | 268 | 269 | 270 | 271 | 0 272 | 25 273 | 274 | 275 | 276 | 277 | 278 | 279 | Qt::AlignCenter 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 0 288 | 0 289 | 290 | 291 | 292 | 293 | 0 294 | 25 295 | 296 | 297 | 298 | 299 | 300 | 301 | Qt::AlignCenter 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 0 310 | 0 311 | 312 | 313 | 314 | 315 | 0 316 | 25 317 | 318 | 319 | 320 | 321 | 322 | 323 | Qt::AlignCenter 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 0 332 | 0 333 | 334 | 335 | 336 | 337 | 0 338 | 25 339 | 340 | 341 | 342 | 343 | 344 | 345 | Qt::AlignCenter 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 0 354 | 0 355 | 356 | 357 | 358 | 359 | 0 360 | 25 361 | 362 | 363 | 364 | 365 | 366 | 367 | Qt::AlignCenter 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 0 381 | 0 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 0 390 | 391 | 392 | 3 393 | 394 | 395 | 0 396 | 397 | 398 | 0 399 | 400 | 401 | 2 402 | 403 | 404 | 405 | 406 | 407 | 0 408 | 0 409 | 410 | 411 | 412 | Qt::NoFocus 413 | 414 | 415 | ! 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 0 424 | 0 425 | 426 | 427 | 428 | Qt::NoFocus 429 | 430 | 431 | @ 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 0 440 | 0 441 | 442 | 443 | 444 | Qt::NoFocus 445 | 446 | 447 | # 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 0 456 | 0 457 | 458 | 459 | 460 | Qt::NoFocus 461 | 462 | 463 | $ 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 0 472 | 0 473 | 474 | 475 | 476 | Qt::NoFocus 477 | 478 | 479 | % 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 0 488 | 0 489 | 490 | 491 | 492 | Qt::NoFocus 493 | 494 | 495 | ^ 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 0 504 | 0 505 | 506 | 507 | 508 | Qt::NoFocus 509 | 510 | 511 | && 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 0 520 | 0 521 | 522 | 523 | 524 | Qt::NoFocus 525 | 526 | 527 | * 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 0 536 | 0 537 | 538 | 539 | 540 | Qt::NoFocus 541 | 542 | 543 | ( 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 0 552 | 0 553 | 554 | 555 | 556 | Qt::NoFocus 557 | 558 | 559 | ) 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 0 568 | 0 569 | 570 | 571 | 572 | Qt::NoFocus 573 | 574 | 575 | - 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 0 584 | 0 585 | 586 | 587 | 588 | Qt::NoFocus 589 | 590 | 591 | + 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 0 600 | 0 601 | 602 | 603 | 604 | Qt::NoFocus 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | Qt::Horizontal 615 | 616 | 617 | QSizePolicy::Minimum 618 | 619 | 620 | 621 | 15 622 | 20 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 0 632 | 0 633 | 634 | 635 | 636 | Qt::NoFocus 637 | 638 | 639 | 7 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 0 648 | 0 649 | 650 | 651 | 652 | Qt::NoFocus 653 | 654 | 655 | 8 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 0 664 | 0 665 | 666 | 667 | 668 | Qt::NoFocus 669 | 670 | 671 | 9 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 0 680 | 0 681 | 682 | 683 | 684 | Qt::NoFocus 685 | 686 | 687 | q 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 0 696 | 0 697 | 698 | 699 | 700 | Qt::NoFocus 701 | 702 | 703 | w 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 0 712 | 0 713 | 714 | 715 | 716 | Qt::NoFocus 717 | 718 | 719 | e 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 0 728 | 0 729 | 730 | 731 | 732 | Qt::NoFocus 733 | 734 | 735 | r 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 0 744 | 0 745 | 746 | 747 | 748 | Qt::NoFocus 749 | 750 | 751 | t 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 0 760 | 0 761 | 762 | 763 | 764 | Qt::NoFocus 765 | 766 | 767 | y 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 0 776 | 0 777 | 778 | 779 | 780 | Qt::NoFocus 781 | 782 | 783 | u 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 0 792 | 0 793 | 794 | 795 | 796 | Qt::NoFocus 797 | 798 | 799 | i 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 0 808 | 0 809 | 810 | 811 | 812 | Qt::NoFocus 813 | 814 | 815 | o 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 0 824 | 0 825 | 826 | 827 | 828 | Qt::NoFocus 829 | 830 | 831 | p 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 0 840 | 0 841 | 842 | 843 | 844 | Qt::NoFocus 845 | 846 | 847 | _ 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 0 856 | 0 857 | 858 | 859 | 860 | Qt::NoFocus 861 | 862 | 863 | / 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 0 872 | 0 873 | 874 | 875 | 876 | Qt::NoFocus 877 | 878 | 879 | | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 0 888 | 0 889 | 890 | 891 | 892 | Qt::NoFocus 893 | 894 | 895 | 4 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 0 904 | 0 905 | 906 | 907 | 908 | Qt::NoFocus 909 | 910 | 911 | 5 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 0 920 | 0 921 | 922 | 923 | 924 | Qt::NoFocus 925 | 926 | 927 | 6 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 0 936 | 0 937 | 938 | 939 | 940 | Qt::NoFocus 941 | 942 | 943 | a 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 0 952 | 0 953 | 954 | 955 | 956 | Qt::NoFocus 957 | 958 | 959 | s 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 0 968 | 0 969 | 970 | 971 | 972 | Qt::NoFocus 973 | 974 | 975 | d 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 0 984 | 0 985 | 986 | 987 | 988 | Qt::NoFocus 989 | 990 | 991 | f 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 0 1000 | 0 1001 | 1002 | 1003 | 1004 | Qt::NoFocus 1005 | 1006 | 1007 | g 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 0 1016 | 0 1017 | 1018 | 1019 | 1020 | Qt::NoFocus 1021 | 1022 | 1023 | h 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 0 1032 | 0 1033 | 1034 | 1035 | 1036 | Qt::NoFocus 1037 | 1038 | 1039 | j 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 0 1048 | 0 1049 | 1050 | 1051 | 1052 | Qt::NoFocus 1053 | 1054 | 1055 | k 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 0 1064 | 0 1065 | 1066 | 1067 | 1068 | Qt::NoFocus 1069 | 1070 | 1071 | l 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 0 1080 | 0 1081 | 1082 | 1083 | 1084 | Qt::NoFocus 1085 | 1086 | 1087 | : 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 0 1096 | 0 1097 | 1098 | 1099 | 1100 | Qt::NoFocus 1101 | 1102 | 1103 | " 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 0 1112 | 0 1113 | 1114 | 1115 | 1116 | Qt::NoFocus 1117 | 1118 | 1119 | ? 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 0 1128 | 0 1129 | 1130 | 1131 | 1132 | Qt::NoFocus 1133 | 1134 | 1135 | = 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 0 1144 | 0 1145 | 1146 | 1147 | 1148 | Qt::NoFocus 1149 | 1150 | 1151 | 1 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 0 1160 | 0 1161 | 1162 | 1163 | 1164 | Qt::NoFocus 1165 | 1166 | 1167 | 2 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 0 1176 | 0 1177 | 1178 | 1179 | 1180 | Qt::NoFocus 1181 | 1182 | 1183 | 3 1184 | 1185 | 1186 | 1187 | 1188 | 1189 | 1190 | 1191 | 0 1192 | 0 1193 | 1194 | 1195 | 1196 | Qt::NoFocus 1197 | 1198 | 1199 | z 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 0 1208 | 0 1209 | 1210 | 1211 | 1212 | Qt::NoFocus 1213 | 1214 | 1215 | x 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 0 1224 | 0 1225 | 1226 | 1227 | 1228 | Qt::NoFocus 1229 | 1230 | 1231 | c 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 0 1240 | 0 1241 | 1242 | 1243 | 1244 | Qt::NoFocus 1245 | 1246 | 1247 | v 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 0 1256 | 0 1257 | 1258 | 1259 | 1260 | Qt::NoFocus 1261 | 1262 | 1263 | b 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | 1270 | 1271 | 0 1272 | 0 1273 | 1274 | 1275 | 1276 | Qt::NoFocus 1277 | 1278 | 1279 | n 1280 | 1281 | 1282 | 1283 | 1284 | 1285 | 1286 | 1287 | 0 1288 | 0 1289 | 1290 | 1291 | 1292 | Qt::NoFocus 1293 | 1294 | 1295 | m 1296 | 1297 | 1298 | 1299 | 1300 | 1301 | 1302 | 1303 | 0 1304 | 0 1305 | 1306 | 1307 | 1308 | Qt::NoFocus 1309 | 1310 | 1311 | , 1312 | 1313 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 0 1320 | 0 1321 | 1322 | 1323 | 1324 | Qt::NoFocus 1325 | 1326 | 1327 | \ 1328 | 1329 | 1330 | 1331 | 1332 | 1333 | 1334 | 1335 | 0 1336 | 0 1337 | 1338 | 1339 | 1340 | Qt::NoFocus 1341 | 1342 | 1343 | 0 1344 | 1345 | 1346 | 1347 | 1348 | 1349 | 1350 | 1351 | 0 1352 | 0 1353 | 1354 | 1355 | 1356 | Qt::NoFocus 1357 | 1358 | 1359 | 00 1360 | 1361 | 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | 0 1368 | 0 1369 | 1370 | 1371 | 1372 | Qt::NoFocus 1373 | 1374 | 1375 | . 1376 | 1377 | 1378 | 1379 | 1380 | 1381 | 1382 | 2 1383 | 1384 | 1385 | 1386 | 1387 | 1388 | 0 1389 | 0 1390 | 1391 | 1392 | 1393 | Qt::NoFocus 1394 | 1395 | 1396 | 空格 1397 | 1398 | 1399 | 1400 | 1401 | 1402 | 1403 | 1404 | 0 1405 | 0 1406 | 1407 | 1408 | 1409 | Qt::NoFocus 1410 | 1411 | 1412 | 回车 1413 | 1414 | 1415 | 1416 | 1417 | 1418 | 1419 | 1420 | 0 1421 | 0 1422 | 1423 | 1424 | 1425 | Qt::NoFocus 1426 | 1427 | 1428 | 小写 1429 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 1442 | 1443 | 1444 | 1445 | -------------------------------------------------------------------------------- /frmmain.cpp: -------------------------------------------------------------------------------- 1 | #include "frmmain.h" 2 | #include "ui_frmmain.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | frmMain::frmMain(QWidget *parent) : 9 | QWidget(parent), 10 | ui(new Ui::frmMain) 11 | { 12 | ui->setupUi(this); 13 | ui->txt->setProperty("noinput", true); 14 | } 15 | 16 | frmMain::~frmMain() 17 | { 18 | delete ui; 19 | } 20 | 21 | void frmMain::on_btnDialog_clicked() 22 | { 23 | QDialog *d = new QDialog(this); 24 | QLineEdit *txt = new QLineEdit(d); 25 | txt->setVisible(true); 26 | d->show(); 27 | } 28 | 29 | void frmMain::on_btnInputDialog_clicked() 30 | { 31 | QInputDialog *d = new QInputDialog(this); 32 | d->show(); 33 | } 34 | 35 | void frmMain::on_btnFileDialog_clicked() 36 | { 37 | QFileDialog *d = new QFileDialog(this); 38 | connect(d, SIGNAL(fileSelected(QString)), this, SLOT(fileSelected(QString))); 39 | d->show(); 40 | } 41 | 42 | void frmMain::fileSelected(QString fileName) 43 | { 44 | QFile file(fileName); 45 | file.open(QFile::WriteOnly | QIODevice::Text); 46 | QTextStream out(&file); 47 | out << ui->plainTextEdit->toPlainText(); 48 | file.close(); 49 | } 50 | -------------------------------------------------------------------------------- /frmmain.h: -------------------------------------------------------------------------------- 1 | #ifndef FRMMAIN_H 2 | #define FRMMAIN_H 3 | 4 | #include 5 | 6 | namespace Ui 7 | { 8 | class frmMain; 9 | } 10 | 11 | class frmMain : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit frmMain(QWidget *parent = 0); 17 | ~frmMain(); 18 | 19 | private slots: 20 | void fileSelected(QString fileName); 21 | void on_btnDialog_clicked(); 22 | void on_btnInputDialog_clicked(); 23 | void on_btnFileDialog_clicked(); 24 | 25 | private: 26 | Ui::frmMain *ui; 27 | 28 | }; 29 | 30 | #endif // FRMMAIN_H 31 | -------------------------------------------------------------------------------- /frmmain.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | frmMain 4 | 5 | 6 | 7 | 0 8 | 0 9 | 751 10 | 543 11 | 12 | 13 | 14 | 输入法演示 15 | 16 | 17 | false 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 禁用输入法 27 | 28 | 29 | 30 | 31 | 32 | 33 | 对话框窗体 34 | 35 | 36 | 37 | 38 | 39 | 40 | 输入框 41 | 42 | 43 | 44 | 45 | 46 | 47 | 打开文件对话框 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | true 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 1 69 | 70 | 71 | 72 | 73 | 2 74 | 75 | 76 | 77 | 78 | 3 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | yyyy年MM月dd日 87 | 88 | 89 | 90 | 91 | 92 | 93 | HH时mm分ss秒 94 | 95 | 96 | 97 | 98 | 99 | 100 | yyyy年MM月dd日 HH时mm分ss秒 101 | 102 | 103 | 104 | 105 | 106 | 107 | 曾经有段时间,我有一个很执着的梦想,我要导演出一部空前绝后的句幕。不过现实无情地碾碎我的梦想,也同时将我推进了人生的低谷。 108 | 我开始思考,思想很多很多我以前总是回避的问题,在一次次思考中,我能感觉到我正在向一个陌生的地方走去,前途是光是暗也无法推测,我发现我在赌,赌注是一辈子的懊悔或是郁郁终生。 109 | 但当我看到阳光弥漫在我身边时,才发现以前的我是那么幼稚,我始终在找借口或不是借口的借口推卸掉与生俱来的责任,在光怪陆离的现实中午找个僻静的地方希望过云淡风轻的日子。我错了,我拥有足够的能力却不敢恣意妄为,我拥有惊人的天赋却畏惧这只是南柯一梦,或者这本来就是梦,醒来时却是了无痕迹和无休止的眷恋。 110 | 从前有个同学问我是不是幻想过一些特别的经历会降临到自己身上。 111 | 当时我只笑了笑,却不知道该怎么回答。 112 | 我想我是矛盾的,我认为我的存在与否关系到世间的万事万物,但我找不到足够的证据来证明我具有救世主的身份。因此我一度怀疑过我是不是生不逢时,或是天妒英才。 113 | 我在一次次轮回中等待着一个机会,也许是乱世,也许是太平,我没有所谓的一技之长,只有飞扬跋扈的骄傲和潮洗潮卷的胸怀。只有一笑置之的孤傲和白云苍狗的方式。 114 | 我想我不该妄自菲薄,甚至这是理所当然的不加半点修饰的顺其自然。 115 | 我很喜欢这样一句话:如果我将庸碌一生的话,地球将停止转动,地球停止转动了吗?没有,那我将不会庸碌一生。 116 | 在特定的时间,特定的环境,特定的地点,有个特定的人将主宰万事万物! 117 | 天生我才必有用! 118 | 经典的心照不宣,只可惜他的傲慢却没有足够的能力做基垫。 119 | 我想我是对的,注定的便是永远无法改变的,过去的只是匆匆一瞥,将来的只是白驹过隙,一次次的轮回换来的是麻木的循规蹈矩,所以世界需要那么一个人----改变。 120 | 过去亦空间空对月,茫茫鸿蒙无归处。 121 | 我如薏苡,为实。 122 | 众如佛珠,为空。 123 | 我为本,众为捧。 124 | 冥冥之间以无踪。 125 | 126 | 127 | 128 | 129 | 130 | 131 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 132 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 133 | p, li { white-space: pre-wrap; } 134 | </style></head><body style=" font-family:'宋体'; font-size:9pt; font-weight:400; font-style:normal;"> 135 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 新建行 150 | 151 | 152 | 153 | 154 | 新建行 155 | 156 | 157 | 158 | 159 | 新建列 160 | 161 | 162 | 163 | 164 | 新建列 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | btnFileDialog 174 | lineEdit 175 | spinBox 176 | doubleSpinBox 177 | dateEdit 178 | dateTimeEdit 179 | comboBox 180 | comboBox_2 181 | timeEdit 182 | textEdit 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /frmnum.cpp: -------------------------------------------------------------------------------- 1 | #include "frmnum.h" 2 | #include "ui_frmnum.h" 3 | #include "qdesktopwidget.h" 4 | 5 | frmNum *frmNum::_instance = 0; 6 | frmNum::frmNum(QWidget *parent) : 7 | QWidget(parent), 8 | ui(new Ui::frmNum) 9 | { 10 | ui->setupUi(this); 11 | this->InitForm(); 12 | this->InitProperty(); 13 | this->ChangeStyle(); 14 | } 15 | 16 | frmNum::~frmNum() 17 | { 18 | delete ui; 19 | } 20 | 21 | void frmNum::Init(QString style, int fontSize) { 22 | this->currentStyle = style; 23 | this->currentFontSize = fontSize; 24 | this->ChangeStyle(); 25 | } 26 | 27 | void frmNum::mouseMoveEvent(QMouseEvent *e) 28 | { 29 | if (mousePressed && (e->buttons() && Qt::LeftButton)) { 30 | this->move(e->globalPos() - mousePoint); 31 | e->accept(); 32 | } 33 | } 34 | 35 | void frmNum::mousePressEvent(QMouseEvent *e) 36 | { 37 | if (e->button() == Qt::LeftButton) { 38 | mousePressed = true; 39 | mousePoint = e->globalPos() - this->pos(); 40 | e->accept(); 41 | } 42 | } 43 | 44 | void frmNum::mouseReleaseEvent(QMouseEvent *) 45 | { 46 | mousePressed = false; 47 | } 48 | 49 | void frmNum::InitForm() 50 | { 51 | this->mousePressed = false; 52 | this->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); 53 | 54 | QDesktopWidget w; 55 | deskWidth = w.availableGeometry().width(); 56 | deskHeight = w.availableGeometry().height(); 57 | frmWidth = this->width(); 58 | frmHeight = this->height(); 59 | 60 | isFirst = true; 61 | isPress = false; 62 | timerPress = new QTimer(this); 63 | connect(timerPress, SIGNAL(timeout()), this, SLOT(reClicked())); 64 | currentWidget = 0; 65 | 66 | //如果需要更改输入法面板的样式,改变currentStyle这个变量即可 67 | //blue--淡蓝色 dev--dev风格 black--黑色 brown--灰黑色 lightgray--浅灰色 darkgray--深灰色 gray--灰色 silvery--银色 68 | currentStyle = ""; 69 | 70 | //输入法面板字体大小,如果需要更改面板字体大小,该这里即可 71 | currentFontSize = 10; 72 | 73 | QList btn = this->findChildren(); 74 | foreach (QPushButton * b, btn) { 75 | connect(b, SIGNAL(clicked()), this, SLOT(btn_clicked())); 76 | } 77 | 78 | //绑定全局改变焦点信号槽 79 | connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)), 80 | this, SLOT(focusChanged(QWidget *, QWidget *))); 81 | //绑定按键事件过滤器 82 | qApp->installEventFilter(this); 83 | } 84 | 85 | void frmNum::InitProperty() 86 | { 87 | ui->btn0->setProperty("btnNum", true); 88 | ui->btn1->setProperty("btnNum", true); 89 | ui->btn2->setProperty("btnNum", true); 90 | ui->btn3->setProperty("btnNum", true); 91 | ui->btn4->setProperty("btnNum", true); 92 | ui->btn5->setProperty("btnNum", true); 93 | ui->btn6->setProperty("btnNum", true); 94 | ui->btn7->setProperty("btnNum", true); 95 | ui->btn8->setProperty("btnNum", true); 96 | ui->btn9->setProperty("btnNum", true); 97 | ui->btn00->setProperty("btnNum", true); 98 | 99 | ui->btnDot->setProperty("btnOther", true); 100 | ui->btnSpace->setProperty("btnOther", true); 101 | ui->btnDelete->setProperty("btnOther", true); 102 | } 103 | 104 | void frmNum::ShowPanel() 105 | { 106 | this->setVisible(true); 107 | } 108 | 109 | void frmNum::focusChanged(QWidget *oldWidget, QWidget *nowWidget) 110 | { 111 | //qDebug() << "oldWidget:" << oldWidget << " nowWidget:" << nowWidget; 112 | if (nowWidget != 0 && !this->isAncestorOf(nowWidget)) { 113 | //在Qt5和linux系统中(嵌入式linux除外),当输入法面板关闭时,焦点会变成无,然后焦点会再次移到焦点控件处 114 | //这样导致输入法面板的关闭按钮不起作用,关闭后马上有控件获取焦点又显示. 115 | //为此,增加判断,当焦点是从有对象转为无对象再转为有对象时不要显示. 116 | //这里又要多一个判断,万一首个窗体的第一个焦点就是落在可输入的对象中,则要过滤掉 117 | #ifndef __arm__ 118 | if (oldWidget == 0x0 && !isFirst) { 119 | QTimer::singleShot(0, this, SLOT(hide())); 120 | return; 121 | } 122 | #endif 123 | 124 | //如果对应属性noinput为真则不显示 125 | if (nowWidget->property("noinput").toBool()) { 126 | QTimer::singleShot(0, this, SLOT(hide())); 127 | return; 128 | } 129 | 130 | isFirst = false; 131 | if (nowWidget->inherits("QLineEdit")) { 132 | currentLineEdit = (QLineEdit *)nowWidget; 133 | currentEditType = "QLineEdit"; 134 | ShowPanel(); 135 | } else if (nowWidget->inherits("QTextEdit")) { 136 | currentTextEdit = (QTextEdit *)nowWidget; 137 | currentEditType = "QTextEdit"; 138 | ShowPanel(); 139 | } else if (nowWidget->inherits("QPlainTextEdit")) { 140 | currentPlain = (QPlainTextEdit *)nowWidget; 141 | currentEditType = "QPlainTextEdit"; 142 | ShowPanel(); 143 | } else if (nowWidget->inherits("QTextBrowser")) { 144 | currentBrowser = (QTextBrowser *)nowWidget; 145 | currentEditType = "QTextBrowser"; 146 | ShowPanel(); 147 | } else if (nowWidget->inherits("QComboBox")) { 148 | QComboBox *cbox = (QComboBox *)nowWidget; 149 | //只有当下拉选择框处于编辑模式才可以输入 150 | if (cbox->isEditable()) { 151 | currentLineEdit = cbox->lineEdit() ; 152 | currentEditType = "QLineEdit"; 153 | ShowPanel(); 154 | } 155 | } else if (nowWidget->inherits("QSpinBox") || 156 | nowWidget->inherits("QDoubleSpinBox") || 157 | nowWidget->inherits("QDateEdit") || 158 | nowWidget->inherits("QTimeEdit") || 159 | nowWidget->inherits("QDateTimeEdit")) { 160 | currentWidget = nowWidget; 161 | currentEditType = "QWidget"; 162 | ShowPanel(); 163 | } else { 164 | currentWidget = 0; 165 | currentLineEdit = 0; 166 | currentTextEdit = 0; 167 | currentPlain = 0; 168 | currentBrowser = 0; 169 | currentEditType = ""; 170 | this->setVisible(false); 171 | } 172 | 173 | QRect rect = nowWidget->rect(); 174 | QPoint pos = QPoint(rect.left(), rect.bottom() + 2); 175 | pos = nowWidget->mapToGlobal(pos); 176 | 177 | int x = pos.x(); 178 | int y = pos.y(); 179 | if (pos.x() + frmWidth > deskWidth) { 180 | x = deskWidth - frmWidth; 181 | } 182 | if (pos.y() + frmHeight > deskHeight) { 183 | y = pos.y() - frmHeight - rect.height() - 35; 184 | } 185 | 186 | this->setGeometry(x, y, frmWidth, frmHeight); 187 | } 188 | } 189 | 190 | bool frmNum::eventFilter(QObject *obj, QEvent *event) 191 | { 192 | if (event->type() == QEvent::MouseButtonPress) { 193 | if (currentEditType != "") { 194 | if (obj != ui->btnClose) { 195 | QString objName = obj->objectName(); 196 | if (!obj->property("noinput").toBool() && objName != "frmMainWindow" 197 | && objName != "frmInputWindow" && objName != "qt_edit_menu") { 198 | ShowPanel(); 199 | } 200 | } 201 | btnPress = (QPushButton *)obj; 202 | if (checkPress()) { 203 | isPress = true; 204 | timerPress->start(500); 205 | } 206 | } 207 | return false; 208 | } else if (event->type() == QEvent::MouseButtonRelease) { 209 | btnPress = (QPushButton *)obj; 210 | if (checkPress()) { 211 | isPress = false; 212 | timerPress->stop(); 213 | } 214 | return false; 215 | } 216 | return QWidget::eventFilter(obj, event); 217 | } 218 | 219 | bool frmNum::checkPress() 220 | { 221 | //只有属于数字键盘的合法按钮才继续处理 222 | bool num_ok = btnPress->property("btnNum").toBool(); 223 | bool other_ok = btnPress->property("btnOther").toBool(); 224 | if (num_ok || other_ok) { 225 | return true; 226 | } 227 | return false; 228 | } 229 | 230 | void frmNum::reClicked() 231 | { 232 | if (isPress) { 233 | timerPress->setInterval(30); 234 | btnPress->click(); 235 | } 236 | } 237 | 238 | void frmNum::btn_clicked() 239 | { 240 | //如果当前焦点控件类型为空,则返回不需要继续处理 241 | if (currentEditType == "") { 242 | return; 243 | } 244 | 245 | QPushButton *btn = (QPushButton *)sender(); 246 | QString objectName = btn->objectName(); 247 | if (objectName == "btnDelete") { 248 | deleteValue(); 249 | } else if (objectName == "btnClose") { 250 | this->setVisible(false); 251 | } else if (objectName == "btnEnter") { 252 | this->setVisible(false); 253 | } else if (objectName == "btnSpace") { 254 | insertValue(" "); 255 | } else { 256 | QString value = btn->text(); 257 | insertValue(value); 258 | } 259 | } 260 | 261 | void frmNum::insertValue(QString value) 262 | { 263 | if (currentEditType == "QLineEdit") { 264 | currentLineEdit->insert(value); 265 | } else if (currentEditType == "QTextEdit") { 266 | currentTextEdit->insertPlainText(value); 267 | } else if (currentEditType == "QPlainTextEdit") { 268 | currentPlain->insertPlainText(value); 269 | } else if (currentEditType == "QTextBrowser") { 270 | currentBrowser->insertPlainText(value); 271 | } else if (currentEditType == "QWidget") { 272 | QKeyEvent keyPress(QEvent::KeyPress, 0, Qt::NoModifier, QString(value)); 273 | QApplication::sendEvent(currentWidget, &keyPress); 274 | } 275 | } 276 | 277 | void frmNum::deleteValue() 278 | { 279 | if (currentEditType == "QLineEdit") { 280 | currentLineEdit->backspace(); 281 | } else if (currentEditType == "QTextEdit") { 282 | //获取当前QTextEdit光标,如果光标有选中,则移除选中字符,否则删除光标前一个字符 283 | QTextCursor cursor = currentTextEdit->textCursor(); 284 | if(cursor.hasSelection()) { 285 | cursor.removeSelectedText(); 286 | } else { 287 | cursor.deletePreviousChar(); 288 | } 289 | } else if (currentEditType == "QPlainTextEdit") { 290 | //获取当前QTextEdit光标,如果光标有选中,则移除选中字符,否则删除光标前一个字符 291 | QTextCursor cursor = currentPlain->textCursor(); 292 | if(cursor.hasSelection()) { 293 | cursor.removeSelectedText(); 294 | } else { 295 | cursor.deletePreviousChar(); 296 | } 297 | } else if (currentEditType == "QTextBrowser") { 298 | //获取当前QTextEdit光标,如果光标有选中,则移除选中字符,否则删除光标前一个字符 299 | QTextCursor cursor = currentBrowser->textCursor(); 300 | if(cursor.hasSelection()) { 301 | cursor.removeSelectedText(); 302 | } else { 303 | cursor.deletePreviousChar(); 304 | } 305 | } else if (currentEditType == "QWidget") { 306 | QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_Delete, Qt::NoModifier, QString()); 307 | QApplication::sendEvent(currentWidget, &keyPress); 308 | } 309 | } 310 | 311 | void frmNum::ChangeStyle() 312 | { 313 | if (currentStyle == "blue") { 314 | changeStyle("#DEF0FE", "#C0DEF6", "#C0DCF2", "#386487"); 315 | } else if (currentStyle == "dev") { 316 | changeStyle("#C0D3EB", "#BCCFE7", "#B4C2D7", "#324C6C"); 317 | } else if (currentStyle == "gray") { 318 | changeStyle("#E4E4E4", "#A2A2A2", "#A9A9A9", "#000000"); 319 | } else if (currentStyle == "lightgray") { 320 | changeStyle("#EEEEEE", "#E5E5E5", "#D4D0C8", "#6F6F6F"); 321 | } else if (currentStyle == "darkgray") { 322 | changeStyle("#D8D9DE", "#C8C8D0", "#A9ACB5", "#5D5C6C"); 323 | } else if (currentStyle == "black") { 324 | changeStyle("#4D4D4D", "#292929", "#D9D9D9", "#CACAD0"); 325 | } else if (currentStyle == "brown") { 326 | changeStyle("#667481", "#566373", "#C2CCD8", "#E7ECF0"); 327 | } else if (currentStyle == "silvery") { 328 | changeStyle("#E1E4E6", "#CCD3D9", "#B2B6B9", "#000000"); 329 | } 330 | } 331 | 332 | void frmNum::changeStyle(QString topColor, QString bottomColor, QString borderColor, QString textColor) 333 | { 334 | QStringList qss; 335 | qss.append(QString("QWidget#widget_title{background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 %1,stop:1 %2);}") 336 | .arg(topColor).arg(bottomColor)); 337 | qss.append("QPushButton{padding:5px;border-radius:3px;}"); 338 | qss.append(QString("QPushButton:hover{background:qlineargradient(spread:pad,x1:0,y1:0,x2:0,y2:1,stop:0 %1,stop:1 %2);}") 339 | .arg(topColor).arg(bottomColor)); 340 | qss.append(QString("QLabel,QPushButton{font-size:%1pt;color:%2;}") 341 | .arg(currentFontSize).arg(textColor)); 342 | qss.append(QString("QPushButton#btnPre,QPushButton#btnNext,QPushButton#btnClose{padding:5px;}")); 343 | qss.append(QString("QPushButton{border:1px solid %1;background:rgba(0,0,0,0);}") 344 | .arg(borderColor)); 345 | qss.append(QString("QLineEdit{border:1px solid %1;border-radius:5px;padding:2px;background:none;selection-background-color:%2;selection-color:%3;}") 346 | .arg(borderColor).arg(bottomColor).arg(topColor)); 347 | this->setStyleSheet(qss.join("")); 348 | } 349 | -------------------------------------------------------------------------------- /frmnum.h: -------------------------------------------------------------------------------- 1 | #ifndef FRMNUM_H 2 | #define FRMNUM_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace Ui 16 | { 17 | class frmNum; 18 | } 19 | 20 | class frmNum : public QWidget 21 | { 22 | Q_OBJECT 23 | 24 | public: 25 | explicit frmNum(QWidget *parent = 0); 26 | ~frmNum(); 27 | 28 | //单例模式,保证一个程序只存在一个输入法实例对象 29 | static frmNum *Instance() { 30 | if (!_instance) { 31 | static QMutex mutex; 32 | QMutexLocker locker(&mutex); 33 | if (!_instance) { 34 | _instance = new frmNum; 35 | } 36 | } 37 | return _instance; 38 | } 39 | 40 | //初始化面板状态,包括字体大小 41 | void Init(QString style, int fontSize); 42 | 43 | protected: 44 | //事件过滤器,处理鼠标按下弹出输入法面板 45 | bool eventFilter(QObject *obj, QEvent *event); 46 | //鼠标拖动事件 47 | void mouseMoveEvent(QMouseEvent *e); 48 | //鼠标按下事件 49 | void mousePressEvent(QMouseEvent *e); 50 | //鼠标松开事件 51 | void mouseReleaseEvent(QMouseEvent *); 52 | 53 | private slots: 54 | //焦点改变事件槽函数处理 55 | void focusChanged(QWidget *oldWidget, QWidget *nowWidget); 56 | //输入法面板按键处理 57 | void btn_clicked(); 58 | //改变输入法面板样式 59 | void changeStyle(QString topColor, QString bottomColor, 60 | QString borderColor, QString textColor); 61 | //定时器处理退格键 62 | void reClicked(); 63 | //显示面板 64 | void ShowPanel(); 65 | 66 | private: 67 | Ui::frmNum *ui; 68 | static frmNum *_instance; //实例对象 69 | 70 | int deskWidth; //桌面宽度 71 | int deskHeight; //桌面高度 72 | int frmWidth; //窗体宽度 73 | int frmHeight; //窗体高度 74 | 75 | bool isPress; //是否长按退格键 76 | QPushButton *btnPress; //长按按钮 77 | QTimer *timerPress; //退格键定时器 78 | bool checkPress(); //校验当前长按的按钮 79 | 80 | QPoint mousePoint; //鼠标拖动自定义标题栏时的坐标 81 | bool mousePressed; //鼠标是否按下 82 | 83 | bool isFirst; //是否首次加载 84 | void InitForm(); //初始化窗体数据 85 | void InitProperty(); //初始化属性 86 | void ChangeStyle(); //改变样式 87 | 88 | QWidget *currentWidget; //当前焦点的对象 89 | QLineEdit *currentLineEdit; //当前焦点的单行文本框 90 | QTextEdit *currentTextEdit; //当前焦点的多行文本框 91 | QPlainTextEdit *currentPlain; //当前焦点的富文本框 92 | QTextBrowser *currentBrowser; //当前焦点的文本浏览框 93 | 94 | QString currentEditType; //当前焦点控件的类型 95 | QString currentStyle; //当前输入法面板样式 96 | int currentFontSize; //当前输入法面板字体大小 97 | void insertValue(QString value);//插入值到当前焦点控件 98 | void deleteValue(); //删除当前焦点控件的一个字符 99 | 100 | }; 101 | 102 | #endif // FRMNUM_H 103 | -------------------------------------------------------------------------------- /frmnum.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | frmNum 4 | 5 | 6 | 7 | 0 8 | 0 9 | 210 10 | 128 11 | 12 | 13 | 14 | 数字键盘 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 31 | 32 | 33 | 0 34 | 0 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 0 43 | 0 44 | 45 | 46 | 47 | Qt::NoFocus 48 | 49 | 50 | 7 51 | 52 | 53 | false 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 0 62 | 0 63 | 64 | 65 | 66 | Qt::NoFocus 67 | 68 | 69 | 8 70 | 71 | 72 | false 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 0 81 | 0 82 | 83 | 84 | 85 | Qt::NoFocus 86 | 87 | 88 | 9 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 0 97 | 0 98 | 99 | 100 | 101 | Qt::NoFocus 102 | 103 | 104 | 关闭 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 0 113 | 0 114 | 115 | 116 | 117 | Qt::NoFocus 118 | 119 | 120 | 4 121 | 122 | 123 | false 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 0 132 | 0 133 | 134 | 135 | 136 | Qt::NoFocus 137 | 138 | 139 | 5 140 | 141 | 142 | false 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 0 151 | 0 152 | 153 | 154 | 155 | Qt::NoFocus 156 | 157 | 158 | 6 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 0 167 | 0 168 | 169 | 170 | 171 | Qt::NoFocus 172 | 173 | 174 | 空格 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 0 183 | 0 184 | 185 | 186 | 187 | Qt::NoFocus 188 | 189 | 190 | 1 191 | 192 | 193 | false 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 0 202 | 0 203 | 204 | 205 | 206 | Qt::NoFocus 207 | 208 | 209 | 2 210 | 211 | 212 | false 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 0 221 | 0 222 | 223 | 224 | 225 | Qt::NoFocus 226 | 227 | 228 | 3 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 0 237 | 0 238 | 239 | 240 | 241 | Qt::NoFocus 242 | 243 | 244 | 回车 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 0 253 | 0 254 | 255 | 256 | 257 | Qt::NoFocus 258 | 259 | 260 | 0 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 0 269 | 0 270 | 271 | 272 | 273 | Qt::NoFocus 274 | 275 | 276 | 00 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 0 285 | 0 286 | 287 | 288 | 289 | Qt::NoFocus 290 | 291 | 292 | . 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 0 301 | 0 302 | 303 | 304 | 305 | Qt::NoFocus 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "frmmain.h" 2 | #include 3 | #include "qtextcodec.h" 4 | #include "qfile.h" 5 | #include "frminput.h" 6 | #include "frmnum.h" 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | QApplication a(argc, argv); 11 | 12 | #if (QT_VERSION <= QT_VERSION_CHECK(5,0,0)) 13 | //QT5版本以上默认就是采用UTF-8编码 14 | QTextCodec *codec = QTextCodec::codecForName("UTF-8"); 15 | QTextCodec::setCodecForLocale(codec); 16 | QTextCodec::setCodecForCStrings(codec); 17 | QTextCodec::setCodecForTr(codec); 18 | #endif 19 | 20 | qApp->setFont(QFont("Microsoft YaHei", 9)); 21 | 22 | #ifndef __arm__ 23 | //如果输入法字库文件不存在,自动拷贝字库文件 24 | QString path = qApp->applicationDirPath(); 25 | QFile file(path + "/py.db"); 26 | if (!file.exists() || file.size()==0) { 27 | QStringList list = path.split("/"); 28 | QString fileName, newName; 29 | for (int i = 0; i < list.count() - 2; i++) { 30 | fileName = fileName + list.at(i) + "/"; 31 | } 32 | fileName += "InputTool/py.db"; 33 | newName = path + "/py.db"; 34 | file.remove(); 35 | QFile::copy(fileName, newName); 36 | } 37 | #endif 38 | 39 | //在main函数中就加载输入法面板,保证整个应用程序可以使用输入法 40 | //以下方法打开中文输入法 41 | frmInput::Instance()->Init("control", "silvery", 10, 10); 42 | //以下方法打开数字键盘 43 | //frmNum::Instance()->Init("black", 10); 44 | 45 | frmMain w; 46 | w.showMaximized(); 47 | 48 | return a.exec(); 49 | } 50 | -------------------------------------------------------------------------------- /py.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanxiaoluo/KeyboardLiuDianWu/7f0470e759d5885a974acf87fe68cbdeab4691fd/py.db -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanxiaoluo/KeyboardLiuDianWu/7f0470e759d5885a974acf87fe68cbdeab4691fd/readme.txt --------------------------------------------------------------------------------