Files
Renderive/YSGraphic_Core/base/VirtualKeyBoard/VirtualKeyBoard.cpp
T
2026-06-16 13:33:27 +08:00

203 lines
7.4 KiB
C++

#include "VirtualKeyBoard.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
namespace YSG {
KeyButton::KeyButton() {
/*支持长按*/
// this->setAutoRepeat(true);
// this->setAutoRepeatDelay(500);
// this->setAutoRepeatInterval(100);
connect(this, &QPushButton::pressed, [&]() {
mVirtualKeyBoard->handleKeyPress(this);
});
}
VirtualKeyBoard::VirtualKeyBoard(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 screenSize = QGuiApplication::primaryScreen()->size();
resize(screenSize / 2);
mMainLayout = new QVBoxLayout(this);
sizePolicy.setHorizontalPolicy(QSizePolicy::Preferred);
sizePolicy.setVerticalPolicy(QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(1);
sizePolicy.setVerticalStretch(0);
mEnglish = createEnglish();
mChinese = createChinese();
mSymbol = createSymbol();
mMainLayout->addWidget(mEnglish);
mMainLayout->addWidget(mChinese);
mMainLayout->addWidget(mSymbol);
mCurWidget = mEnglish;
mChinese->hide();
mSymbol->hide();
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool | Qt::WindowDoesNotAcceptFocus);
mCore = new InputCore(this);
if (!mCore->init()) {
qDebug() << "字典加载失败,请将dict文件移至工作目录";
}
/* 设置为列表显示模式 */
listWidget->setViewMode(QListView::ListMode);
/* 从左往右排列 */
listWidget->setFlow(QListView::LeftToRight);
/* 屏蔽水平滑动条 */
listWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
/* 屏蔽垂直滑动条 */
listWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
/* 设置为像素滚动 */
listWidget->setHorizontalScrollMode(QListWidget::ScrollPerPixel);
/* 设置鼠标左键拖动 */
QScroller::grabGesture(listWidget, QScroller::LeftMouseButtonGesture);
//设置不可选中
connect(mEdit, &QLineEdit::selectionChanged, [=] { mEdit->deselect(); });
//中文输入
connect(mEdit, &QLineEdit::textChanged, [=](const QString &text) {
/* 单个字符过长引发崩溃
* 处理:单个字符限制长度为10
*/
if (text.isEmpty()) {
return;
}
if (text.length() >= 10) {
if (issingleChar(text)) {
QString deal_text = text.mid(0, 10);
getCandidateList(deal_text);
return;
}
getCandidateList(text);
return;
} else {
getCandidateList(text);
}
});
connect(listWidget, &QListWidget::itemClicked, [=](QListWidgetItem *item) {
QKeyEvent keyPress(QEvent::KeyPress, Qt::Key_unknown, Qt::NoModifier, item->text());
QCoreApplication::sendEvent(mInputWidget, &keyPress);
listWidget->clear();
mEdit->clear();
});
}
VirtualKeyBoard::~VirtualKeyBoard() {
}
bool VirtualKeyBoard::issingleChar(QString spell) {
bool ret = true;
for (auto s: spell) {
if (s != spell[0]) {
ret = false;
break;
}
}
return ret;
}
void VirtualKeyBoard::setEdit(QWidget *edit) {
this->mInputWidget = edit;
this->mInputWidget->installEventFilter(this);
}
void VirtualKeyBoard::getCandidateList(const QString spell) {
unsigned int cand = mCore->search(spell);
if (cand == 0) {
return;
}
QStringList ret = mCore->get_candidate(cand);
if (ret.isEmpty()) {
return;
}
listWidget->clear();
listWidget->addItems(ret);
}
void VirtualKeyBoard::handleKeyPress(KeyButton *button) {
if (mState == Chinese) {
if (button->mKey != Qt::Key_Backspace) {
mEdit->insert(button->mText);
} else {
if (!mEdit->text().isEmpty()) {
mEdit->backspace();
} else {
listWidget->clear();
QKeyEvent keyPress(QEvent::KeyPress, button->mKey, button->modifiers, button->mText);
QCoreApplication::sendEvent(mInputWidget, &keyPress);
}
}
} else {
if (button->isText) {
QKeyEvent keyPress(QEvent::KeyPress, button->mKey, button->modifiers, button->mText);
if(mInputWidget) {
QCoreApplication::sendEvent(mInputWidget, &keyPress);
} else
{
qWarning("VirtualKeyBoard mInputWidget == NULL!");
}
}
}
}
bool VirtualKeyBoard::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);
setEdit(w);
QPoint pos = w->mapToGlobal(QPoint(0, 0));
QSize screenSize = QGuiApplication::primaryScreen()->size();
int keyboardWidth = width();
int keyboardHeight = height();
int screenWidth = screenSize.width();
int screenHeight = screenSize.height();
int x = pos.x();
int y = pos.y() + w->height();
if (x + keyboardWidth > screenWidth) {
setFixedWidth(screenWidth - pos.x() - w->width());
}
if (y + keyboardHeight > screenHeight) {
setFixedHeight(screenHeight - pos.y() - w->height());
}
move(x, y);
show();
}
if (event->type() == QEvent::FocusOut) {
this->hide();
}
return QObject::eventFilter(watched, event);
}
void VirtualKeyBoard::mousePressEvent(QMouseEvent *event) {
if (mMoving) return;
if (event->button() == Qt::LeftButton) {
mMoving = true;
mStartPos = pos();
mStartGlobalPos = event->globalPos();
QApplication::setOverrideCursor(Qt::ClosedHandCursor);
}
event->accept();
}
void VirtualKeyBoard::mouseMoveEvent(QMouseEvent *event) {
if (!mMoving) return;
move(mStartPos + event->globalPos() - mStartGlobalPos);
event->accept();
}
void VirtualKeyBoard::mouseReleaseEvent(QMouseEvent *event) {
if (!mMoving) return;
mMoving = false;
event->accept();
QApplication::restoreOverrideCursor();
}
}