#include "Virtual_Keyboard.h" #include #include #include namespace renderive { Key_Button::Key_Button() { /*支持长按*/ // this->setAutoRepeat(true); // this->setAutoRepeatDelay(500); // this->setAutoRepeatInterval(100); connect(this, &QPushButton::pressed, [&]() { virtual_keyboard->handle_Key_Press(this); }); } Virtual_Keyboard::Virtual_Keyboard(QWidget* parent) : QWidget(parent) { this->setStyleSheet( "QPushButton{" "font: 16pt 黑体;" "font-size: 26px;" "color: white;" "margin: 2px;" "border-radius: 5px;" "background: #00C78C;}" "QPushButton:pressed{" "background: #F0FFFF ;}" "QListWidget::Item:hover { background: #00C78C; color: white; }" "QListWidget {outline: none; border:1px solid #00000000; color: black; }" "QLineEdit {outline: none; border:1px solid #00000000; color: black;}"); QSize screen_size = QGuiApplication::primaryScreen()->size(); resize(screen_size / 2); main_layout = new QVBoxLayout(this); size_policy.setHorizontalPolicy(QSizePolicy::Preferred); size_policy.setVerticalPolicy(QSizePolicy::Preferred); size_policy.setHorizontalStretch(1); size_policy.setVerticalStretch(0); english = create_english(); chinese = create_chinese(); symbol = create_symbol(); main_layout->addWidget(english); main_layout->addWidget(chinese); main_layout->addWidget(symbol); cur_widget = english; chinese->hide(); symbol->hide(); setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool | Qt::WindowDoesNotAcceptFocus); core = new Input_Core(this); if (!core->init()) { qDebug() << "字典加载失败,请将dict文件移至工作目录"; } /* 设置为列表显示模式 */ list_widget->setViewMode(QListView::ListMode); /* 从左往右排列 */ list_widget->setFlow(QListView::LeftToRight); /* 屏蔽水平滑动条 */ list_widget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); /* 屏蔽垂直滑动条 */ list_widget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); /* 设置为像素滚动 */ list_widget->setHorizontalScrollMode(QListWidget::ScrollPerPixel); /* 设置鼠标左键拖动 */ QScroller::grabGesture(list_widget, QScroller::LeftMouseButtonGesture); // 设置不可选中 connect(edit, &QLineEdit::selectionChanged, [=] { edit->deselect(); }); // 中文输入 connect(edit, &QLineEdit::textChanged, [=](const QString& text) { /* 单个字符过长引发崩溃 * 处理:单个字符限制长度为10 */ if (text.isEmpty()) { return; } if (text.length() >= 10) { if (is_single_char(text)) { QString deal_text = text.mid(0, 10); get_candidate_list(deal_text); return; } get_candidate_list(text); return; } else { get_candidate_list(text); } }); connect(list_widget, &QListWidget::itemClicked, [=](QListWidgetItem* item) { QKeyEvent key_press(QEvent::KeyPress, Qt::Key_unknown, Qt::NoModifier, item->text()); QCoreApplication::sendEvent(input_widget, &key_press); list_widget->clear(); edit->clear(); }); } Virtual_Keyboard::~Virtual_Keyboard() {} bool Virtual_Keyboard::is_single_char(QString spell) { bool ret = true; for (auto s : spell) { if (s != spell[0]) { ret = false; break; } } return ret; } void Virtual_Keyboard::set_edit(QWidget* edit) { this->input_widget = edit; this->input_widget->installEventFilter(this); } void Virtual_Keyboard::get_candidate_list(const QString spell) { unsigned int cand = core->search(spell); if (cand == 0) { return; } std::vector ret = core->get_candidate(cand); if (ret.empty()) { return; } list_widget->clear(); for (const QString& candidate : ret) list_widget->addItem(candidate); } void Virtual_Keyboard::handle_Key_Press(Key_Button* button) { if (state == Chinese) { if (button->key != Qt::Key_Backspace) { edit->insert(button->text); } else { if (!edit->text().isEmpty()) { edit->backspace(); } else { list_widget->clear(); QKeyEvent key_press(QEvent::KeyPress, button->key, button->modifiers, button->text); QCoreApplication::sendEvent(input_widget, &key_press); } } } else { if (button->is_text) { QKeyEvent key_press(QEvent::KeyPress, button->key, button->modifiers, button->text); if (input_widget) { QCoreApplication::sendEvent(input_widget, &key_press); } else { qWarning("VirtualKeyBoard input_widget == NULL!"); } } } } bool Virtual_Keyboard::eventFilter(QObject* watched, QEvent* event) { bool ok = false; if (QApplication::focusWidget() == watched && event->type() == QEvent::MouseButtonRelease) { ok = true; } if (event->type() == QEvent::FocusIn) { ok = true; } if (ok) { QWidget* w = qobject_cast(watched); set_edit(w); QPoint pos = w->mapToGlobal(QPoint(0, 0)); QSize screen_size = QGuiApplication::primaryScreen()->size(); int keyboard_width = width(); int keyboard_height = height(); int screen_width = screen_size.width(); int screen_height = screen_size.height(); int x = pos.x(); int y = pos.y() + w->height(); if (x + keyboard_width > screen_width) { setFixedWidth(screen_width - pos.x() - w->width()); } if (y + keyboard_height > screen_height) { setFixedHeight(screen_height - pos.y() - w->height()); } move(x, y); show(); } if (event->type() == QEvent::FocusOut) { this->hide(); } return QObject::eventFilter(watched, event); } void Virtual_Keyboard::mousePressEvent(QMouseEvent* event) { if (moving) return; if (event->button() == Qt::LeftButton) { moving = true; start_pos = pos(); start_global_pos = event->globalPos(); QApplication::setOverrideCursor(Qt::ClosedHandCursor); } event->accept(); } void Virtual_Keyboard::mouseMoveEvent(QMouseEvent* event) { if (!moving) return; move(start_pos + event->globalPos() - start_global_pos); event->accept(); } void Virtual_Keyboard::mouseReleaseEvent(QMouseEvent* event) { if (!moving) return; moving = false; event->accept(); QApplication::restoreOverrideCursor(); } } // namespace renderive