208 lines
6.8 KiB
C++
208 lines
6.8 KiB
C++
#include "Virtual_Keyboard.h"
|
|
#include <QApplication>
|
|
#include <QDesktopWidget>
|
|
#include <QScreen>
|
|
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<QString> 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<QWidget*>(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
|